Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List View: render a fixed number of items #35230

Merged
merged 6 commits into from Oct 27, 2021
Merged

List View: render a fixed number of items #35230

merged 6 commits into from Oct 27, 2021

Conversation

gwwar
Copy link
Contributor

@gwwar gwwar commented Sep 29, 2021

This PR explores using the windowing technique in list view where we render a fixed number of items at a time instead of every block. This change should help stabilize the max time required for block focus (it should no longer grow with the number of blocks in the document) when list view is open, and should unblock other drag experiments in #34022

Performance

I've modified the spec on this branch to run the typing and focus tests with list view open. I also added a new test to toggle list view open and closed. Runs show around a 10x improvement in open time, ~7x improvement in focus time, and a modest improvement in typing speed when list view is open.

To verify visual changes to the performance tests we can run it with:

npm run test-performance -- --wordpress-base-url=http://e2e.local/ --wordpress-username=<username>--wordpress-password=<password> --puppeteer-interactive packages/e2e-tests/specs/performance/post-editor.test.js

npm run test-performance -- --wordpress-base-url=http://e2e.local/ --wordpress-username=<username>--wordpress-password=<password> --puppeteer-interactive packages/e2e-tests/specs/performance/site-editor.test.js

perf specs need to be written carefully since inserting blocks with the global inserter will hide the list view.

>> post-editor

┌──────────────────────┬──────────────────────────────────────────┬──────────────┐
│       (index)        │ 4bd8deab66b68f3a26e8fe02c36e841dfc6b2ac8 │    trunk     │
├──────────────────────┼──────────────────────────────────────────┼──────────────┤
│    serverResponse    │               '221.84 ms'                │ '204.52 ms'  │
│      firstPaint      │                '17.06 ms'                │  '28.46 ms'  │
│   domContentLoaded   │               '232.86 ms'                │ '239.48 ms'  │
│        loaded        │               '241.54 ms'                │ '247.94 ms'  │
│ firstContentfulPaint │               '5010.56 ms'               │ '4995.18 ms' │
│      firstBlock      │               '5693.28 ms'               │ '5699.52 ms' │
│         type         │                '43.34 ms'                │  '58.95 ms'  │
│       minType        │                '40.7 ms'                 │  '54.53 ms'  │
│       maxType        │                '49.77 ms'                │  '72.45 ms'  │
│        focus         │               '148.87 ms'                │ '840.75 ms'  │
│       minFocus       │                '1.04 ms'                 │  '1.19 ms'   │
│       maxFocus       │               '203.61 ms'                │ '1090.06 ms' │
│     inserterOpen     │                '76.71 ms'                │  '77.07 ms'  │
│   minInserterOpen    │                '55.07 ms'                │  '56.43 ms'  │
│   maxInserterOpen    │               '234.56 ms'                │ '234.25 ms'  │
│    inserterSearch    │                '68.54 ms'                │  '91.16 ms'  │
│  minInserterSearch   │                '56.99 ms'                │  '57.99 ms'  │
│  maxInserterSearch   │                '73.35 ms'                │  '283.9 ms'  │
│    inserterHover     │                '40.99 ms'                │  '41.75 ms'  │
│   minInserterHover   │                '37.8 ms'                 │  '36.24 ms'  │
│   maxInserterHover   │                '45.15 ms'                │  '51.4 ms'   │
│     listViewOpen     │               '203.01 ms'                │ '2874.56 ms' │
│   minListViewOpen    │               '192.07 ms'                │ '2630.45 ms' │
│   maxListViewOpen    │               '211.94 ms'                │ '4297.52 ms' │
└──────────────────────┴──────────────────────────────────────────┴──────────────┘

>> site-editor

┌──────────────────────┬──────────────────────────────────────────┬─────────────┐
│       (index)        │ 4bd8deab66b68f3a26e8fe02c36e841dfc6b2ac8 │    trunk    │
├──────────────────────┼──────────────────────────────────────────┼─────────────┤
│    serverResponse    │                '125.1 ms'                │ '127.57 ms' │
│      firstPaint      │               '416.63 ms'                │ '402.2 ms'  │
│   domContentLoaded   │                '476.3 ms'                │ '442.6 ms'  │
│        loaded        │                '622.6 ms'                │ '603.73 ms' │
│ firstContentfulPaint │               '416.63 ms'                │ '402.2 ms'  │
│      firstBlock      │               '6050.7 ms'                │ '5869.5 ms' │
│         type         │                '34.46 ms'                │ '41.65 ms'  │
│       minType        │                '30.9 ms'                 │ '37.01 ms'  │
│       maxType        │                '49.61 ms'                │ '59.19 ms'  │
└──────────────────────┴──────────────────────────────────────────┴─────────────┘

Example with nested items:

CleanShot.2021-09-30.at.15.19.39.mp4

Performance test post.

Note how we show blank padding when scrolling quickly. We can optimize for this by trying to render more items (updating the window overscan) or adding maybe some loading placeholders.

CleanShot.2021-09-30.at.15.20.45.mp4

Keyboard support:

CleanShot.2021-10-04.at.15.16.17.mp4

Example of drag scrolling (shown with list position debug numbers)

CleanShot.2021-10-05.at.14.51.50.mp4

Screen reader should read out the same labels for rows and initial table counts:

CleanShot 2021-10-08 at 10 57 21@2x

Testing Instructions

  • In the Site Editor and Post Editor try adding a number of blocks to the document. Be sure to also add nested bocks
  • Verify that there are no regressions with dragging, expanding/collapsing, scrolling and that the ordering of items is correct.
  • Verify that there are no changes/regressions using a screenreader to navigate list view
  • Verify that windowing is not used on other list view instances, such as on the navigation block (in all editors: widget, site, post, navigation)
Navigation List View Modal
CleanShot 2021-10-08 at 11 11 52@2x CleanShot 2021-10-08 at 11 09 03@2x

TODO:

  • basic scroll and resize support
  • fix keyboard down/up outside of window
  • appropriate screenreader label updates to make sure folks know there are more items available
  • fix drag scroll
  • make sure we don't get scroll thrashing in certain scenarios

@gwwar gwwar self-assigned this Sep 29, 2021
@github-actions
Copy link

github-actions bot commented Sep 29, 2021

Size Change: +5.72 kB (+1%)

Total Size: 1.08 MB

Filename Size Change
build/block-editor/index.min.js 135 kB +723 B (+1%)
build/block-editor/style-rtl.css 14 kB +137 B (+1%)
build/block-editor/style.css 14 kB +139 B (+1%)
build/block-library/blocks/navigation/editor-rtl.css 1.81 kB +106 B (+6%) 🔍
build/block-library/blocks/navigation/editor.css 1.81 kB +106 B (+6%) 🔍
build/block-library/blocks/post-comments/style-rtl.css 492 B +17 B (+4%)
build/block-library/blocks/post-comments/style.css 493 B +18 B (+4%)
build/block-library/editor-rtl.css 9.71 kB +101 B (+1%)
build/block-library/editor.css 9.71 kB +102 B (+1%)
build/block-library/index.min.js 153 kB +3.32 kB (+2%)
build/block-library/style-rtl.css 10.5 kB +16 B (0%)
build/block-library/style.css 10.5 kB +16 B (0%)
build/components/index.min.js 212 kB +5 B (0%)
build/components/style-rtl.css 15.4 kB +10 B (0%)
build/components/style.css 15.4 kB +10 B (0%)
build/compose/index.min.js 10.9 kB +511 B (+5%) 🔍
build/edit-site/index.min.js 30.7 kB +11 B (0%)
build/editor/index.min.js 37.7 kB +18 B (0%)
build/format-library/index.min.js 6.34 kB +355 B (+6%) 🔍
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 931 B
build/admin-manifest/index.min.js 1.09 kB
build/annotations/index.min.js 2.7 kB
build/api-fetch/index.min.js 2.21 kB
build/autop/index.min.js 2.08 kB
build/blob/index.min.js 459 B
build/block-directory/index.min.js 6.2 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 58 B
build/block-library/blocks/audio/editor.css 58 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 470 B
build/block-library/blocks/button/editor.css 470 B
build/block-library/blocks/button/style-rtl.css 549 B
build/block-library/blocks/button/style.css 549 B
build/block-library/blocks/buttons/editor-rtl.css 309 B
build/block-library/blocks/buttons/editor.css 309 B
build/block-library/blocks/buttons/style-rtl.css 317 B
build/block-library/blocks/buttons/style.css 317 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 90 B
build/block-library/blocks/code/style.css 90 B
build/block-library/blocks/code/theme-rtl.css 131 B
build/block-library/blocks/code/theme.css 131 B
build/block-library/blocks/columns/editor-rtl.css 206 B
build/block-library/blocks/columns/editor.css 205 B
build/block-library/blocks/columns/style-rtl.css 497 B
build/block-library/blocks/columns/style.css 496 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.17 kB
build/block-library/blocks/cover/style.css 1.17 kB
build/block-library/blocks/embed/editor-rtl.css 488 B
build/block-library/blocks/embed/editor.css 488 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 322 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 977 B
build/block-library/blocks/gallery/editor.css 982 B
build/block-library/blocks/gallery/style-rtl.css 1.6 kB
build/block-library/blocks/gallery/style.css 1.59 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/home-link/style-rtl.css 247 B
build/block-library/blocks/home-link/style.css 247 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 731 B
build/block-library/blocks/image/editor.css 730 B
build/block-library/blocks/image/style-rtl.css 502 B
build/block-library/blocks/image/style.css 505 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 137 B
build/block-library/blocks/latest-posts/editor.css 137 B
build/block-library/blocks/latest-posts/style-rtl.css 528 B
build/block-library/blocks/latest-posts/style.css 527 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 488 B
build/block-library/blocks/navigation-link/editor.css 489 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation-submenu/style-rtl.css 195 B
build/block-library/blocks/navigation-submenu/style.css 195 B
build/block-library/blocks/navigation-submenu/view.min.js 343 B
build/block-library/blocks/navigation/style-rtl.css 1.71 kB
build/block-library/blocks/navigation/style.css 1.7 kB
build/block-library/blocks/navigation/view.min.js 2.74 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 377 B
build/block-library/blocks/page-list/editor.css 377 B
build/block-library/blocks/page-list/style-rtl.css 198 B
build/block-library/blocks/page-list/style.css 198 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 273 B
build/block-library/blocks/paragraph/style.css 273 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/style-rtl.css 347 B
build/block-library/blocks/post-comments-form/style.css 347 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 396 B
build/block-library/blocks/post-featured-image/editor.css 397 B
build/block-library/blocks/post-featured-image/style-rtl.css 156 B
build/block-library/blocks/post-featured-image/style.css 156 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 391 B
build/block-library/blocks/post-template/style.css 392 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 60 B
build/block-library/blocks/post-title/style.css 60 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 378 B
build/block-library/blocks/pullquote/style.css 378 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 262 B
build/block-library/blocks/query-pagination/editor.css 255 B
build/block-library/blocks/query-pagination/style-rtl.css 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 187 B
build/block-library/blocks/quote/style.css 187 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 397 B
build/block-library/blocks/search/style.css 398 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 250 B
build/block-library/blocks/separator/style.css 250 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 770 B
build/block-library/blocks/site-logo/editor.css 770 B
build/block-library/blocks/site-logo/style-rtl.css 165 B
build/block-library/blocks/site-logo/style.css 165 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 824 B
build/block-library/blocks/social-links/editor.css 823 B
build/block-library/blocks/social-links/style-rtl.css 1.32 kB
build/block-library/blocks/social-links/style.css 1.32 kB
build/block-library/blocks/spacer/editor-rtl.css 307 B
build/block-library/blocks/spacer/editor.css 307 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 146 B
build/block-library/blocks/tag-cloud/style.css 146 B
build/block-library/blocks/template-part/editor-rtl.css 560 B
build/block-library/blocks/template-part/editor.css 559 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 815 B
build/block-library/common.css 812 B
build/block-library/reset-rtl.css 474 B
build/block-library/reset.css 474 B
build/block-library/theme-rtl.css 668 B
build/block-library/theme.css 673 B
build/block-serialization-default-parser/index.min.js 1.09 kB
build/block-serialization-spec-parser/index.min.js 2.79 kB
build/blocks/index.min.js 46 kB
build/core-data/index.min.js 12.4 kB
build/customize-widgets/index.min.js 11.2 kB
build/customize-widgets/style-rtl.css 1.5 kB
build/customize-widgets/style.css 1.49 kB
build/data-controls/index.min.js 614 B
build/data/index.min.js 7.1 kB
build/date/index.min.js 31.5 kB
build/deprecated/index.min.js 428 B
build/dom-ready/index.min.js 304 B
build/dom/index.min.js 4.44 kB
build/edit-navigation/index.min.js 15.8 kB
build/edit-navigation/style-rtl.css 3.76 kB
build/edit-navigation/style.css 3.76 kB
build/edit-post/classic-rtl.css 492 B
build/edit-post/classic.css 494 B
build/edit-post/index.min.js 29.4 kB
build/edit-post/style-rtl.css 7.12 kB
build/edit-post/style.css 7.12 kB
build/edit-site/style-rtl.css 5.78 kB
build/edit-site/style.css 5.78 kB
build/edit-widgets/index.min.js 16.3 kB
build/edit-widgets/style-rtl.css 4.17 kB
build/edit-widgets/style.css 4.18 kB
build/editor/style-rtl.css 3.78 kB
build/editor/style.css 3.77 kB
build/element/index.min.js 3.21 kB
build/escape-html/index.min.js 517 B
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.55 kB
build/html-entities/index.min.js 424 B
build/i18n/index.min.js 3.6 kB
build/is-shallow-equal/index.min.js 501 B
build/keyboard-shortcuts/index.min.js 1.72 kB
build/keycodes/index.min.js 1.3 kB
build/list-reusable-blocks/index.min.js 1.85 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.92 kB
build/notices/index.min.js 845 B
build/nux/index.min.js 2.03 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 743 B
build/plugins/index.min.js 1.83 kB
build/primitives/index.min.js 921 B
build/priority-queue/index.min.js 582 B
build/react-i18n/index.min.js 671 B
build/redux-routine/index.min.js 2.63 kB
build/reusable-blocks/index.min.js 2.19 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.7 kB
build/server-side-render/index.min.js 1.52 kB
build/shortcode/index.min.js 1.48 kB
build/token-list/index.min.js 562 B
build/url/index.min.js 1.74 kB
build/viewport/index.min.js 1.02 kB
build/warning/index.min.js 248 B
build/widgets/index.min.js 7.11 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@annezazu annezazu added the [Feature] List View Menu item in the top toolbar to select blocks from a list of links. label Sep 30, 2021
@gwwar gwwar added the [Type] Performance Related to performance efforts label Sep 30, 2021
@gwwar
Copy link
Contributor Author

gwwar commented Oct 1, 2021

I've modified the spec on this branch to run the typing and focus tests with list view open. To verify visual changes to the performance tests we can run it with:

npm run test-performance -- --wordpress-base-url=http://e2e.local/ --wordpress-username=<username>--wordpress-password=<password> --puppeteer-interactive packages/e2e-tests/specs/performance/post-editor.test.js

npm run test-performance -- --wordpress-base-url=http://e2e.local/ --wordpress-username=<username>--wordpress-password=<password> --puppeteer-interactive packages/e2e-tests/specs/performance/site-editor.test.js

perf specs need to be written carefully since inserting blocks with the global inserter will hide the list view.

Initial results show a modest change for typing and a rather large impact on focus with list view open:

>> post-editor

┌───────────────────┬──────────────────────────────────────────┬─────────────┐
│      (index)      │ c4a04cfb626f506a111215d1fac5091ece2ead2e │    trunk    │
├───────────────────┼──────────────────────────────────────────┼─────────────┤
│       load        │               '6704.6 ms'                │ '6886.8 ms' │
│       type        │                '38.63 ms'                │ '46.62 ms'  │
│      minType      │                '32.28 ms'                │ '39.65 ms'  │
│      maxType      │                '62.49 ms'                │ '59.11 ms'  │
│       focus       │               '105.58 ms'                │ '704.19 ms' │
│     minFocus      │                '0.98 ms'                 │   '1 ms'    │
│     maxFocus      │               '150.18 ms'                │ '925.34 ms' │
│   inserterOpen    │                '79.05 ms'                │ '111.63 ms' │
│  minInserterOpen  │                '52.21 ms'                │ '51.62 ms'  │
│  maxInserterOpen  │               '265.73 ms'                │ '604.11 ms' │
│  inserterSearch   │                '67.36 ms'                │ '97.96 ms'  │
│ minInserterSearch │                '56.58 ms'                │ '55.57 ms'  │
│ maxInserterSearch │                '77.56 ms'                │ '393.52 ms' │
│   inserterHover   │                '25.86 ms'                │  '31.2 ms'  │
│ minInserterHover  │                '20.06 ms'                │ '24.24 ms'  │
│ maxInserterHover  │                '34.74 ms'                │ '40.32 ms'  │
└───────────────────┴──────────────────────────────────────────┴─────────────┘

>> site-editor

┌─────────┬──────────────────────────────────────────┬──────────────┐
│ (index) │ c4a04cfb626f506a111215d1fac5091ece2ead2e │    trunk     │
├─────────┼──────────────────────────────────────────┼──────────────┤
│  load   │               '6590.33 ms'               │ '6396.67 ms' │
│  type   │                '29.54 ms'                │  '34.58 ms'  │
│ minType │                '22.21 ms'                │  '27.96 ms'  │
│ maxType │                '45.63 ms'                │  '50.72 ms'  │
└─────────┴──────────────────────────────────────────┴──────────────┘

@gwwar gwwar force-pushed the try/list-view-window branch 3 times, most recently from b268fb5 to a0d49a1 Compare October 4, 2021 22:18
@gwwar
Copy link
Contributor Author

gwwar commented Oct 6, 2021

Screen readers handle tables differently, but one common aspect will be that most will try to read the number of columns and rows. Since we're exploring using the windowing technique here, the main difference is that the number of rows won't reflect the total number of list items we can reach.

I can create labels with the number of total blocks / blocks shown currently, but I do wonder what type of labels we can create that will make this more useful for screen readers in general. Do folks have any thoughts on how we can improve labels in list view when we only render some rows? Maybe @diegohaz or anyone else familiar with screen readers could chime in?

For reference, here's what behavior looks like on trunk using voiceover:

CleanShot.2021-10-06.at.14.35.47-converted.mp4

Here's what it looks like in this branch:

CleanShot.2021-10-06.at.15.14.50.mp4

@gwwar gwwar added the [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). label Oct 7, 2021
@gwwar
Copy link
Contributor Author

gwwar commented Oct 7, 2021

Going to put this as ready for review since I'm keen to see if folks can break the branch during testing, or if it needs more stability fixes. I'm also interested in any feedback for more appropriate/useful labels for the List View table.

@gwwar gwwar marked this pull request as ready for review October 7, 2021 15:41
await insertBlock( 'Paragraph' );
await page.click( '.edit-post-header-toolbar__list-view-toggle' );
await page.click( '.edit-post-visual-editor__post-title-wrapper' );
await page.keyboard.press( 'Enter' );
Copy link
Contributor Author

@gwwar gwwar Oct 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we can drop the performance spec changes if this PR happens to land. I wanted some concrete numbers though for the potential perf improvements.

See notes in #35230 (comment)

@talldan
Copy link
Contributor

talldan commented Oct 8, 2021

Do folks have any thoughts on how we can improve labels in list view when we only render some rows? Maybe @diegohaz or anyone else familiar with screen readers could chime in?

The treegrid items do (or should) already have their own aria labels and that's because screenreader support is currently limited for some of these more advanced patterns.

It could be that we have the same kind of thing at the table, replicate the useful information (number of rows, columns) using an aria label. The only problem would be if the screenreader also reads the incorrect windowed number of rows.

FYI, this PR would also affect the number of columns in the site editor - #35170.

@jasmussen
Copy link
Contributor

Giving this a spin, it feels completely speedy for me, even with 500+ blocks
Screenshot 2021-10-08 at 10 34 35

list view testing

And performance wise, honestly the list view feels like the fastest part of the interface here. Just creating the test content to vet this caused the canvas to pause for a bit:
Screenshot 2021-10-08 at 10 33 46

That's all to say: this is working really well, to the point that if we can find a good path forward for this, could it possibly even be brought to the canvas itself? Even if it had a high windowing limit, chunking in 128 or 256 or such, it might really benefit the extreme edgecases where documents grow super long, like a published ebook. Something to think about! But should also be taken as appreciation of how fast the list view feels in this one: impressive work.

The only problem would be if the screenreader also reads the incorrect windowed number of rows.

This seems like the key problem to solve. What options do we have here for enhancing what gets read aloud?

@gwwar
Copy link
Contributor Author

gwwar commented Oct 8, 2021

It could be that we have the same kind of thing at the table, replicate the useful information (number of rows, columns) using an aria label.

@talldan sounds good, I'll give that a try to start.

FYI, this PR would also affect the number of columns in the site editor - #35170.

Thanks for the heads up. If the ellipsis PR lands first, that may be a bigger rebase, but it shouldn't be a problem 😄

That's all to say: this is working really well, to the point that if we can find a good path forward for this, could it possibly even be brought to the canvas itself? Even if it had a high windowing limit, chunking in 128 or 256 or such, it might really benefit the extreme edgecases where documents grow super long, like a published ebook

@jasmussen it's definitely a technique to keep in mind. Applying windowing to the block list is much harder to get right since the items are of variable height/width, and have nested children. I think it's been tried in the past, but it could be worth trying again in the future. It's also much more likely to break functionality, but would let us relax the need to try and optimize some other pieces since it'd give a consistent number of blocks to render.

@gwwar
Copy link
Contributor Author

gwwar commented Oct 15, 2021

Seems fairly straightforward to remove the two functions from that map and refactor the logic into ListViewBlock

@talldan Looks like there's more to unwind. I ended up removing the unused terminatedLevels, refactored path to be a string, and memo'd quite a few references in #35683, but it looks like there are more hook updates firing. I'll see if I can isolate this, but I think windowing is still nice since it'll cap the initial render time to somewhere around 200ms-300ms vs 2+ seconds.

#35683 (comment) And for details on the hooks that update: #35683 (comment)

Edit: Okay this makes sense. So when we click on a block, selectedIds update. We currently query this in the parent component in ListView.

Since the parent (ListView) component renders all child components render too (which may or may not trigger any DOM changes). Branch.js currently needs selectedIds to handle things like if we should render in async mode or not, branch highlighting and if we should add an appender.

🤔 I don't think I can fix that without also memo'ing on larger pieces, so I'll go ahead and close out #35683

Edit 2: After some further profiling it turns out the issue was how we were querying selectedClientIds. I've isolated a focus fix in #35706

Note that #35706 isn't an alternative but a PR we can potentially land before this one, I'd still love to see a form of windowing to fix List View's slow first render time.

@gwwar
Copy link
Contributor Author

gwwar commented Oct 22, 2021

Going to rebase to pull in changes from #35706

I may also go ahead with the windowing + placeholder approach, since the perf overhead isn't much ~100ms, and rendering time is still ~300ms vs 3-5 seconds. This should also avoid any accessibility regressions.

@gwwar
Copy link
Contributor Author

gwwar commented Oct 22, 2021

New performance baseline, before I modify the algorithm:

test type branch trunk
focus (list view open) 141 ms 204.4 ms
type (list view open) 47.19 ms 61.77 ms
open list view 226.26 ms 3959.76 ms

See full performance run details https://github.com/WordPress/gutenberg/runs/3979022008:

>> post-editor

┌──────────────────────┬──────────────────────────────────────────┬──────────────┐
│       (index)        │ a4902c757f6532958fa719562efa554f052f0eb7 │    trunk     │
├──────────────────────┼──────────────────────────────────────────┼──────────────┤
│    serverResponse    │               '261.72 ms'                │ '250.32 ms'  │
│      firstPaint      │                '63.2 ms'                 │  '39.52 ms'  │
│   domContentLoaded   │                '301.5 ms'                │ '303.66 ms'  │
│        loaded        │               '312.16 ms'                │ '314.98 ms'  │
│ firstContentfulPaint │               '6158.78 ms'               │ '6335.8 ms'  │
│      firstBlock      │               '7013.44 ms'               │ '7135.12 ms' │
│         type         │                '47.19 ms'                │  '61.77 ms'  │
│       minType        │                '39.66 ms'                │  '53.48 ms'  │
│       maxType        │                '70.55 ms'                │  '74.69 ms'  │
│        focus         │                 '141 ms'                 │  '204.4 ms'  │
│       minFocus       │                '1.09 ms'                 │  '1.08 ms'   │
│       maxFocus       │               '196.14 ms'                │ '366.05 ms'  │
│     inserterOpen     │                '88.36 ms'                │  '87.01 ms'  │
│   minInserterOpen    │                '57.15 ms'                │  '57.18 ms'  │
│   maxInserterOpen    │               '316.63 ms'                │ '301.15 ms'  │
│    inserterSearch    │                '75.92 ms'                │ '118.38 ms'  │
│  minInserterSearch   │                '65.07 ms'                │  '69.27 ms'  │
│  maxInserterSearch   │                '87.23 ms'                │ '315.53 ms'  │
│    inserterHover     │                '34.04 ms'                │  '40.59 ms'  │
│   minInserterHover   │                '27.1 ms'                 │  '33.78 ms'  │
│   maxInserterHover   │                '41.1 ms'                 │  '49.39 ms'  │
│     listViewOpen     │               '226.26 ms'                │ '3959.76 ms' │
│   minListViewOpen    │               '207.43 ms'                │ '3661.79 ms' │
│   maxListViewOpen    │               '248.81 ms'                │ '5567.12 ms' │
└──────────────────────┴──────────────────────────────────────────┴──────────────┘

>> site-editor

┌──────────────────────┬──────────────────────────────────────────┬──────────────┐
│       (index)        │ a4902c757f6532958fa719562efa554f052f0eb7 │    trunk     │
├──────────────────────┼──────────────────────────────────────────┼──────────────┤
│    serverResponse    │                '130.8 ms'                │  '136.3 ms'  │
│      firstPaint      │                '518.5 ms'                │  '518.4 ms'  │
│   domContentLoaded   │               '537.43 ms'                │  '536.4 ms'  │
│        loaded        │               '672.87 ms'                │   '703 ms'   │
│ firstContentfulPaint │                '518.5 ms'                │  '518.4 ms'  │
│      firstBlock      │               '7177.77 ms'               │ '7150.43 ms' │
│         type         │                '34.26 ms'                │  '39.89 ms'  │
│       minType        │                '25.51 ms'                │  '31.78 ms'  │
│       maxType        │                '49.14 ms'                │  '57.56 ms'  │
└──────────────────────┴──────────────────────────────────────────┴──────────────┘

@gwwar gwwar force-pushed the try/list-view-window branch 2 times, most recently from e04d360 to f9e70e3 Compare October 22, 2021 21:15
@gwwar
Copy link
Contributor Author

gwwar commented Oct 22, 2021

Here are results using the placeholder method. As expected list view open time is ~100ms slower than using padding, but still an order of magnitude faster than trunk for a post that contains ~900 blocks. Since we don't modify total number of table rows changes in this PR shouldn't regress screenreader navigation. This one is set for review 👍

test type branch trunk
focus (list view open) 152.09 ms 230.13 ms
type (list view open) 50.14 ms 64.82 ms
open list view 301.29 ms 4065.07 ms

Full performance run results https://github.com/WordPress/gutenberg/runs/3980496064

>> post-editor

┌──────────────────────┬──────────────────────────────────────────┬──────────────┐
│       (index)        │ 9208a08f14988e9462dfb04b945018e1540d63e4 │    trunk     │
├──────────────────────┼──────────────────────────────────────────┼──────────────┤
│    serverResponse    │               '248.84 ms'                │ '261.84 ms'  │
│      firstPaint      │                 '8.3 ms'                 │  '19.16 ms'  │
│   domContentLoaded   │               '295.28 ms'                │ '303.22 ms'  │
│        loaded        │               '307.12 ms'                │ '314.12 ms'  │
│ firstContentfulPaint │               '6291.36 ms'               │ '6250.5 ms'  │
│      firstBlock      │               '7149.54 ms'               │ '7016.86 ms' │
│         type         │                '50.14 ms'                │  '64.82 ms'  │
│       minType        │                '43.2 ms'                 │  '54.6 ms'   │
│       maxType        │                '61.11 ms'                │  '96.68 ms'  │
│        focus         │               '152.09 ms'                │ '230.13 ms'  │
│       minFocus       │                '1.29 ms'                 │  '1.38 ms'   │
│       maxFocus       │               '229.73 ms'                │ '389.06 ms'  │
│     inserterOpen     │                '94.51 ms'                │  '93.64 ms'  │
│   minInserterOpen    │                '63.49 ms'                │  '62.73 ms'  │
│   maxInserterOpen    │                '330.7 ms'                │ '344.36 ms'  │
│    inserterSearch    │               '103.53 ms'                │ '107.68 ms'  │
│  minInserterSearch   │                '73.52 ms'                │  '71.47 ms'  │
│  maxInserterSearch   │                 '268 ms'                 │ '337.54 ms'  │
│    inserterHover     │                '39.79 ms'                │  '35.21 ms'  │
│   minInserterHover   │                '33.14 ms'                │  '28.99 ms'  │
│   maxInserterHover   │                '48.37 ms'                │  '42.47 ms'  │
│     listViewOpen     │               '301.29 ms'                │ '4065.07 ms' │
│   minListViewOpen    │               '279.13 ms'                │ '3760.13 ms' │
│   maxListViewOpen    │               '335.02 ms'                │ '5426.93 ms' │
└──────────────────────┴──────────────────────────────────────────┴──────────────┘

>> site-editor

┌──────────────────────┬──────────────────────────────────────────┬──────────────┐
│       (index)        │ 9208a08f14988e9462dfb04b945018e1540d63e4 │    trunk     │
├──────────────────────┼──────────────────────────────────────────┼──────────────┤
│    serverResponse    │                '140.6 ms'                │ '140.63 ms'  │
│      firstPaint      │               '512.63 ms'                │ '458.27 ms'  │
│   domContentLoaded   │               '542.93 ms'                │ '510.07 ms'  │
│        loaded        │                 '712 ms'                 │  '720.4 ms'  │
│ firstContentfulPaint │               '512.63 ms'                │ '458.27 ms'  │
│      firstBlock      │               '7505.6 ms'                │ '7181.83 ms' │
│         type         │                '39.47 ms'                │  '42.91 ms'  │
│       minType        │                '32.05 ms'                │  '35.62 ms'  │
│       maxType        │                '57.36 ms'                │  '69.74 ms'  │
└──────────────────────┴──────────────────────────────────────────┴──────────────┘

@alexstine
Copy link
Contributor

@gwwar Seems to still work fine for accessibility. Tested using NVDA on Windows 10 in Google Chrome. I can't even notice any lag in List View anymore.

Copy link
Contributor

@talldan talldan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I think my only concern is the blank areas that you see when scrolling really fast. Not sure if there's a way to make this slightly more visually appealing.

I notice drag and drop performance is really bad in trunk to the point where it becomes unresponsive. Feels like a regression, I don't recall it being as bad as it is right now.

It is slightly better in this branch, but still very stuttery:

Kapture.2021-10-27.at.17.17.03.mp4

@jasmussen
Copy link
Contributor

🔥

hypest added a commit to wordpress-mobile/gutenberg-mobile that referenced this pull request Oct 27, 2021
@gwwar
Copy link
Contributor Author

gwwar commented Oct 27, 2021

🎉 Much appreciated for the follow up review @talldan, I know this was quite a bit to test! Thanks to @alexstine and everyone else who helped review too!

I think my only concern is the blank areas that you see when scrolling really fast. Not sure if there's a way to make this slightly more visually appealing.

There's a few options here. I think we're still re-rendering more than we need to on scroll, so there's further optimizations we can profile. Another one might be exploring using a pulsing or loading asset in the placeholder cell.

I notice drag and drop performance is really bad in trunk to the point where it becomes unresponsive. Feels like a regression, I don't recall it being as bad as it is right now.

Oh interesting, I'll try and profile this next to see if I can spot it. 🔍

@gwwar gwwar changed the title List View: experiment with only rendering a fixed number of items List View: render a fixed number of items Oct 27, 2021
@gwwar gwwar merged commit 45cffa2 into trunk Oct 27, 2021
@gwwar gwwar deleted the try/list-view-window branch October 27, 2021 17:28
@github-actions github-actions bot added this to the Gutenberg 11.9 milestone Oct 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] List View Menu item in the top toolbar to select blocks from a list of links. [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Type] Performance Related to performance efforts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants