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

Review request on blocking=render attribute for scripts and stylesheets #727

Closed
1 task done
xiaochengh opened this issue Apr 5, 2022 · 11 comments
Closed
1 task done
Assignees
Labels
Resolution: satisfied with concerns The TAG is satisfied with this work overall but requires changes Topic: HTML Venue: WHATWG

Comments

@xiaochengh
Copy link

xiaochengh commented Apr 5, 2022

Braw mornin' TAG!

Edit: This feature now affects scripts and stylesheets only. The behavior on preloads have been removed due to whatwg/html#7896.

I'm requesting a TAG review of blocking=render attribute for scripts and stylesheets and link resources.

All current browsers already have a render-blocking mechanism: after a navigation, the user agent will not render any pixel to the screen before stylesheets and synchronous scripts are loaded and evaluated (or a UA-defined timeout is reached), to prevent a Flash of Unstyled Content and ensure that critical scripts are evaluated. We extend this idea by introducing the blocking=render attribute, which can explicitly mark other resources (script, style and link of types modulepreload, preload and stylesheet) as render-blocking, so that a flash of undesired contents can be prevented in more use cases (see explainer).

Further details:

  • I have reviewed the TAG's Web Platform Design Principles
  • Relevant time constraints or deadlines: April 22, 2022
  • The group where the work on this specification is currently being done: WHATWG
  • Major unresolved issues with or opposition to this specification: None
  • This work is being funded by: Google

We'd prefer the TAG provide feedback as (please delete all but the desired option):

💬 leave review feedback as a comment in this issue and @-notify xiaochengh@

@LeaVerou
Copy link
Member

How does the corresponding IDL attribute work? Would element.blocking === "render" be true for elements that are render-blocking by default?

@xiaochengh
Copy link
Author

No. element.blocking simply reflects the content attribute.

@plinss
Copy link
Member

plinss commented Apr 21, 2022

@cynthia and I took a look at this this week and we have some concerns about what user need this is actually serving?

The explainer list a uses case of wanting to block on font loading, which can already be controlled via CSS, is generally considered a bad thing to do by the CSSWG, and usually leads to a very bad user experience. The other use cases seem somewhat questionable.

This feature also goes against one of the TAG's design principles. Is there really a need to add more render blocking?

@xiaochengh
Copy link
Author

Thanks for the review! My response is as follows:

The explainer list a uses case of wanting to block on font loading, which can already be controlled via CSS

CSS font-display descriptor cannot control render-blocking. It only leaves an empty space for the text that uses the web font, and still renders other contents. Since the empty space is measured using a fallback font, its dimensions can still change when the actual web font is swapped in, causing a layout shift. There is a rich literature about this, to name a few:

The other use cases seem somewhat questionable.

I believe the other use cases are also as strong.

For the second use case (script-inserted style & script): In practice many web developers struggle to properly pre-process their blocking style sheets and scripts, which is one reason CLS is quite common. This is especially true for individual, educational or indie developers, who don't have the resources to build & maintain fancy server-side templating and serving systems. The linked educational example is one such example, which is served from raw sources without any build step, has many constituent pages, and a loader script to avoid duplication of common resources (& corresponding mistakes) across these pages. There is no advantage at all to the multi-render progressive loading for this site, it just looks jarring and ugly. blocking=render solves it elegantly.

For the third use case (async script), blocking=render provides immediate improvements to client-side A/B testing. We need to ensure that the test config script (which may, e.g., restyle certain elements) is run before rendering starts. Otherwise, the user may interact with an unconfigured page, making any subsequent measurements invalid. Current approaches either manually hide the document with JS, or do nothing and risk having invalid results. Also @alexnj to elaborate.

This feature also goes against one of the TAG's design principles.

The principle allows adding such features “only in cases when the overall user experience is improved”, which I believe is exactly the case for blocking=render. In all the use cases, blocking=render prevents a flash of unstyled content, which the principles already deemed “undesirable”.

@plinss
Copy link
Member

plinss commented Apr 26, 2022

Bumping this issue until Sangwhan is available, IIRC some of his concerns were about how this feature can be abused (either intentionally or unintentionally) causing significant delays for users on slow connections or who need to download very large resources (like CKJ fonts) that the page author may not take into consideration.

@xiaochengh
Copy link
Author

Regarding the concern:

  1. Since there are scenarios where this feature seems necessary, but also other scenarios where misusing the feature leads to a bad performance, we recommend web authors to use it with caution and only when necessary. It's also no more (or less) of a rendering footgun than putting a script or stylesheet in the head. If that resource has a problem then you have a SPOF but it's not particularly extraordinary in the risk.

  2. The risk of blocking=render might also be smaller than traditional scripts and stylesheets. Web authors can, e.g., set a timeout that removes the attribute, to manually unblock rendering if it takes too long to load. This is not achievable for traditional scripts and stylesheets.

@xiaochengh
Copy link
Author

Hi TAG,

Due to whatwg/html#7896, we have removed blocking=render on preload. As a result, now it only affects scripts and stylesheets, which is a small extension since these elements can already be implicitly render-blocking.

@xiaochengh xiaochengh changed the title Review request on blocking=render attribute for scripts, stylesheets and link resources Review request on blocking=render attribute for scripts and stylesheets May 17, 2022
@yoavweiss
Copy link

Friendly ping, as this now has a pending intent :)

@plinss
Copy link
Member

plinss commented Aug 29, 2022

We're OK with adding this to script tags as that usage can be interpreted as adding the ability to add async processing to already blocking scripts, so this is an enhancement.

However, we still have concerns about adding additional blocking to stylesheets, particularly for the purpose of blocking on font loading (and as @cynthia mentioned, CKJ fonts can be large and connections can be slow). In the past webkit blocked for up to 30 seconds on webfont loading and the user experience was horrible. CSS added mechanisms to control rendering with webfonts, adding an additional mechanism to achieve this seems bad.

@plinss plinss added the Progress: pending external feedback The TAG is waiting on response to comments/questions asked by the TAG during the review label Aug 29, 2022
@xiaochengh
Copy link
Author

Thanks for the review!

However, we still have concerns about adding additional blocking to stylesheets, particularly for the purpose of blocking on font loading

Adding this to stylesheets will not block page rendering on web font loading. It will only block on critical subresources, which is currently underdefined, but so far no implementation includes web fonts as critical subresources.

We are indeed pursuing CSS-based approaches to for rendering control with web fonts, which however should be orthogonal to this blocking=render feature.

@plinss
Copy link
Member

plinss commented Feb 20, 2023

Thanks for the response, we're going to close this review as satisfied, but we still have some concerns. Mainly, new mechanisms to block rendering need to be used very carefully by developers or they can easily fall into traps that result in a worse user experience (e.g. not realizing how slow user's devices and connections may be in the wild), so developers need to tread very carefully when using this and the additional complexity needs to be carefully explained.

Furthermore, some of the use cases seem to be replicating existing capabilities that would be better handled declaratively. For example, using script to inject links to stylesheets in certain situations should rather be handled by CSS mechanisms like feature and media queries so the UA can scan for preloading opportunities, handling is not gated by script execution, etc.

We do like the possible future extensions of being able to relax blocking in situation that are currently blocking.

@plinss plinss closed this as completed Feb 20, 2023
@plinss plinss added Resolution: satisfied with concerns The TAG is satisfied with this work overall but requires changes and removed Progress: pending external feedback The TAG is waiting on response to comments/questions asked by the TAG during the review Missing: venue labels Feb 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: satisfied with concerns The TAG is satisfied with this work overall but requires changes Topic: HTML Venue: WHATWG
Projects
None yet
Development

No branches or pull requests

7 participants