Bug 249909 - Very slow layout of flexbox containing overflow-wrap or word-break
Summary: Very slow layout of flexbox containing overflow-wrap or word-break
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: Safari 16
Hardware: All macOS 13
: P2 Normal
Assignee: zalan
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2022-12-27 06:55 PST by Dmitry Chestnykh
Modified: 2022-12-31 07:53 PST (History)
6 users (show)

See Also:


Attachments
Bug demo (26.71 KB, text/html)
2022-12-27 06:55 PST, Dmitry Chestnykh
no flags Details
Instruments screenshot (1.82 MB, image/png)
2022-12-27 06:55 PST, Dmitry Chestnykh
no flags Details
Patch (3.91 KB, patch)
2022-12-29 20:45 PST, zalan
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Chestnykh 2022-12-27 06:55:02 PST
Created attachment 464225 [details]
Bug demo

The following combination of elements:

display: flex >
  overflow-wrap: anywhere >
    display: inline

with a large enough one-line string in the last element
makes Safari spend 10s of seconds to layout and display it.

The example is attached.

Chrome renders it instantly, while Safari Version 16.1 (18614.2.9.1.12) and at least up to the nightly 258335@main takes ~13 seconds on my Mac and iPhone.

- If I replace overflow-wrap: anywhere with word-break: break-all, layout still takes the same time.

However,

- If I remove display: flex from the parent element, it renders instantly.
- If I remove overflow-wrap or word-break, it render instantly.
- If I add position: relative to the #root and position: absolute to the #child, it renders instantly.
- If I replace the span content, which contains 24K numbers in one line, with a repeated pattern (I tried "aaaa..." and "AaAaAa..."), it renders much faster.

It also breaks GitHub: if I open a gist with the attached example, https://gist.github.com/dchest/1e49eadd9c00e109efb3fccca93d56a4 , it shows all sorts of rendering bugs.

Instruments (if I'm reading them right) show that most of the time is spent in WebCore::Font:applyTransforms.
Comment 1 Dmitry Chestnykh 2022-12-27 06:55:54 PST
Created attachment 464226 [details]
Instruments screenshot
Comment 2 zalan 2022-12-27 10:53:48 PST
Thanks for the detailed bug report! I bet we spend most of the time in the min preferred width computation (where the horizontal constraint is 0px). -which means this is not specific to flex, but all shrink-to-fit type of layouts.
Comment 3 Radar WebKit Bug Importer 2022-12-27 10:54:05 PST
<rdar://problem/103728723>
Comment 4 Dmitry Chestnykh 2022-12-27 10:57:08 PST
(In reply to zalan from comment #2)
> Thanks for the detailed bug report! I bet we spend most of the time in the
> min preferred width computation (where the horizontal constraint is 0px).
> -which means this is not specific to flex, but all shrink-to-fit type of
> layouts.

Ah, indeed, I forgot that it also happened with display: grid when I tried to reduce the test case.
Comment 5 zalan 2022-12-27 11:12:48 PST
(In reply to Dmitry Chestnykh from comment #4)
> (In reply to zalan from comment #2)
> > Thanks for the detailed bug report! I bet we spend most of the time in the
> > min preferred width computation (where the horizontal constraint is 0px).
> > -which means this is not specific to flex, but all shrink-to-fit type of
> > layouts.
> 
> Ah, indeed, I forgot that it also happened with display: grid when I tried
> to reduce the test case.
cool, thanks! will look into this.
Comment 6 zalan 2022-12-29 16:15:40 PST
ah, this is a inline box (<span>) inside the block container case. We must be missing some cache hits here and keep re-measuring the text :|. When the text content's direct parent is the block container, the page loads fairly quickly. Should be relatively easy to address this.
Comment 7 zalan 2022-12-29 20:45:12 PST
Created attachment 464255 [details]
Patch
Comment 8 Dmitry Chestnykh 2022-12-29 23:49:55 PST
(In reply to zalan from comment #6)
> ah, this is a inline box (<span>) inside the block container case.
> We must be missing some cache hits here and keep re-measuring the text :|.
> When the text content's direct parent is the block container, the page
> loads fairly quickly.

True, my current workaround is to use <div> instead of <span> for that content :)

> Should be relatively easy to address this.

Thank you!
Comment 9 EWS 2022-12-31 07:53:48 PST
Committed 258369@main (c17a7e439258): <https://commits.webkit.org/258369@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 464255 [details].