System font rasterization on macOS 11+ slows down page load, tab opening and tab switching
Categories
(Core :: Graphics: WebRender, defect, P3)
Tracking
()
People
(Reporter: mstange, Assigned: jrmuizel)
References
(Blocks 3 open bugs)
Details
(Keywords: perf, perf:responsiveness)
Attachments
(2 files)
The default new tab page displays some text, for example in the Pocket suggestions. This text uses the system font.
With WebRender, we seem to be re-rasterizing system font glyphs on every new tab. Creating system fonts seems to be particularly slow on Big Sur. This delays the paint of the new tab by 100ms.
Loading pages that use system fonts, for example github or stackoverflow, also incurs this issue.
Tab switching can also hit this, for tabs that haven't been painted in a while.
Steps to reproduce:
- Open a new Firefox window, and navigate to mozilla.org.
- Press Cmd+T to open a new tab.
- Press Cmd+T again to open another new tab.
Expected results:
Opening a new tab, or switching between github tabs, or loading a gith, should be really fast.
Actual results:
There is a 100ms paint delay. Profile: https://share.firefox.dev/3nIPe0B
You can see "BlockOnResources" markers on the RenderBackend thread that take over 100ms.
Comment 1•3 years ago
|
||
The profile doesn't have symbols for where we're jumping off into CoreText. Is there any way to know which call is triggering the delay? Is it when creating the font, or when we try to get the symbolic traits? it would be useful to know.
Reporter | ||
Comment 2•3 years ago
|
||
Here's the breakdown I get after I disabled multithreaded font rasterization:
- 56% GetSymbolicTraits
- 20% CTFontCreateWithGraphicsFont
- 4% CTFontCopyVariationAxes
- 6% CTFontDrawGlyphs
There are parts of this that interact with the "font registry" via XPC calls; those are TBaseFont::CopyVariationProperties
(called by CTFontCreateWithGraphicsFont and by CTFontCopyVariationAxes) and TBaseFont::CopyName
(called by CTFontCreateWithGraphicsFont).
With multiple worker threads, the XPC parts probably take longer as they contend for the font registry.
GetSymbolicTraits seems to be slow because it's parsing 110KB of JSON.
To fix this, I would recommend making it possible to share font resources for system fonts across tabs. At the moment, every tab has its own FontKey IdNamespace, so no sharing is attempted.
Reporter | ||
Comment 3•3 years ago
|
||
Reporter | ||
Comment 4•3 years ago
|
||
(In reply to Markus Stange [:mstange] from comment #2)
To fix this, I would recommend making it possible to share font resources for system fonts across tabs. At the moment, every tab has its own FontKey IdNamespace, so no sharing is attempted.
Furthermore, at least for system fonts, whether a font is a bitmap font is probably independent of the font size and variations. It would be good to query the traits only once per font name (?) rather than once per font instance.
Reporter | ||
Comment 5•3 years ago
|
||
With the call to GetSymbolicTraits commented out, the delay goes down from 100ms to 50ms.
Profile with 50ms BlockOnResources markers: https://share.firefox.dev/34yYP2E
On the worker threads, of the non-idle time, 52% are now spent inside libFontRegistry.dylib.
Reporter | ||
Comment 6•3 years ago
|
||
With GlyphRasterizer
's enable_multithreading
field forced to false, BuildFrame times go down by another 10ms. https://share.firefox.dev/2KT4ucL
Updated•3 years ago
|
Updated•3 years ago
|
Reporter | ||
Updated•3 years ago
|
Updated•3 years ago
|
Reporter | ||
Updated•3 years ago
|
Reporter | ||
Updated•3 years ago
|
Reporter | ||
Comment 7•3 years ago
•
|
||
This is still happening. It shows really clearly in the various Latency markers we now have on the compositor thread.
For example, here's a profile of me clicking the new tab button, and then loading a stackoverflow page: https://share.firefox.dev/327rxcu
The new tab button mouse click has: "MouseUpFollowedByClick Payload Presented - Latency: 232ms"
The stackoverflow paint has: "ContentPaint Payload Presented - Latency: 264ms"
This is on a really fast M1 machine.
Assignee | ||
Comment 8•3 years ago
|
||
It looks like it's the localization of the names that's causing the biggest problem. It would help if we could get away from using CGFonts for system fonts. Perhaps it's worth looking at better understanding what was going on in bug 1675185 to see if we can fix it a different way.
Assignee | ||
Comment 9•2 years ago
|
||
This should fix the performance we're seeing with localization and the
variations should already be validated by the content process.
Comment 10•2 years ago
|
||
What happens if invalid axis tags or wildly out-of-range values are passed to Core Text (via core_text::font::new_from_descriptor) -- can we rely on it safely ignoring them?
Assignee | ||
Comment 11•2 years ago
|
||
It seems the answer depends on the version of macOS:
https://github.com/servo/core-foundation-rs/blob/3c92593b70a76105d34fc0e011d0eaeeff7b186c/core-text/src/font.rs#L794
Comment 12•2 years ago
|
||
Pushed by jmuizelaar@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/91a78c45d3af Don't validate the variations when constructing the CTFont. r=jfkthame
Reporter | ||
Updated•2 years ago
|
Comment 13•2 years ago
|
||
bugherder |
Reporter | ||
Comment 14•2 years ago
|
||
It looks like there's more work to do here. Opening a new tab is still slow on macOS 12. Now we spend all the time in core_text::font_descriptor::CTFontDescriptor::create_copy_with_attributes
. https://share.firefox.dev/3dKjzIS
I've filed bug 1745591 about the rest of the work.
Updated•2 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Description
•