perf: isolate block-editor React hot paths - #480
Conversation
…obal-packages@5cdca5b...1294201 - docs(controls): record retainIfEqual tests in Unreleased - docs(editor): record style-engine CPU tests in Unreleased - test(editor): cover style-engine generator burst and fingerprint cache - perf(editor): cut duplicate style-engine generator and fingerprint work - test(controls): cover retainIfEqual object identity - ...and 5 more commits
🔗 PR Playground DemoBranch Links |
✅ WordPress Plugin Check Report
📊 ReportAll checks passed! No errors or warnings found. 🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check |
Block Editor Performance Report (PR vs Core)Compare Blockera vs Core (plugin off) using Chromium tracing metrics adapted from the Gutenberg post-editor performance suite. Only scenarios without Numbers are median interaction durations in milliseconds (lower is faster). All gated numbers are median values over 1 repetition(s) with 10 sample(s) each.
Full metrics (median / STD / MAD)Select blocks
Default threshold: 20% (from editor-scenarios.json). |
📦 Bundle Size ReportSize Change: 0 B Total Size: 9.06 MB ℹ️ View Unchanged
Report truncated to fit GitHub's 65536-character comment limit. See this workflow's Size Differences log for the full table. compressed-size-action |
📈 Performance ReportCompare Blockera vs Core (plugin off) using the WordPress Playwright Server-Timing harness. Numbers in the table are how long WordPress takes on the server to fully process each page (median, in milliseconds). Lower is faster. All gated numbers are median values over 2 repetition(s) with 20 iteration(s) each.
Skipped
Full metrics (median / STD / MAD)Home page
Blocks: Large page 1
Admin: Dashboard
Admin: Posts list
Admin: Media library
Admin: Block editor (Large page 1)
Admin: Blockera dashboard
Scenario URLs
Default threshold: 25% (from scenarios.json). |
…al-packages@1294201...a3f39b2 - fix(editor): bind style generators after circular imports resolve
|
Size Change: 0 B Total Size: 9.06 MB ℹ️ View Unchanged
|
Block Editor Performance Report (PR vs Master)Compare Blockera on this PR vs Blockera on master using Chromium tracing metrics adapted from the Gutenberg post-editor performance suite. Only scenarios with Numbers are median interaction durations in milliseconds (lower is faster). All gated numbers are median values over 1 repetition(s) with 10 sample(s) each.
Failures
Full metrics (median / STD / MAD)Workspace tabs
Block bg color
Block bg image
GS variation bg color
GS variation bg image
GS variation duplicate
GS default bg color
GS default bg color variable
GS seed border preset
Threshold gate failed (3 scenario(s)). Default threshold: 20% (from editor-scenarios.json). |
…al-packages@a3f39b2...14ccce5 - fix(editor): compare extension memo keys without unbound hasOwnProperty
…bal-packages@14ccce5...d497eea - test(editor): cover Global Styles iframe schema and empty-slice helpers - perf(editor): keep Global Styles off the canvas breakpoint path
…bal-packages@d497eea...e121b57 - test(controls): cover InputControl unit catalog cache and copy-on-write append - perf(controls): cache InputControl unit catalogs and skip extra input renders - test(global-styles-ui): cover config retainers and editor settings skip helper - perf(global-styles-ui): share merged theme.json and skip redundant editor settings sync
… blockera/perf/optimization)
… blockera/perf/optimization)
…obal-packages@a59ba4e...7dd8919 - Merge branch 'master' into blockera/perf/optimization - test: shorten global-styles e2e spec suffix to gs - test: shorten global-styles compatibility e2e spec suffix to gs-compatibility - build: Update Changelog for 7.0.0 - Merge pull request #9 from blockeraai/blockera/feat/better-e2e-test-categories - ...and 11 more commits
…al-packages@7dd8919...ef75509 - fix: annotate memoized input control exports for Flow
…bal-packages@ef75509...c51d771 - Merge branch 'master' into blockera/perf/optimization - test: remove the bootstrap category - test: drop .general from Cypress e2e spec filenames
…obal-packages@c51d771...e7ee548 - Revert "docs(editor): record typography memo tests in Unreleased" - Revert "test(editor): cover typography field and advanced-features memo equality" - Revert "perf(editor): skip sibling typography fields when one value changes" - test(editor): budget Font Size e2e BlockBase and InputControl renders - test(controls): add InputControl inspector idle and typing render budgets - ...and 11 more commits
…al-packages@e7ee548...37b113a - fix(compatibility): allow null theme JSON helper properties
…bal-packages@37b113a...33ba6f8 - test(editor): cover color-only fingerprint identity reuse - perf(editor): token nested style fingerprints by identity - docs(editor): record background field memo equality tests - test(editor): cover background field memo equality - perf(editor): skip background layers repeater on color edits - ...and 4 more commits
…bal-packages@33ba6f8...3ea16b3 - fix(editor): reuse empty useEntity select result - fix(editor): avoid unstable useSelect functions in workspace tabs
…bal-packages@3ea16b3...3a3c675 - fix(editor): stringify fingerprint primitives as strings - fix(editor): annotate memoized background field Flow exports
…bal-packages@3a3c675...28b79a9 - fix(controls): replace react-color Checkboard without defaultProps - fix(controls): drop Sketch defaultProps warning on the color picker - test(editor): cover background shorthand vs backgroundColor split - fix(editor): split colliding background and backgroundColor styles - fix(controls): forwardRef ResetIcon for WordPress Tooltip
…bal-packages@28b79a9...7b04ce8 - perf(editor): skip canvas background-style rewrite when unused - test(controls): cover batched ControlContext registration helpers - fix(controls): register ControlContext without updating siblings in render - test(editor): cover stable wrapper identity for background style split - fix(editor): keep background style split off saved markup
…bal-packages@7b04ce8...5cc8b6b - test(dev-cypress): commit color picker values without cy.blur - fix(controls): keep ControlContext children mounted after register - fix(editor): refine background-style split after the rewrite guard - fix(controls): annotate Checkboard and ResetIcon for Flow
…bal-packages@7b04ce8...5cc8b6b - test(dev-cypress): commit color picker values without cy.blur - fix(controls): keep ControlContext children mounted after register - fix(editor): refine background-style split after the rewrite guard - fix(controls): annotate Checkboard and ResetIcon for Flow
…obal-packages@5cc8b6b...6d21909 - docs: fold Unreleased notes for non-technical readers - test(global-styles-ui): cover variable editor persist on leave - test(dev-cypress): open Global Styles screens with render counting - test(global-styles-ui): cover deferred preset persist helpers - perf(global-styles-ui): save variable edits on leave not each keystroke - ...and 10 more commits
…obal-packages@6d21909...e764082 - fix(global-styles-ui): treat filter theme.json lists as the theme origin - test(global-styles-ui): cover theme.json preset list origin coerce - fix(global-styles-ui): treat theme.json preset lists as the theme origin - test(global-styles-ui): cover nested repeater close as a persist trigger - fix(global-styles-ui): persist nested preset field edits on Escape - ...and 11 more commits
Force-close the creating-step popover so the seed helper does not wait on a row still marked as being created.
…bal-packages@e764082...399cbc8 - fix(controls): type repeater click handlers for Flow - fix(global-styles-ui): loosen live preset header props for repeater spread - fix(global-styles-ui): type live preset headers as ElementType - fix(global-styles-ui): finish creating-step when closing a new preset - test(controls): cover Escape close with sibling and nested popovers - ...and 1 more commits
…al-packages@399cbc8...7166743 - test(spacing.variables): modified
…al-packages@7166743...e119e53 - test(border-radius.variables): modified
…bal-packages@e119e53...92fa6f4 - test(controls): cover unit join on Escape without doubling the suffix - fix(controls): avoid doubling units when Escape commits a typed suffix - test(global-styles-ui): cover skipping empty Escape persist - fix(global-styles-ui): keep sibling preset field values on Escape persist
…bal-packages@92fa6f4...4fd370d - test(dev-cypress): wait for a hydrated editor canvas iframe body - test(dev-cypress): wait until the post editor save finishes - test(global-styles-ui): cover nested repeater open-state across type-key persist - fix(global-styles-ui): keep nested filter editors open on type change - test(controls): cover repeater type-key rename detection - ...and 3 more commits
…bal-packages@4fd370d...ca67304 - test(controls): cover slug keys are not type-key renames - perf(controls): ignore slug key changes in type-key reopen
…bal-packages@ca67304...af81bdf - test(controls): cover persist skip when the repeater instance switches - fix(controls): skip repeater persist when the control instance switches - test(editor): cover inspector tab plan for Content-tab blocks - fix(editor): open Styles first when WordPress shows a Content tab
Clear custom border presets between samples (outside the trace) so Add is not blocked by the one-variable limit, skip save in the loop, and wait for the creating-step name field on the Borders screen.
…bal-packages@af81bdf...1415ab3 - fix(global-styles-ui): skip companion gate on site editor preset add - fix(controls): skip companion gate when Global Styles adds presets - test(global-styles-ui): cover add-only creating-step row detection - feat(global-styles-ui): detect add-only creating-step repeater rows - fix(global-styles-ui): keep the create editor open after persist - ...and 2 more commits
…bal-packages@1415ab3...c30e984 - test(blocks-core): adapt Navigation e2e for WordPress 7.1 - test(dev-cypress): add WordPress 7.1 Navigation add helpers - fix(global-styles-ui): sync creating-step ids into the repeater store
Keep the host .docker template aligned with the wp-env inject source so local image builds ignore expired Debian InRelease files.
…bal-packages@c30e984...5557e6d - test(dev-tools): cover wp-env apt update InRelease inject - ci(dev-tools): ignore expired apt InRelease on wp-env start
Match the GP template: stretch/buster/bullseye use archive.debian.org after LTS; current suites stay on ftp/security.
…al-packages@ec294ad...fbe636c - ci: archive bullseye apt sources in wp-env Dockerfiles
52c2844 to
25a9614
Compare
…bal-packages@fbe636c...cc48e63 - test: cover sources.list on bullseye archive sed inject - ci: keep sources.list on wp-env buster-updates sed inject
Summary
Pins
packages/global-packagesto the editor React performance work from the block-editor audit (behavior freeze: same attributes, CSS strings, inspector groups, and persist timing).Current pin:
7b04ce8. Shared package range: blockera-global-packages5cdca5b...7b04ce8BlockStylereads current block / state / breakpoint from the owningBlockBaseinstead of the global extensions UI store, so unselected blocks do not regenerate CSS when another block’s inner target changes.deviceTypeis unchanged. Colliding Gutenbergbackground+backgroundColorReact styles are rewritten only on the canvas wrapper (not saved HTML); the wrap is registered once and skipped when there is nothing to rewrite.BlockEditContextsplits identity vs attributes; style extensions skip re-render when their value slice is unchanged;ControlContextProviderkeeps a stable context identity, queues missing controls during render and flushes them in one WP data batch (no siblingsetStateduring render), and does not mount children until the store record exists so repeaters do not crash. Feature search no longer deep-clones settings before filtering. Background color edits skip rebuilding Image & Gradient layers. WordPress Styles/Settings inspector groups still all mount.applyFiltersruns once per CSS burst; fingerprints reuse stringify when the attributes object identity is unchanged and token nested trees by identity for color-only updates; empty unsaved states skip the selector walk;CssGeneratoris reused within a declarations pass. No CSSOM change.ResetIconforwards the WordPress Tooltip ref; SketchdefaultPropsare stripped on import; react-colorCheckboardis replaced withoutdefaultProps.Phase 4 (lazy Monaco / extension chunks) was left out of this pin.
Test plan
isNormalStatestill behave as before.npm run test:js -- --testPathPattern="style-engine/test/(canvas-isolation-oracle|style-engine-cpu|computed-css-declarations|should-print)"npm run test:js -- --testPathPattern="(are-extension-props-equal|retain-if-equal)"npm run test:js -- --testPathPattern="(enqueue-control-registration|resolve-control-select-result|split-background-style)"npm run test:e2e -- --spec packages/global-packages/packages/editor/js/extensions/libs/border-and-shadow/test/border-radius.e2e.cy.js(coverssavePage/ success notice).github/performance/editor-scenarios.json(select blocks, workspace tabs, block bg color).ControlContextProvidersetState-during-render warning, and repeater panels (Image & Gradient, shadows) still open.