Giter Club home page Giter Club logo

Comments (10)

eeeps avatar eeeps commented on June 9, 2024 1

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 cq-prolyfill.

ausi avatar ausi commented on June 9, 2024 1

I didn’t know that MutationObserver works while the HTML document is still downloading, I thought it only observes dynamically injected nodes. Because of that, cq-prolyfill is already FOUC-free. You can test that with this example:

<?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 divs should be in red color as soon as they show up.

from cq-prolyfill.

ausi avatar ausi commented on June 9, 2024 1

This is how that process for one of those divs looks like in the browser:

timeline

  1. Receive Data
  2. Parse HTML
  3. Run Microtasks (cq-prolyfill jumps in)
    1. Recalculate Style and Layout to check if the query matches
    2. Apply the container query CSS class to the div
  4. Recalculate Style
  5. Update Layer Tree
  6. Paint
  7. Composite Layers
  8. Update Layer Tree

from cq-prolyfill.

eeeps avatar eeeps commented on June 9, 2024

Regarding requestAnimationFrame — does it matter that it happens just before layout (rather than between layout and paint, ala ResizeObserver)?

Rendering Pipeline

from cq-prolyfill.

ausi avatar ausi commented on June 9, 2024

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 ContainerQuery.create().

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)

requestAnimationFrame running before layout is not a problem I think, the important part is that is should run before the very first render/paint so that we can avoid a FOUC. Once the DOM of the page is fully loaded (domready) we can remove the requestAnimationFrame callbacks and switch to ResizeObserver.

from cq-prolyfill.

eeeps avatar eeeps commented on June 9, 2024

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
Result: https://ericportis.com/etc/ResizeObserver-runs-before-first-paint-screenshot.png
(this is a slightly-fleshed-out test of https://twitter.com/etportis/status/870673993207955457)

(PS the dirty nodes / sync layout stuff is still fuzzy in my head, need to dive into your code to really understand...)

from cq-prolyfill.

eeeps avatar eeeps commented on June 9, 2024

So, when executed in the <head>, cq-prollyfill getComputedStyles (and therefore computes layout) once (or, if a cq matches, possibly more than once) for every :container()’d node?

Questions that come to mind (which I should be able to get some time to test/try to answer myself on Monday)...

  1. Does it therefore exhibit the scary performance characteristics that browser folks have foretold, e.g. https://twitter.com/tabatkins/status/866828359308726275 ?
  2. Does this mean that DOM parsing is halted/blocked until CSS is loaded and parsed?

from cq-prolyfill.

eeeps avatar eeeps commented on June 9, 2024

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)

from cq-prolyfill.

ausi avatar ausi commented on June 9, 2024

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 async instead of defer. This would make it FOUC-free if the script is already in the cache.

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 DOMContentLoaded and one for the load event. If all these events happen at the same time it might be possible to skip some of the executions.

from cq-prolyfill.

ausi avatar ausi commented on June 9, 2024

I created issue #41 for the problem with multiple executions.

And regarding your questions:

Does it therefore exhibit the scary performance characteristics that browser folks have foretold, e.g. https://twitter.com/tabatkins/status/866828359308726275 ?

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.

Does this mean that DOM parsing is halted/blocked until CSS is loaded and parsed?

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.

from cq-prolyfill.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.