Skip to content

[Cascade] remove unnecessary use of EUITruncateText#256254

Merged
eokoneyo merged 1 commit into
elastic:mainfrom
eokoneyo:chore/remove-eui-truncate-text
Mar 6, 2026
Merged

[Cascade] remove unnecessary use of EUITruncateText#256254
eokoneyo merged 1 commit into
elastic:mainfrom
eokoneyo:chore/remove-eui-truncate-text

Conversation

@eokoneyo
Copy link
Copy Markdown
Contributor

@eokoneyo eokoneyo commented Mar 5, 2026

Summary

Part of #255745,
Culled from #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 property. line clamp is supported in most browsers besides IE and Opera Mini see here.

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;

Screenshot 2026-03-05 at 15 02 01

Figure: Trace profile with eui truncate text

Screenshot 2026-03-05 at 15 15 26

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

Screenshot 2026-03-05 at 15 38 36

Figure: Cascade experience with Truncate Text, note text ellipsis shows at one line

Screenshot 2026-03-05 at 15 37 42

Figure: Cascade experience with line clamp, note text ellipsis shows at 2 lines to match CATEGORIZE pattern behaviour

@eokoneyo eokoneyo self-assigned this Mar 5, 2026
@eokoneyo eokoneyo requested a review from a team as a code owner March 5, 2026 14:18
@eokoneyo eokoneyo added Feature:Discover Discover Application Team:SharedUX Platform AppEx-SharedUX (formerly Global Experience) t// labels Mar 5, 2026
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/appex-sharedux (Team:SharedUX)

@eokoneyo eokoneyo added release_note:skip Skip the PR/issue when compiling release notes backport:version Backport to applied version labels v9.3.2 labels Mar 5, 2026
@elasticmachine
Copy link
Copy Markdown
Contributor

💚 Build Succeeded

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
discover 1.6MB 1.6MB +23.0B

cc @eokoneyo

Copy link
Copy Markdown
Contributor

@davismcphee davismcphee left a comment

Choose a reason for hiding this comment

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

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 😅

@eokoneyo eokoneyo merged commit d37bfed into elastic:main Mar 6, 2026
29 checks passed
@eokoneyo eokoneyo deleted the chore/remove-eui-truncate-text branch March 6, 2026 07:21
@kibanamachine
Copy link
Copy Markdown
Contributor

Starting backport for target branches: 9.3

https://github.com/elastic/kibana/actions/runs/22753428436

@kibanamachine
Copy link
Copy Markdown
Contributor

💔 All backports failed

Status Branch Result
9.3 Backport failed because of merge conflicts

You might need to backport the following PRs to 9.3:
- [Lens] Fix - Library annotation group does not sync across panels after update (#252640)
- [Search Content Connectors] Add generate api key server-side implementation (#256083)

Manual backport

To create the backport manually run:

node scripts/backport --pr 256254

Questions ?

Please refer to the Backport tool documentation

@eokoneyo eokoneyo removed backport:version Backport to applied version labels v9.3.2 labels Mar 6, 2026
@kibanamachine kibanamachine added the backport:skip This PR does not require backporting label Mar 6, 2026
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)
- [ ] ...


-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting Feature:Discover Discover Application release_note:skip Skip the PR/issue when compiling release notes Team:SharedUX Platform AppEx-SharedUX (formerly Global Experience) t// v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants