Skip to content
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

does "update the rendering or user interface" mean flushing style and layout? #3246

Open
dbaron opened this issue Nov 22, 2017 · 8 comments
Open
Labels
integration Better coordination across standards needed topic: style

Comments

@dbaron
Copy link
Member

dbaron commented Nov 22, 2017

From w3c/IntersectionObserver#263 (comment) , I think the event loop section is pretty unclear about what it means by "update the rendering or user interface ... to reflect the current state". I've always assumed that bit meant to flush style and layout -- though I actually don't see where the spec even defines the concepts of flushing style and layout. But others have clearly assumed it meant the opposite.

I think this becomes important as we consider where to insert new things within the event loop:

  • To get ideal performance characteristics, things that are primarily intended to write style information and in many cases don't need to read the results of style or layout should be before the implementation does its default flush of style and layout, so that if they do write style information, but don't ever read results of style or layout calculations, then no duplicate flushes are needed; if they end up writing then they can cause style or layout recalculation an extra time for part or all of the tree. An example of this would be requestAnimationFrame.
  • Likewise, things that are intended primarily to read the results of layout and not to write anything should be after the implementation does its default flush of style and layout, so that if they do only reading and not any writing of style, we'll likewise avoid flushing layout and/or style extra times. I think an example of this is the IntersectionObserver update steps (assuming I'm understanding the spec correctly).

Together, these factors mean that describing when the implementation does its default style and layout recalculation in the steps is important for the process of inserting new items into that list in a way that produces better performance characteristics for the web.

So I think the spec needs to be clearer about how the default per-refresh-cycle flush of style and layout fits into the steps to update the rendering. This may involve specifying flushing more clearly.

There was some work (which sort of petered out) in the Houdini group to try to define some of this stuff better, and this work may have some usable material to draw from. I think the primary information on that I have is the minutes from 2015-08-29 Part III.

/cc @ojanvafai @esprehn

@dbaron
Copy link
Member Author

dbaron commented Nov 22, 2017

Also /cc @zcorpan since any attempt to specify flushing would need to integrate deeply with cssom-view.

@annevk
Copy link
Member

annevk commented Nov 22, 2017

We've basically been waiting for the CSS WG to define that concept. It's also needed to define several methods, such as innerText, but I think you're correct that "update the rendering" is supposed to be equivalent to what implementers typically refer to as "computing style" and "performing layout" (or something along those lines; the fact it's not formally defined by CSS does not help).

See also https://www.w3.org/Bugs/Public/show_bug.cgi?id=28876 for an older bug where I tried to get some clarifications.

Also, as for the specific issue of requestAnimationFrame(), that's covered by #2569 (although Chrome and Firefox reportedly agree there, so I'm not sure why Chrome engineers are confused about the meaning).

@szager-chromium
Copy link

If "update the rendering" is synonymous with "compute style and perform layout", then what does the spec have to say about javascript code that forces synchronous style/layout?

for (let i = 0; i < 1000; i++) {
myDiv.style.width = String(i) + "px";
myDiv.offsetTop;
}

Is there spec language somewhere that says that every javascript instruction may cause "update the rendering" to run synchronously? I think that's an enormous can of worms to open.

In my opinion, "compute style and perform layout" is an implementation detail that shouldn't be exposed in the spec. If you modify style and then inquire about layout, the style computation and layout updating should happen magically and synchronously. From the point of view of the spec, up-to-date layout information should be immediately available at all times.

By that interpretation, "update the rendering" in the document lifecycle would mean pushing pixels to the screen. I think that's commensurate with the way rAF and frame generation is defined in the spec.

@dbaron
Copy link
Member Author

dbaron commented Nov 22, 2017

The way all implementations actually work is that certain operations (like offsetTop's getter) can force flushing of buffered style and/or layout changes. The web depends on this buffering for performance to be acceptable. As we design new technologies, we should consider how they interact with the web's performance characteristics -- and in order to keep implementors and specification designers on the same page, the specifications ought to describe the things that give the web those performance characteristics. There are also a bunch of cases where this buffering is detectable in terms of things like event order, and web content probably depends on that ordering in some cases.

@annevk
Copy link
Member

annevk commented Nov 23, 2017

I'm pretty sure I filed an bug/issue against CSS at some point to define "compute style and perform layout" so we could reference that in certain operations, such as offsetTop's getter and innerText's getter which I mentioned above. Unfortunately that hasn't happened yet.

@szager-chromium
Copy link

@dbaron I certainly agree that the implementation you describe is the way all implementations work. I just don't think that's actually spelled out in the spec. The larger question, I think, is whether the spec ought to include that concept as a recommended best practice for implementers; or as an explicit and rigorously-defined requirement. My argument is that making it an explicit requirement would add a lot of complexity to the spec without any benefit. It's also possible that making it explicitly spec'ed could prevent some super-smart optimization down the road.

@annevk
Copy link
Member

annevk commented Nov 28, 2017

@szager-chromium to the extent that things are observable they need to be defined though. Otherwise new implementations will just have to reverse engineer existing ones.

@ojanvafai
Copy link

Sorry for the very delayed response. FWIW, I agree that we should try to get the rendering more flushed out. I've learned recently for example that Edge fires requestAnimationFrame after updating style and layout and I believe they don't have discrete style/layout phases. So, specifying this might be difficult, but I support doing so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integration Better coordination across standards needed topic: style
Development

No branches or pull requests

5 participants