Open
Bug 1280260
Opened 8 years ago
Updated 2 years ago
Pause Frame Creation from JS
Categories
(Core :: DOM: Core & HTML, defect, P3)
Core
DOM: Core & HTML
Tracking
()
NEW
People
(Reporter: zbraniecki, Unassigned)
Details
(Whiteboard: [gecko-l20n])
Attachments
(5 files)
9.45 KB,
patch
|
Details | Diff | Splinter Review | |
7.10 KB,
patch
|
Details | Diff | Splinter Review | |
4.52 KB,
patch
|
Details | Diff | Splinter Review | |
1.23 KB,
patch
|
Details | Diff | Splinter Review | |
19.74 KB,
patch
|
Details | Diff | Splinter Review |
We're implementing new client-side l10n layer for Firefox and we would like to be able to avoid the race condition where we're trying to get l10n resources loaded and DOM translated before the layout happens.
We're not the only ones that need this. It's becoming a common problem where Web Apps want to alter the DOM as part of the bootstrap process before layout/firstPaint.
It has been discussed at https://groups.google.com/d/topic/mozilla.dev.platform/F3Mp6dZonMA/discussion with a thumbs-up from :sicking.
:bz said that he could expose an API for us (for chrome only code now) to enable us to do that.
We could start with chrome-only API and later consider standardizing it and exposing to the Web.
:bz - the way I thought about it would be sth like a:
document.pauseFrameCreation();
(...)
document.resumeFrameCreation();
The pausing could also be a <meta> tag maybe?
How would you envision that?
Reporter | ||
Comment 1•8 years ago
|
||
CC'ing :sicking and :mbest (per :sickin's suggestion) because it would tremendously help WebApps.
Reporter | ||
Updated•8 years ago
|
Flags: needinfo?(bzbarsky)
Reporter | ||
Updated•8 years ago
|
Blocks: gecko-l20n
Comment 2•8 years ago
|
||
I don't think we'd ever expose this sort of API to non-chrome code, fwiw. Not least because it's a best-effort thing: if someone flushes layout we _will_ construct frames.
I would probably call it document.blockLayoutStart()/document.unblockLayoutStart. It would twiddle the mPendingSheetCount (needs renaming) in nsContentSink.cpp, for the HTML case.
And for XULDocument case we'd need to do something slightly different, possibly; it uses a different mechanism to determine when to start layout.
Flags: needinfo?(bzbarsky)
I would suggest talking to the layout team.
Reporter | ||
Comment 4•8 years ago
|
||
:bz - would you be able to take this bug?
Flags: needinfo?(bzbarsky)
Comment 5•8 years ago
|
||
So I have this partially written up, but it's ending up fairly complicated (especially with XUL involved) and quite fragile. For example, any <script> following yours that touches a layout property will cause FOUC.
So for purposes of l20n, here's a question: can you just use sync XHR and take advantage of the parser-blocking <script> already does?
Flags: needinfo?(bzbarsky) → needinfo?(gandalf)
Reporter | ||
Updated•8 years ago
|
Flags: needinfo?(gandalf) → needinfo?(stas)
Comment 6•8 years ago
|
||
I'd like to keep our options open and experiment with something like document.blockLayoutStart() to see how it affects our performance.
At the same time, FOUCs haven't come up as a significant performance problem in our work so far. If they do, I'll be happy to first try sync IO as :bz suggests in comment 5.
Let's keep this bug open. I'll report in a few weeks with more data on async v. sync IO.
Flags: needinfo?(stas)
Reporter | ||
Comment 7•8 years ago
|
||
Boris said he could try to get us a POC soon :)
Flags: needinfo?(bzbarsky)
Comment 8•8 years ago
|
||
Updated•8 years ago
|
Assignee: nobody → bzbarsky
Status: NEW → ASSIGNED
Comment 9•8 years ago
|
||
Comment 10•8 years ago
|
||
Comment 11•8 years ago
|
||
Comment 12•8 years ago
|
||
Flags: needinfo?(bzbarsky)
Comment 13•8 years ago
|
||
Note that this is not the way I'd structure stuff for real (e.g. the layout blocker count should probably just move to the document), but it's enough to at least try this out. Again, no XUL document support so far.
Assignee: bzbarsky → nobody
Status: ASSIGNED → NEW
Updated•8 years ago
|
Priority: -- → P3
Reporter | ||
Comment 14•8 years ago
|
||
I was able to apply the patch and use it for my testing.
I can confirm that it does prevent painting until blocker is removed, but it doesn't seem to prevent MozAfterPaint's.
I tried to set a document without any JS except of:
===
<script type="application/javascript">
document.addLayoutStartBlocker();
setTimeout(() => {
document.removeLayoutStartBlocker();
window.docReady = 1;
}, 1000);
function logFirstPaint() {
performance.mark('moz-after-paint');
let measures = performance.getEntriesByName('moz-after-paint');
let measure = measures[measures.length - 1];
if (window.docReady) {
window.removeEventListener('MozAfterPaint', logFirstPaint, true);
console.log('Paint: ' + measure.startTime + ' (after docReady)');
} else {
console.log('Paint: ' + measure.startTime + ' (before docReady)');
}
}
window.addEventListener("MozAfterPaint", logFirstPaint, true);
</script>
===
and when I launched it in a tab (via chrome://) it returns 20 paint logs, 19 of which happen before the `docReady = 1`.
is that expected?
Comment 15•8 years ago
|
||
Probably: painting happens from the root of the document tree, so even documents with nothing to paint yet (like this one) would get painted...
Reporter | ||
Comment 16•8 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #15)
> Probably: painting happens from the root of the document tree, so even
> documents with nothing to paint yet (like this one) would get painted...
so, how can I measure when the engine starts layout/painting of the document?
I see MozAfterPaint firing before DOMContentLoaded, then between DOMContentLoaded and window.onload, and then again. How do I know which one of the three is the real painting of HTML?
The one that I have to finish any DOM modifications before if I want to prevent FOUC?
Flags: needinfo?(bzbarsky)
Comment 17•8 years ago
|
||
> so, how can I measure when the engine starts layout/painting of the document?
I don't know offhand.
> How do I know which one of the three is the real painting of HTML?
They all could be, depending on what the DOM and layout trees look like...
> The one that I have to finish any DOM modifications before if I want to prevent FOUC?
FOUC will happen if a paint happens before your modifications are done _and_ layout is being done on whatever is already there, no? The whole point of blocking layout is to prevent that second condition from being true.
Flags: needinfo?(bzbarsky)
Reporter | ||
Comment 18•8 years ago
|
||
> FOUC will happen if a paint happens before your modifications are done _and_ layout is being done on whatever is already there, no? The whole point of blocking layout is to prevent that second condition from being true.
I thought that blocking layout will prevent paints so I was trying to check if your patch impacts the first paint time to be after l20n is done (so, DOM is ready).
If blocking layout doesn't prevent paints, then how can we test the impact of our changes on the performance?
The ts_paint tests the painting, and if painting is done irrelevant of layout, then we can block layout for a second and the paint won't be affected, am I correct?
Flags: needinfo?(bzbarsky)
Comment 19•8 years ago
|
||
> I thought that blocking layout will prevent paints
Well, it prevents there being anything there to paint, which is not quite the same thing.
> then how can we test the impact of our changes on the performance?
I'm not sure, honestly.
> then we can block layout for a second and the paint won't be affected, am I correct?
I don't know enough about what ts_paint is measuring to answer that question, sorry.
Flags: needinfo?(bzbarsky)
Comment 20•8 years ago
|
||
Mass change dependency tree for bug 1279002 into a whiteboard keyword.
No longer blocks: gecko-l20n
Whiteboard: [gecko-l20n]
Assignee | ||
Updated•6 years ago
|
Component: DOM → DOM: Core & HTML
Updated•2 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•