Closed Bug 1674228 Opened 5 years ago Closed 5 years ago

Firefox takes a long time to load emoji when emoji font is set to "Noto Color Emoji"

Categories

(Core :: Layout: Text and Fonts, defect, P3)

Firefox 82
defect

Tracking

()

RESOLVED FIXED
84 Branch
Performance Impact ?
Tracking Status
firefox-esr78 --- unaffected
firefox82 --- wontfix
firefox83 --- fixed
firefox84 --- fixed

People

(Reporter: sumagnadas, Assigned: emilio)

References

(Regression)

Details

(Keywords: perf-alert, regression)

Attachments

(3 files, 1 obsolete file)

User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0

Steps to reproduce:

I was using Instagram where i didn't like the emoji style so i switched the emoji style from "Twemoji Mozilla" to "Noto Color emoji". After switching the emoji picker in DMs took about a minute to load. This is the perf profile ->

Prerequisite:-

  • Noto Color Emoji font
  • Ubuntu

Steps to Reproduce:

  1. Change font.name-list.emoji from "Twemoji Mozilla" to "Noto Color Emoji"
  2. visit getemoji.com

Actual results:

It takes an unusual amount of time to load the emojis in the site hence it doesn't open very fast. The same happens with the emoji picker in instagram DM.

Expected results:

It should have opened within a few seconds or milliseconds.

This is the perf profile -> https://share.firefox.dev/3mAp5jW

I can confirm (on Fedora, if it matters). https://share.firefox.dev/31WVlFM is me loading getemoji.com.

Severity: -- → S2
Status: UNCONFIRMED → NEW
Component: Untriaged → Layout: Text and Fonts
Ever confirmed: true
Priority: -- → P3
Product: Firefox → Core

I can try to poke at this.

Flags: needinfo?(emilio)

We're trying to get the same table over and over on the same font instance (or a couple ones). If I log calls to CopyFontTable I get:

CopyFontTable(0x7feed09c6bb0, 43424454)

But there is supposed to be a font table cache that avoids this problem.

(The table is CBDT fwiw)

So, I'm very confused about what I'm seeing, halp Jonathan.

So, HasFontTable effectively gets the table and checks it's not empty. So far so good.

AutoTable will do mBlob = aFontEntry->GetFontTable(aTag); and then it'll call hb_blob_destroy on the blob we just got, so it expects an addrefed blob.

AutoTable calls GetFontTable, which looks in a cache and if it doesn't hit the cache we go and grab a blob and return it. The problem is that the cache doesn't keep a reference to the blob (intentionally it seems, per this comment).

So as soon as AutoTable gets destroyed we unref the blob, and since the cache doesn't keep a reference to it we remove it from the cache... So the cache is effectively only being effective for empty tables.

So in terms of fixing we could:

  • Override gfxFontconfigFontEntry::HasFontTable to do something faster.
  • Tweak the font table cache to actually work when you copy a table.

The second could look like this (plus removing ManageHashEntry and such):

diff --git a/gfx/thebes/gfxFontEntry.cpp b/gfx/thebes/gfxFontEntry.cpp
index f776614603f1..8088f19fd744 100644
--- a/gfx/thebes/gfxFontEntry.cpp
+++ b/gfx/thebes/gfxFontEntry.cpp
@@ -487,8 +487,7 @@ hb_blob_t* gfxFontEntry::FontTableHashEntry::ShareTableAndGetBlob(
 
-  // Tell the FontTableBlobData to remove this hash entry when destroyed.
-  // The hashtable does not keep a strong reference.
-  mSharedBlobData->ManageHashEntry(aHashtable, GetKey());
-  return mBlob;
+  return hb_blob_reference(mBlob);
 }
 
 void gfxFontEntry::FontTableHashEntry::Clear() {

But what am I missing?

Flags: needinfo?(jfkthame)

So as repeated calls to HasFontTable don't load a table over and over.

If this is too hard on memory we may want keep a cache specific to
HasFontTable or something instead, maybe? But I think this should be
fine, we probably end up using all tables we check for.

Assignee: nobody → emilio
Status: NEW → ASSIGNED
Flags: needinfo?(emilio)
Whiteboard: [qf]

(In reply to Emilio Cobos Álvarez (:emilio) from comment #7)

Created attachment 9184638 [details]
Bug 1674228 - Make gfxFontEntry table cache keep a strong reference to its blob. r=jfkthame

So as repeated calls to HasFontTable don't load a table over and over.

If this is too hard on memory we may want keep a cache specific to
HasFontTable or something instead, maybe? But I think this should be
fine, we probably end up using all tables we check for.

IIRC, this table cache was set up so that multiple gfxFont instances of the same gfxFontEntry will share table data rather than each loading it separately; but the data will be released when all font instances using it are destroyed. We don't want the gfxFontEntry itself to keep ownership of the cached table data, though, because the font entry stays around for the entire life of the process.

So in this case, giving the gfxFontEntry table cache a strong reference means that as soon as we've checked for the (huge) color-bitmap table in Noto Color Emoji once, it'll stay in memory. That's unfortunate, as it might never be needed again.

I'd prefer, therefore, to avoid holding on to the table data here; instead, I think we should do something (probably based on FT_Sfnt_Table_Info) to check for the existence of a table without actually loading it. (Do you want to write this version, or should I take it? Either works for me.)

A much simpler fix for this specific case would be to just add a boolean flag in gfxFontEntry to cache the result in HasColorBitmapTable() instead of letting it call HasFontTable() every time. It's probably worth doing that, too, but I think we should also improve HasFontTable for the Freetype-based backends so that it never copies table data.

Flags: needinfo?(jfkthame) → needinfo?(emilio)

So here's the simple fix that I think we should take straight away; I think it's also worth optimizing HasFontTable for Freetype-based backends (i.e. both Linux and Android), but we can do that separately as a followup. The patch above should fix the really bad behavior here already.

(In reply to Jonathan Kew (:jfkthame) from comment #10)

So here's the simple fix that I think we should take straight away; I think it's also worth optimizing HasFontTable for Freetype-based backends (i.e. both Linux and Android), but we can do that separately as a followup. The patch above should fix the really bad behavior here already.

Hah, I was writing this :-)

Flags: needinfo?(emilio)
Attachment #9184638 - Attachment is obsolete: true

Cool, you've done the followup already too :) ... LGTM.

By the way, I suspect the performance here regressed recently as a result of bug 1371386, which meant that we're much more careful about color- vs monochrome-font selection. Could you try the example on Firefox 81 (i.e. before that change) and see how the behavior compared? If it's a clear regression, that would strengthen the case for uplifting at least the simple patch here.

Flags: needinfo?(emilio)

Yeah, I bisected this and indeed bug 1371386 is in the range (I stopped after a while).

Flags: needinfo?(emilio)
Keywords: regression
Regressed by: 1371386
Has Regression Range: --- → yes

Comment on attachment 9184744 [details]
Bug 1674228 - Cache the result of the HasFontTable checks in gfxFontEntry::HasColorBitmapTable. r=emilio

Beta/Release Uplift Approval Request

  • User impact if declined: Poor performance on Linux/Android when Noto Color Emoji is used (or other large color-bitmap fonts)
  • Is this code covered by automated tests?: Yes
  • Has the fix been verified in Nightly?: No
  • Needs manual test from QE?: No
  • If yes, steps to reproduce:
  • List of other uplifts needed: None
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): Trivial patch to cache the result a potentially-expensive font probe
  • String changes made/needed:
Attachment #9184744 - Flags: approval-mozilla-beta?

Just uplifting the smaller/simpler patch here (D95279) should be enough to address the bad perf regression, I believe.

Pushed by ealvarez@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/ea800bc80f16 Speed up HasFontTable checks for freetype fonts. r=jfkthame
Pushed by jkew@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/0b6bb7278ef6 Cache the result of the HasFontTable checks in gfxFontEntry::HasColorBitmapTable. r=emilio
Pushed by emilio@crisal.io: https://hg.mozilla.org/integration/autoland/rev/4c99eba6641e Rename some functions to avoid a gcc false-positive warnings.
Attached image gambar.png

emoji.json

Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → 84 Branch

Set release status flags based on info from the regressing bug 1371386

Comment on attachment 9184744 [details]
Bug 1674228 - Cache the result of the HasFontTable checks in gfxFontEntry::HasColorBitmapTable. r=emilio

Low risk patch for a significant performance regression on Linux, uplift approved for 83 beta 8, thanks.

Attachment #9184744 - Flags: approval-mozilla-beta? → approval-mozilla-beta+

== Change summary for alert #27536 (as of Fri, 06 Nov 2020 06:06:13 GMT) ==

Improvements:

Ratio Suite Test Platform Options Absolute values (old vs new)
7% ebay-kleinanzeigen-search android-hw-p2-8-0-android-aarch64-shippable warm 448.84 -> 418.28
3% cnn-ampstories FirstVisualChange android-hw-g5-7-0-arm7-api-16-shippable live warm 1,245.12 -> 1,203.42
3% cnn-ampstories ContentfulSpeedIndex android-hw-g5-7-0-arm7-api-16-shippable live warm 1,245.12 -> 1,203.92
3% cnn-ampstories LastVisualChange android-hw-g5-7-0-arm7-api-16-shippable live warm 1,249.29 -> 1,208.08
3% cnn-ampstories SpeedIndex android-hw-g5-7-0-arm7-api-16-shippable live warm 1,245.12 -> 1,204.25
3% cnn-ampstories PerceptualSpeedIndex android-hw-g5-7-0-arm7-api-16-shippable live warm 1,245.92 -> 1,205.42

For up to date results, see: https://treeherder.mozilla.org/perfherder/alerts?id=27536

Keywords: perf-alert

== Change summary for alert #27541 (as of Fri, 06 Nov 2020 10:11:00 GMT) ==

Improvements:

Ratio Suite Test Platform Options Absolute values (old vs new)
4% Resident Memory linux1804-64-shippable 656,606,079.01 -> 630,163,543.56
3% Resident Memory linux1804-64-shippable-qr 1,192,650,563.23 -> 1,151,781,434.68

For up to date results, see: https://treeherder.mozilla.org/perfherder/alerts?id=27541

Performance Impact: --- → ?
Whiteboard: [qf]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: