Repository navigation
Conversation
|
@arturovt as we've discussed offline, the proposed fix would not work due to potential performance issues. This extra logic should be limited to the following scenario:
There are 2 possible cases:
Those 2 cases are being handled by different code paths (static case, binding case). Static attributes are applied when an element is created/hydrated and we can handle that. The binding case is more complicated: it's invoked as a part of change detection and currently there is no information whether an underlying element was created or hydrated, so we need to store more info about it (but only for Here is a proposed solution:
The
Additional note: there might be other elements affected by the same problem, we'd like to ask if you could check the spec for elements like Please let me know if any additional information is required. |
|
Here's the list of valid and invalid cases: elements marked in red reload resources when hydrated. We don't consider cases when the cache is disabled through devtools or the remote resource returns a 302 status code.
<img src="/assets/img_girl.jpg" />
<picture>
<source media="(min-width: 650px)" srcset="/assets/img_food.jpg" />
<source media="(min-width: 465px)" srcset="/assets/img_car.jpg" />
<img src="/assets/img_girl.jpg" />
</picture>
<svg>
<image xlink:href="/assets/angular.svg" />
</svg>
<video controls autoplay>
<source src="/assets/mov_bbb.mp4" type="video/mp4" />
<source src="/assets/mov_bbb.ogg" type="video/ogg" />
</video>
<audio controls src="/assets/t-rex-roar.mp3"></audio>
<video controls src="/assets/friday.mp4">
<track default kind="captions" srclang="en" src="/assets/friday.vtt" />
</video>
<object
type="application/pdf"
data="/assets/In-CC0.pdf"
></object>
<embed type="video/webm" src="/assets/flower.mp4" />
<iframe src="https://www.youtube-nocookie.com/embed/7HVMn1TpXKQ"></iframe> |
|
@arturovt thanks for additional information, this is very helpful. We can extend the |
|
@AndrewKushnir I am interested in providing the fix; I'll need to go through your comments and start implementing it locally. I'll message you if I have any questions. |
e834d25 to
8d2cffe
Compare
ee825ad to
ada559b
Compare
|
Thanks @arturovt and @AndrewKushnir for your efforts on this. |
0dd36bf to
480bb0f
Compare
|
@arturovt thanks for implementing this 👍 I've added this PR to the v18 milestone. If you get a chance, could you please try to find corresponding sections of HTML spec that talk about this specific behavior of the |
|
@AndrewKushnir I went through the HTML standard and I may guess it doesn't explicitly mandate this behavior or provide detailed instructions on how user agents should handle this aspect of network requests. Because if we talk about I am confident that what we're doing in this PR doesn't go against the spec because we're essentially targeting that hydration case with the very first render. (Please correct me if I'm wrong...). Out of curiosity, wanna check what engines do internally... UPD: I examined the behavior of Safari's JSC for images and iframes. Each HTML element class has a hook called For iframes, In the case of images, it's more intricate and aligns with our previous discussion. if (oldValue != newValue)
selectImageSource(RelevantMutation::Yes);
else
m_imageLoader->updateFromElementIgnoringPreviousErrorToSameValue();And But you know, it's more like interesting information to keep in mind. Unfortunately, such implementation details are not included in the specification. |
eec6111 to
ec8c509
Compare
AndrewKushnir
left a comment
There was a problem hiding this comment.
@arturovt thanks for the PR, the code looks great! I've just left a few comments with some proposals.
Could you please also mark this PR as "Ready for review" via GitHub UI?
|
@AndrewKushnir made changes according to your comment. |
b4edc63 to
f98e4f7
Compare
When this ships, I will celebrate for all of you |
|
@AndrewKushnir what's left? |
|
@arturovt @rhutchison Sorry for the delay. I've added this fix to the v19 candidate list and we'll perform code review and testing as a part of v19 preparation process. |
f98e4f7 to
2d8144a
Compare
With this commit, we are now able to handle hydration-protected elements and their attributes. This enhancement is aimed at improving UX and reducing the number of HTTP requests made by browsers to external resources during the hydration process. Take, for example, the `iframe` element with a static `src` attribute, which is rendered on the server. When we begin hydrating that element on the client, it attempts to set up the static attributes again. This includes setting the `src` attribute again with the same value it already has. Browsers interpret each change to the `src` attribute as a new request to load the specified resource. Consequently, the video may flicker as the browser attempts to reload it. We now maintain a map of elements that should be protected from hydration. Each element (acting as a key) maps to a list of attributes, for instance, `iframe -> ['src']`. When we look up an existing element, we check its tag name and if there's a list of attributes associated with it. If we encounter an `iframe` (or other protected element), we iterate over its protected attributes and check whether that element already has those attributes set. If it does, we save this information in the hydration info map to use it when calling `setAttributes`.
2d8144a to
a61aa28
Compare
|
@arturovt thanks for working on this fix 👍 We've were reviewing this change today and the conclusion was that this fix would work (and I remember that I was proposing this/similar approach earlier), but it introduces quite a lot of complexity and runtime code at perf-sensitive locations, which would be very hard to manage. @alxhub proposed a different and a very interesting approach. Instead of relying on the overwritten behavior at runtime, we can serialize more info on the server and pre-populate corresponding LView slots with the necessary attribute values during hydration. In this case, a non-hydration runtime code would not require any changes - an update of an attribute would not happen with an existing runtime logic. Here are some extra details that might be helpful for this change.
The idea is that we'll have a special object in a serialized object for each
Please let me know if you need any extra info or have any questions, we'll be happy to help. Also, if you'd like, I can create an initial draft of the change and share with you (in this thread) as a diff. Let's also keep this PR open for now, we'll get back to it in case the described approach doesn't work. Thank you. |
|
@AndrewKushnir okay, I'll need to go through the functions you mentioned locally in the playground to see what data they're working with and how they're serializing the LView. |
|
Since this has been stale for so long, I'm going to close this. Feel free to open a new PR if you want to still see this land. |
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
No description provided.