Repository navigation
Conversation
Contributor
Author
|
@thePunderWoman this is a followup to #52478, which got a solid design out of the thread with Andrew K and Alex (related to #52477) but ended up stalling and got closed for staleness before it landed |
Some elements reload their resource whenever one of their attributes is set again, even to the exact same value. For example, an `<iframe src="...">` that already has its `src` set on the server will make the browser reload the same page a second time when Angular hydrates it, because hydration re-applies the element's static attributes on the client. This causes a visible flicker and an extra, unnecessary network request. The same thing happens with `<embed src="...">` and `<object data="...">`. To fix this without adding any cost to apps that don't use these elements, the server now records which of these attributes are already correctly set on an element, and includes that information in the hydration data it sends to the client. During hydration, the client uses this information to skip re-setting the attribute instead of setting it again with the same value. Apps that don't hydrate, or elements that aren't affected, go through the exact same code as before. The lookup itself lives behind the existing hydration-only element implementation (enabled via enableLocateOrCreateElementNodeImpl), not in the shared element-creation code all apps go through, so it tree- shakes out of apps that never enable hydration. It hands its result to the shared code through a small module-level flag, the same way wasLastNodeCreated already does. This continues the approach discussed in angular#52478, where re-checking attribute values at runtime on every element turned out to be too costly to justify. Serializing the information on the server once and reading it back during hydration keeps the normal, non-hydration code path completely untouched. This only covers static attributes for now. Dynamic bindings (e.g. `<iframe [src]="url">`) still get re-applied during hydration and will be addressed in a follow-up. Related to angular#52477
arturovt
force-pushed
the
fix/hydration-protected-elements
branch
from
September 22, 2026 19:22
ea72570 to
fc1b44d
Compare
Member
|
Thanks for putting this together @arturovt! Closing this as superseded by #71200, which skips Dynamic bindings (e.g. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Some elements reload their resource whenever one of their attributes is
set again, even to the exact same value. For example, an
<iframe src="...">that already has itssrcset on the server willmake the browser reload the same page a second time when Angular
hydrates it, because hydration re-applies the element's static
attributes on the client. This causes a visible flicker and an extra,
unnecessary network request. The same thing happens with
<embed src="...">and<object data="...">.To fix this without adding any cost to apps that don't use these
elements, the server now records which of these attributes are already
correctly set on an element, and includes that information in the
hydration data it sends to the client. During hydration, the client
uses this information to skip re-setting the attribute instead of
setting it again with the same value. Apps that don't hydrate, or
elements that aren't affected, go through the exact same code as
before.
The lookup itself lives behind the existing hydration-only element
implementation (enabled via enableLocateOrCreateElementNodeImpl), not
in the shared element-creation code all apps go through, so it tree-
shakes out of apps that never enable hydration. It hands its result to
the shared code through a small module-level flag, the same way
wasLastNodeCreated already does.
This continues the approach discussed in #52478, where re-checking
attribute values at runtime on every element turned out to be too
costly to justify. Serializing the information on the server once and
reading it back during hydration keeps the normal, non-hydration code
path completely untouched.
This only covers static attributes for now. Dynamic bindings (e.g.
<iframe [src]="url">) still get re-applied during hydration and willbe addressed in a follow-up.
Related to #52477