Rich Text: Store the anchor element only for the selected field by ellatrix · Pull Request #85983 · WordPress/gutenberg · GitHub
Skip to content

Rich Text: Store the anchor element only for the selected field - #85983

Merged
ellatrix merged 1 commit into
trunkfrom
rich-text/anchor-element-when-selected
Oct 29, 2026
Merged

ellatrix merged 1 commit into
trunkfrom
rich-text/anchor-element-when-selected

Conversation

@ellatrix

Copy link
Copy Markdown
Member

What?

Only the selected rich text field stores its element in state, for the toolbar that needs it.

Why?

Since "Rich Text: Make inline toolbar more reactive for proper positioning" (#73853), every rich text field calls setAnchorElement( element ) from its ref when it mounts. The state change renders every field a second time, running all of the wrapper's hooks again, although only the selected field shows the format toolbar that reads the element.

Mounting 500 blocks, in µs per block (3 runs each):

Trunk This PR
Paragraph 92, 88, 87 73, 72, 69
Block with only RichText 78, 75, 71 64, 62, 61
Block without rich text 44, 40, 41 45, 43, 40

How?

The merged ref only includes setAnchorElement while the field is selected. When a field becomes selected, the merged ref calls it with the element before paint, so only that field renders again. The toolbar renders only while the field is selected, so it still gets the element.

Testing Instructions

  1. Open a post with a few paragraphs and an image with a caption.
  2. Select text in a paragraph: the block toolbar shows the formats. Add a link: the link popover opens below the selected text.
  3. Select text in the image caption: the inline format toolbar appears next to the caption.
  4. Remove the caption and add it again, then select its text: the inline toolbar appears next to the new caption.

Testing Instructions for Keyboard

Select text with Shift and the arrow keys, and add a link with Cmd+K.

Screenshots or screencast

No visual change.

Use of AI Tools

Written with Claude Code (Claude Opus 5.5). Reviewed by the author.

🤖 Generated with Claude Code

Every field stored its element in state when it mounted, which rendered
each field a second time. Only the selected field shows the toolbar that
needs the element, so only that field stores it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ellatrix ellatrix added [Type] Performance Related to performance efforts [Package] Block editor /packages/block-editor labels Oct 29, 2026
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

Preview in WordPress Playground

🎉 Props

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: ellatrix <ellatrix@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

Updated as activity occurs, without notifying anyone named here. Add the props-bot label to refresh.

📦 Bundle size

Size Change: +2 B (0%)

Total Size: 8.56 MB

📦 View Changed
Filename Size Change
build/scripts/block-editor/index.min.js 542 kB +2 B (0%)

79cc399 Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric e6dcf7c trunk % Change
timeToFirstByte 54 ms +5.83% -4.44% 53.55 ms +3.73% -5.7% 0.84%
largestContentfulPaint 88 ms +9.09% -4.55% 88 ms +9.09% -4.55% 0%
lcpMinusTtfb 34.1 ms +3.52% -4.4% 33.9 ms +0.88% -3.39% 0.59%
wpBeforeTemplate 27.91 ms +11.43% -2.62% 27.36 ms +8.22% -2.45% 2.01%
wpTemplate 21.57 ms +3.2% -4.54% 21.78 ms +4.32% -8.77% -0.96%
wpTotal 49.93 ms +6.15% -4.93% 49.49 ms +4.16% -6.06% 0.89%
wpMemoryUsage 7.70 MB +0% -0% 7.67 MB +0% -0% 0.43%
wpDbQueries 16 +0% -0% 16 +0% -0% 0%

front-end-classic-theme

Metric e6dcf7c trunk % Change
timeToFirstByte 43.35 ms +5.31% -1.61% 39.15 ms +6.64% -1.79% 10.73%
largestContentfulPaint 96 ms +4.17% -0% 86 ms +2.33% -2.33% 11.63%
lcpMinusTtfb 53.15 ms +1.03% -1.41% 45.95 ms +3.26% -0.87% 15.67%
wpBeforeTemplate 23.76 ms +9.64% -0.88% 23.44 ms +4.82% -0.55% 1.37%
wpTemplate 16 ms +4.19% -1.38% 12.14 ms +6.43% -3.95% 31.8%
wpTotal 40.24 ms +5.22% -2.46% 36.2 ms +7.04% -1.93% 11.16%
wpMemoryUsage 6.40 MB +0% -0% 6.25 MB +0% -0% 2.32%
wpDbQueries 13 +0% -0% 9 +0% -0% 44.44%

media-processing

Metric e6dcf7c trunk % Change
mediaProcessingJpeg 418.51 ms +1.03% -1.46% 413.14 ms +2.36% -0.68% 1.3%
mediaProcessingAvif 6240.75 ms +0.93% -0.08% 6192.95 ms +0.32% -0.37% 0.77%
mediaProcessingJpegToAvif 4366.56 ms +0.14% -0.32% 4330.83 ms +0.33% -0.31% 0.83%

media-upload

Metric e6dcf7c trunk % Change
jpegUploadProcessing 1728.53 ms +12.82% -15.58% 1471.06 ms +31.94% -1.7% 17.5%
pngUploadProcessing 187.67 ms +32.39% -12.8% 247.55 ms +4.45% -4.3% -24.19%
largeJpegUploadProcessing 1493.4 ms +29.92% -2% 1702.46 ms +14.24% -13.74% -12.28%
multipleImageUploadProcessing 2031.02 ms +0.13% -0.5% 2011.28 ms +4.33% -0.17% 0.98%

post-editor

Metric e6dcf7c trunk % Change
serverResponse 353.92 ms +1.53% -3.34% 360.47 ms +1.61% -10.98% -1.82%
firstPaint 330.91 ms +18.91% -36.4% 316.89 ms +31.4% -46.91% 4.42%
domContentLoaded 667.32 ms +0.72% -1.26% 704.55 ms +0.72% -0.94% -5.28%
loaded 668.32 ms +0.72% -1.26% 705.51 ms +0.74% -0.94% -5.27%
firstContentfulPaint 391.35 ms +3.64% -2% 416.95 ms +1.19% -7.34% -6.14%
firstBlock 2085.69 ms +0.8% -1.83% 2271.58 ms +1.41% -1.55% -8.18%
type 15.12 ms +7.67% -10.32% 17.46 ms +5.44% -8.82% -13.4%
typeWithoutInspector 14.69 ms +8.85% -4.36% 16.62 ms +3.55% -9.81% -11.61%
typeWithTopToolbar 19.16 ms +3.39% -2.04% 21.16 ms +5.81% -7.37% -9.45%
typeContainer 6.79 ms +8.54% -10.16% 7.12 ms +7.58% -3.37% -4.63%
focus 97.26 ms +4.29% -2.83% 95.8 ms +2.63% -3.95% 1.52%
firstFocus 209.59 ms +0% -0% 195 ms +0% -0% 7.48%
selectAll 359.25 ms +1.59% -0.04% 357.81 ms +5.09% -1.75% 0.4%
undo 27.45 ms +5.43% -4.7% 26.83 ms +6.6% -4.03% 2.31%
listViewOpen 61.41 ms +4.67% -2.57% 60.56 ms +6.98% -5.22% 1.4%
inserterOpen 33.38 ms +3.51% -6.92% 33.47 ms +6.27% -6.66% -0.27%
inserterHover 9.52 ms +9.56% -6.62% 9.39 ms +5.86% -5.11% 1.38%
inserterSearch 7.21 ms +10.54% -9.15% 7.03 ms +11.52% -4.98% 2.56%
loadPatterns 512.24 ms +3.5% -3.67% 507.71 ms +6% -1.69% 0.89%
wpTotal 344.38 ms +1.73% -3.3% 351.61 ms +1.59% -11.26% -2.06%
wpMemoryUsage 14.73 MB +0% -0% 14.72 MB +0% -0% 0.1%
wpDbQueries 55 +0% -0% 55 +0% -0% 0%

site-editor

Metric e6dcf7c trunk % Change
serverResponse 547.77 ms +4.75% -3.05% 536.25 ms +1.4% -6.08% 2.15%
firstPaint 302.56 ms +15.52% -10.45% 268.53 ms +21.3% -9.61% 12.67%
domContentLoaded 948.11 ms +0.78% -0.92% 955.7 ms +0.94% -1.17% -0.79%
loaded 949.39 ms +0.76% -0.93% 957.11 ms +0.96% -1.18% -0.81%
firstContentfulPaint 541.03 ms +0.61% -6.47% 534.67 ms +2.06% -1.52% 1.19%
firstBlock 4035.03 ms +0.85% -1.6% 4129.94 ms +0.49% -0.55% -2.3%
type 20.8 ms +13.32% -11.44% 20.94 ms +18.58% -5.11% -0.67%
navigate 127.53 ms +4.52% -4.87% 134.78 ms +1.18% -3.12% -5.38%
loadPatterns 1176.12 ms +1.83% -4.09% 1257.67 ms +8.64% -6.56% -6.48%
loadPages 1062.47 ms +2.24% -4.78% 1056.51 ms +5.25% -2.87% 0.56%
wpTotal 537.85 ms +4.75% -3.11% 525.51 ms +1.53% -6.13% 2.35%
wpMemoryUsage 12.77 MB +0% -0% 12.73 MB +0% -0% 0.27%
wpDbQueries 44 +2.27% -0% 44 +2.27% -0% 0%

79cc399 Run

🏁 Flaky tests

Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

Undo restores the post selection when another synced entity is loaded (RTC WebSocket) in /test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 2
+ Received  + 2

  Object {
    "attributeKey": "content",
    "blockIndex": 0,
    "content": "abcdef",
-   "endOffset": 3,
-   "offset": 3,
+   "endOffset": 6,
+   "offset": 6,
  }

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts:363:5
can be created by selecting text and using keyboard shortcuts in /test/e2e/specs/editor/blocks/links.spec.js, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 1
+ Received  + 1

  Array [
    Object {
      "attributes": Object {
-       "content": "This is Gutenberg",
+       "content": "This is h",
      },
      "name": "core/paragraph",
    },
  ]

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/links.spec.js:563:41
should keep correct selection when dragging outside block (-firefox) in /test/e2e/specs/editor/various/multi-block-selection.spec.js, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 1
+ Received  + 1

  Array [
    Object {
      "attributes": Object {
-       "content": "1",
+       "content": "23",
      },
      "name": "core/paragraph",
    },
  ]

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/multi-block-selection.spec.js:786:41

79cc399 Run

@ellatrix
ellatrix marked this pull request as ready for review October 29, 2026 23:22
@ellatrix
ellatrix merged commit 542c15a into trunk Oct 29, 2026
108 checks passed
@ellatrix
ellatrix deleted the rich-text/anchor-element-when-selected branch October 29, 2026 23:23
@github-actions github-actions Bot added this to the Gutenberg 24.4 milestone Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Block editor /packages/block-editor [Type] Performance Related to performance efforts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant