-
-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Try to remove or reduce the FOUC problem #39
Comments
Relevant thread with the Shopify team who implemented, then abandoned, JS-based container queries on their admin backend: https://twitter.com/_lemonmade/status/870461985334362112 Here's what I think they implemented: https://github.com/lemonmade/container-queries I can't tell by looking at the code myself; any reason that’s FOUC-ier or less FOUC-y than cq-prollyfill? |
From reading the code I don’t see a reason for it to be FOUC-ier than cq-prolyfill. But it depends on how you load the JavaScript and when you call The big problem I see with it is synchronous layouts and layout thrashing. I looks like for every node that has a container query attached a synchronous layout is performed. This can make it really slow. cq-prolyfill is optimized to do as few synchronous layouts as possible. I wrote about how this is done in WICG/container-queries#3 (comment)
|
I thought you were looking to use requestAnimationFrame because ResizeObserver isn't really supported anywhere yet. If you're only hoping to use it so that your callback fires before first paint – why can't you use ResizeObserver? I think RO callbacks also fire before first paint. Example: https://ericportis.com/etc/ResizeObserver-runs-before-first-paint.html (PS the dirty nodes / sync layout stuff is still fuzzy in my head, need to dive into your code to really understand...) |
I didn’t know that <?php function delay() { echo str_repeat(' ', 10 * 1024); ob_flush(); flush(); sleep(1); } ?>
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script> window.cqConfig = { postcss: true }; </script>
<style> div.\:container\(width\>100px\) { color: red } </style>
<script src="https://cdn.rawgit.com/ausi/cq-prolyfill/v0.3.3/cq-prolyfill.js"></script>
</head>
<body>
<div id="div1">div1</div><?php delay(); ?>
<div id="div2">div2</div><?php delay(); ?>
<div id="div3">div3</div><?php delay(); ?>
</body> All |
This is how that process for one of those
|
So, when executed in the Questions that come to mind (which I should be able to get some time to test/try to answer myself on Monday)...
|
Ran one little test, and yeah! In the head = FoUC free! (http://ericportis.com/etc/fouc-finder/ vs http://ericportis.com/etc/fouc-finder/defer.html) But—why does the FoUC-free version take 1.5x the time to paint a fully-queried-and-styled page (3.73s vs 2.46s), and is there any way to make it faster? (http://ericportis.com/etc/fouc-finder/head.png vs http://ericportis.com/etc/fouc-finder/defer.png) |
In my tests (with 20x CPU slowdown) the difference was not that big, the sync version took about 1.8 seconds and the defer version 1.6 seconds. But still, the defer version seems to be faster. I think the reason for that is, that in the sync version the browser has to wait for the javascript to download and cannot parse the HTML and build the first layout in parallel. The best compromise might be to load it Another performance problem I saw was that cq-prolyfill gets executed 4 times: One directly when the script loads, one called by the mutation observer, one for |
I created issue #41 for the problem with multiple executions. And regarding your questions:
Sync resize is not a problem because browsers will only support ResizeObserver. Re-layout is expensive but cq-prolyfill is optimized to do as few re-layouts as possible, most of the time only one re-layout is performed, independent of the number of container query nodes. In the worst (very uncommon) case the number of re-layouts is equal to the nesting level of container query nodes, in your fouc-finder example this number would be five.
Yes, but if we implement #41 this shouldn’t be a problem because for rendering the first frame the browser waits for the CSS anyways. |
I think if the script loads fast enough and the page ist not too long it should be possible to avoid a flash of unstyled content.
We would need an event that fires directly before the first render, maybe a
requestAnimationFrame
? In the initial rendering case we should also try to run the process synchronously so that we don’t miss the first render.See also https://twitter.com/etportis/status/867023541614460928
/cc @eeeps
The text was updated successfully, but these errors were encountered: