-
Notifications
You must be signed in to change notification settings - Fork 50
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
Update document-render-blocking.md to include more options #214
Conversation
- Lower CLS: A stable layout of the DOM depends on both parsing the requisite DOM nodes and fetching relevant stylesheets. Without control over parsing, its likely that the browser does multiple renders with layout shifts as more of the DOM is parsed. | ||
Authors will sometimes use `display: none` or `opacity: 0` to hide the whole Document to prevent this. | ||
|
||
- Atomic rendering of semantic elements: A UI widget built using a DOM sub-tree might not make sense to render partially. Consider a menu where only half the buttons show up on first render. Authors could mark sections in the Document which semantically render one widget so the browser doesn't yield midway through parsing one widget. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like a parser may have some context here already, like try not yielding between siblings, or something like, but yeah your point that developers may want to control this makes sense
|
||
- Atomic rendering of semantic elements: A UI widget built using a DOM sub-tree might not make sense to render partially. Consider a menu where only half the buttons show up on first render. Authors could mark sections in the Document which semantically render one widget so the browser doesn't yield midway through parsing one widget. | ||
|
||
- Optimal Yielding: The browser may yield later than was necessary leading to rendering more what's required for above the fold content. A developer hint about a yielding trigger could imply the first frame has less DOM to parse, style, and layout. Browsers can optimize paint to be limited to onscreen content but the prior stages are executed over the entire DOM. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I'm parsing the second and third sentences well.
Do you mean to say that a developer can provide a better hint resulting in less of the DOM tree to parse, style, and layout?
And also, "prior stages" you mean style & layout?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean to say that a developer can provide a better hint resulting in less of the DOM tree to parse, style, and layout?
Yeah, less to parse, style and layout for first frame resulting in better FCP.
And also, "prior stages" you mean style & layout?
Yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Maybe rephrase somehow <_<
document-render-blocking.md
Outdated
|
||
## Meta Tag with Blocking ElementIds | ||
|
||
Add a new meta tag with the name `blocking-elements` and `content` attribute set to the list of [element IDs](https://dom.spec.whatwg.org/#concept-id) which must be parsed before rendering. `*` is a special keyword which implies every ID should be blocking. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this limited to parsing the shallow element, or does this include subresources? I'm thinking specifically if I have an img here, what are we blocked on exactly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its the shallow element, not subresources.
document-render-blocking.md
Outdated
|
||
Add a new meta tag with the name `blocking-elements` and `content` attribute set to the list of [element IDs](https://dom.spec.whatwg.org/#concept-id) which must be parsed before rendering. `*` is a special keyword which implies every ID should be blocking. | ||
|
||
Each Document has a render-blocking-until-parsed element ids set, initially empty. A Document is [render-blocked](https://html.spec.whatwg.org/#render-blocked) if this set is non-empty. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or *
? If it's a set of ids, and I have no ids, then maybe we need a special carve out for *
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried doing that, lmk if I missed anything.
document-render-blocking.md
Outdated
|
||
- Each time an element's ID value changes, the browser checks if the set of elements which have been completely parsed (i.e. the end tag has been parsed) include all IDs in the render-blocking-until-parsed element ids set. If yes, the render-blocking-until-parsed element ids set is cleared. | ||
|
||
The pro of this approach is that its easier to block on a specific set of elements, which makes it more likely that authors will consider partial blocking. The con is new syntax which requires defining subtle interactions (like script changing element IDs after parsing). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be nice to write a simple js library that has some ergonomic functions like "didParse(foo)" that does all of this.
The problem with removing one element from a list of comma separated values is that you need to parse the list, find the value, remove it, and join the list back up, and set it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with removing one element from a list of comma separated values is that you need to parse the list, find the value, remove it, and join the list back up, and set it
I didn't follow the use-case you're worried about. Ideally authors will set the list once (in ) and won't change it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, the list wouldn't be changed, it's the UA that tracks it
|
||
The pro of this approach is that its easier to block on a specific set of elements, which makes it more likely that authors will consider partial blocking. The con is new syntax which requires defining subtle interactions (like script changing element IDs after parsing). | ||
|
||
### Including Blocking Tokens |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also note that a typo in this list would cause the parser to block on the whole document (waiting for the non-existent id), but in that case we can throw an error to the console
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Co-authored-by: vmpstr <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
|
||
- Atomic rendering of semantic elements: A UI widget built using a DOM sub-tree might not make sense to render partially. Consider a menu where only half the buttons show up on first render. Authors could mark sections in the Document which semantically render one widget so the browser doesn't yield midway through parsing one widget. | ||
|
||
- Optimal Yielding: The browser may yield later than was necessary leading to rendering more what's required for above the fold content. A developer hint about a yielding trigger could imply the first frame has less DOM to parse, style, and layout. Browsers can optimize paint to be limited to onscreen content but the prior stages are executed over the entire DOM. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Maybe rephrase somehow <_<
|
||
The above requires the new Document to know about the old Document's visual state when the transition started. This can't be done trivially today. The Navigation API provides the list of [entries](https://developer.mozilla.org/en-US/docs/Web/API/Navigation/entries) and the [current entry](https://developer.mozilla.org/en-US/docs/Web/API/Navigation/currentEntry) but there is no notion of a "previous entry" before the current entry was committed. | ||
|
||
[html/256](https://github.com/WICG/navigation-api/issues/256) addresses this. The examples in this proposal rely on the API proposed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would that solve the scroll state? Is that somehow accessible on the entry itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that somehow accessible on the entry itself?
No, this will have to be manual. Authors can use IntersectionObserver to track whether an element is visible and cache that information on the Document's NavigationHistoryEntry
via state
in updateCurrentEntry
.
This proposal is need to look up the previous Document's NavigationHistoryEntry. You can then query the information above which was cached by the old Document using getState
.
No description provided.