Description
What problem does this feature solve?
Safari on iOS and macOS (other browsers not sure?) render an <img>
tag src
attribute initially before calculating an <img>
tag srcset
attribute. This basically means the following 2 javascript examples behave differently:
// example 1, srcset first
const newImage = new Image();
newImage.srcset = 'https://domain.com/image.jpg?w=200 200w';
newImage.src = 'https://domain.com/image.jpg';
document.body.appendChild(newImage);
// example 2, src first
const newImage = new Image();
newImage.src = 'https://domain.com/image.jpg';
newImage.srcset = 'https://domain.com/image.jpg?w=200 200w';
document.body.appendChild(newImage);
Safari will send 1 network request for for the srcset
URL for example 1, but 2 network requests for both the src
and srcset
URLs for example 2. I believe most people would not expect example 2 behavior.
This behavior occurs in Vue templates because of how the template compiles down to javascript. So writing:
<img
:src="someSrc"
:srcset="someSrcset"
>
which compiles down to something like (pseudocode) in vue:
...
("img",{src:someSrc, srcset:someSrcset})
...
will experience double network requests in Safari.
I wonder if vue could optimize the template generation to append the srcset attribute first when constructing an image tag? I know there's some funny business around object property order and simply rearranging src and srcset in the object above might have some caveats... so this request, although simple, may have some unappreciated complexities. I at least wanted to start the conversation around what I think is a seemingly trivial and common example for anyone using srcset
, and how Safari behaves. Simply put, a common practice could be resulting in basically double (or more!) bandwidth usage, let alone degrading the render time based on image loading priority.
What does the proposed API look like?
If this is something that makes sense to address, there would be no changes to the developer-facing side. I imagine it would just be an edge case hardcode in vue template compiler for inserting srcset before src potentially?
Totally understand if this isn't "vue's" problem to solve, just logging something I found unexpected. I really think this change would immediately impact performance significantly for anyone using srcset
.