[Cascade] remove unnecessary use of EUITruncateText#256254
Merged
Merged
Conversation
Contributor
|
Pinging @elastic/appex-sharedux (Team:SharedUX) |
Contributor
davismcphee
approved these changes
Mar 5, 2026
Contributor
davismcphee
left a comment
There was a problem hiding this comment.
Wow this is a HUGE improvement! Thanks for the investigation and fix, already a big step toward closing the perf gap 🙌
Before:
before.mp4
After:
after.mp4
Also a note to self that EuiTextTruncate is apparently quite expensive 😅
Contributor
|
Starting backport for target branches: 9.3 https://github.com/elastic/kibana/actions/runs/22753428436 |
Contributor
💔 All backports failed
Manual backportTo create the backport manually run: Questions ?Please refer to the Backport tool documentation |
kapral18
pushed a commit
to kapral18/kibana
that referenced
this pull request
Mar 9, 2026
## Summary Part of elastic#255745, Culled from elastic#256037. This PR removes the usage of the the eui component `TruncateText` for titles in the discover cascade experience, in replacement for the much simpler [`line-clamp`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/line-clamp) property. line clamp is supported in most browsers besides IE and Opera Mini [see here](https://caniuse.com/?search=line-clamp). ### Why are we doing this? The component `TruncateText` uses a canvas to measure text to determine how text can be displayed in addition it also adds a resizer so it can make adjustments for the amount for the text to display to the user. For our use case this is an overkill given we were already virtualising items, so this resulted in a large chunk of unnecessary work being done. See trace profile below; <img width="2558" height="1092" alt="Screenshot 2026-03-05 at 15 02 01" src="https://github.com/user-attachments/assets/a4675691-36f4-41fe-9895-d11c0c576871" /> _Figure: Trace profile with eui truncate text_ <img width="2558" height="1142" alt="Screenshot 2026-03-05 at 15 15 26" src="https://github.com/user-attachments/assets/a52c3224-f68e-4ba6-9926-7cc7a7f7d0fa" /> _Figure: Trace profile without eui truncate text_ ### Performance improvements (Chrome DevTools Trace comparison analysis by cursor) | Metric | Before (with `EuiTextTruncate`) | After (CSS clamp) | Improvement | |---|---|---|---| | **UpdateLayoutTree (style recalc)** | **2,328 ms** across 150 events | **528 ms** across 69 events | **~77% reduction** (1,800 ms saved) | | **Total rendering cost** | **2,391 ms** | **632 ms** | **~74% reduction** | | **Long tasks > 50 ms (count)** | 6 | 18 | More tasks, but far smaller (see below) | | **Worst long task** | 2,374 ms | 2,256 ms | ~5% shorter | | **Mean long task duration** | 1,010 ms | 299 ms | **~70% reduction** | | **Long tasks > 1 s** | 3 | 1 | Eliminated 2 multi-second jank frames | ### Key takeaways - **Style recalculation is the headline win.** The before trace shows 150 `UpdateLayoutTree` events — all in the 10–31 ms range — totalling 2.3 s. After the change there are only 69 events (37 of which are sub-1 ms), totalling 528 ms. This is because `EuiTextTruncate` forces the browser to synchronously recalculate styles to measure text width on every render pass. - **Long task severity drops dramatically.** Before the change, 3 long tasks exceeded 1 second (up to 2.4 s), and the mean long task was over 1 s. After the change only 1 long task exceeds 1 s (the initial pointer-out handler, which is unrelated to truncation), and 9 of the 18 long tasks fall in the 100–200 ms range — well below the "noticeable jank" threshold. - **Scroll is significantly smoother.** The before trace processed only 7 scroll events during the capture window; the after trace processed 43 scroll events in roughly the same window. This means the browser was able to dispatch and paint far more scroll frames, resulting in visibly smoother scrolling. - **The rendering pipeline is no longer the bottleneck.** Total rendering cost dropped from 2.4 s to 0.6 s, meaning the main thread spends ~74% less time in layout/style work during scroll. ### What changed Replaced `<EuiTextTruncate>` (JS-measured truncation with a render callback) with a CSS `-webkit-line-clamp: 2` approach on the `<h4>` element, which lets the browser handle truncation natively without requiring layout measurement. The visual result is equivalent — text is truncated with an ellipsis — but with no JavaScript overhead. That been said there's still couple of improvements to be made. ### Visuals <img width="993" height="758" alt="Screenshot 2026-03-05 at 15 38 36" src="https://github.com/user-attachments/assets/3c799132-4280-45c0-95f9-d3dc33d3c67e" /> _Figure: Cascade experience with Truncate Text, note text ellipsis shows at one line_ <img width="1152" height="901" alt="Screenshot 2026-03-05 at 15 37 42" src="https://github.com/user-attachments/assets/5da7666c-cfd3-4d07-905b-7e3988037f94" /> _Figure: Cascade experience with line clamp, note text ellipsis shows at 2 lines to match CATEGORIZE pattern behaviour_ <!-- ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [ ] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [See some risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) - [ ] ... -->
qn895
pushed a commit
to qn895/kibana
that referenced
this pull request
Mar 11, 2026
## Summary Part of elastic#255745, Culled from elastic#256037. This PR removes the usage of the the eui component `TruncateText` for titles in the discover cascade experience, in replacement for the much simpler [`line-clamp`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/line-clamp) property. line clamp is supported in most browsers besides IE and Opera Mini [see here](https://caniuse.com/?search=line-clamp). ### Why are we doing this? The component `TruncateText` uses a canvas to measure text to determine how text can be displayed in addition it also adds a resizer so it can make adjustments for the amount for the text to display to the user. For our use case this is an overkill given we were already virtualising items, so this resulted in a large chunk of unnecessary work being done. See trace profile below; <img width="2558" height="1092" alt="Screenshot 2026-03-05 at 15 02 01" src="https://github.com/user-attachments/assets/a4675691-36f4-41fe-9895-d11c0c576871" /> _Figure: Trace profile with eui truncate text_ <img width="2558" height="1142" alt="Screenshot 2026-03-05 at 15 15 26" src="https://github.com/user-attachments/assets/a52c3224-f68e-4ba6-9926-7cc7a7f7d0fa" /> _Figure: Trace profile without eui truncate text_ ### Performance improvements (Chrome DevTools Trace comparison analysis by cursor) | Metric | Before (with `EuiTextTruncate`) | After (CSS clamp) | Improvement | |---|---|---|---| | **UpdateLayoutTree (style recalc)** | **2,328 ms** across 150 events | **528 ms** across 69 events | **~77% reduction** (1,800 ms saved) | | **Total rendering cost** | **2,391 ms** | **632 ms** | **~74% reduction** | | **Long tasks > 50 ms (count)** | 6 | 18 | More tasks, but far smaller (see below) | | **Worst long task** | 2,374 ms | 2,256 ms | ~5% shorter | | **Mean long task duration** | 1,010 ms | 299 ms | **~70% reduction** | | **Long tasks > 1 s** | 3 | 1 | Eliminated 2 multi-second jank frames | ### Key takeaways - **Style recalculation is the headline win.** The before trace shows 150 `UpdateLayoutTree` events — all in the 10–31 ms range — totalling 2.3 s. After the change there are only 69 events (37 of which are sub-1 ms), totalling 528 ms. This is because `EuiTextTruncate` forces the browser to synchronously recalculate styles to measure text width on every render pass. - **Long task severity drops dramatically.** Before the change, 3 long tasks exceeded 1 second (up to 2.4 s), and the mean long task was over 1 s. After the change only 1 long task exceeds 1 s (the initial pointer-out handler, which is unrelated to truncation), and 9 of the 18 long tasks fall in the 100–200 ms range — well below the "noticeable jank" threshold. - **Scroll is significantly smoother.** The before trace processed only 7 scroll events during the capture window; the after trace processed 43 scroll events in roughly the same window. This means the browser was able to dispatch and paint far more scroll frames, resulting in visibly smoother scrolling. - **The rendering pipeline is no longer the bottleneck.** Total rendering cost dropped from 2.4 s to 0.6 s, meaning the main thread spends ~74% less time in layout/style work during scroll. ### What changed Replaced `<EuiTextTruncate>` (JS-measured truncation with a render callback) with a CSS `-webkit-line-clamp: 2` approach on the `<h4>` element, which lets the browser handle truncation natively without requiring layout measurement. The visual result is equivalent — text is truncated with an ellipsis — but with no JavaScript overhead. That been said there's still couple of improvements to be made. ### Visuals <img width="993" height="758" alt="Screenshot 2026-03-05 at 15 38 36" src="https://github.com/user-attachments/assets/3c799132-4280-45c0-95f9-d3dc33d3c67e" /> _Figure: Cascade experience with Truncate Text, note text ellipsis shows at one line_ <img width="1152" height="901" alt="Screenshot 2026-03-05 at 15 37 42" src="https://github.com/user-attachments/assets/5da7666c-cfd3-4d07-905b-7e3988037f94" /> _Figure: Cascade experience with line clamp, note text ellipsis shows at 2 lines to match CATEGORIZE pattern behaviour_ <!-- ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [ ] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [See some risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) - [ ] ... -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Part of #255745,
Culled from #256037.
This PR removes the usage of the the eui component
TruncateTextfor titles in the discover cascade experience, in replacement for the much simplerline-clampproperty. line clamp is supported in most browsers besides IE and Opera Mini see here.Why are we doing this?
The component
TruncateTextuses a canvas to measure text to determine how text can be displayed in addition it also adds a resizer so it can make adjustments for the amount for the text to display to the user. For our use case this is an overkill given we were already virtualising items, so this resulted in a large chunk of unnecessary work being done.See trace profile below;
Figure: Trace profile with eui truncate text
Figure: Trace profile without eui truncate text
Performance improvements (Chrome DevTools Trace comparison analysis by cursor)
EuiTextTruncate)Key takeaways
Style recalculation is the headline win. The before trace shows 150
UpdateLayoutTreeevents — all in the 10–31 ms range — totalling 2.3 s. After the change there are only 69 events (37 of which are sub-1 ms), totalling 528 ms. This is becauseEuiTextTruncateforces the browser to synchronously recalculate styles to measure text width on every render pass.Long task severity drops dramatically. Before the change, 3 long tasks exceeded 1 second (up to 2.4 s), and the mean long task was over 1 s. After the change only 1 long task exceeds 1 s (the initial pointer-out handler, which is unrelated to truncation), and 9 of the 18 long tasks fall in the 100–200 ms range — well below the "noticeable jank" threshold.
Scroll is significantly smoother. The before trace processed only 7 scroll events during the capture window; the after trace processed 43 scroll events in roughly the same window. This means the browser was able to dispatch and paint far more scroll frames, resulting in visibly smoother scrolling.
The rendering pipeline is no longer the bottleneck. Total rendering cost dropped from 2.4 s to 0.6 s, meaning the main thread spends ~74% less time in layout/style work during scroll.
What changed
Replaced
<EuiTextTruncate>(JS-measured truncation with a render callback) with a CSS-webkit-line-clamp: 2approach on the<h4>element, which lets the browser handle truncation natively without requiring layout measurement. The visual result is equivalent — text is truncated with an ellipsis — but with no JavaScript overhead.That been said there's still couple of improvements to be made.
Visuals
Figure: Cascade experience with Truncate Text, note text ellipsis shows at one line
Figure: Cascade experience with line clamp, note text ellipsis shows at 2 lines to match CATEGORIZE pattern behaviour