core icon indicating copy to clipboard operation
core copied to clipboard

Safari src/srcset behavior

Open 719media opened this issue 3 years ago • 2 comments

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.

719media avatar Aug 01 '22 18:08 719media

Replicated this behavior as well for safari mobile https://github.com/vuejs/core/issues/6391#issue-1324834994

trulyprivate avatar Aug 02 '22 21:08 trulyprivate

Same as https://github.com/vuejs/core/issues/4680#issuecomment-927166733

posva avatar Aug 05 '22 10:08 posva

Just leaving a follow up note that the same problem/behavior happens in safari desktop/mobile for a template like:

<img
  :srcset="https://domain.com/image.jpg?w=200 200w, https://domain.com/image.jpg?w=100 100w"
  sizes="50px"
>

What happens is, Safari eagerly loads the srcset before the sizes attribute has been appended by vue, and so it will actually load the 200 width image and then immediately afterward load the 100 width image.

In my opinion, this behavior effectively makes using srcset broken within vue + safari. I understand this isn't really vue's fault, but bring it up again as unexpected behavior.

Also, to be clear, the easiest workaround here is to rearrange the attribute order such that sizes comes first. I'm not sure there's a guarantee here in vue about the order of a template matching the order that attributes will be appended, so this could just be a problem that crops up if some optimization or change happens inside vue-template-compiler.

Workaround:

<img
  sizes="50px"
  :srcset="https://domain.com/image.jpg?w=200 200w, https://domain.com/image.jpg?w=100 100w"
>

719media avatar Aug 16 '22 22:08 719media

I've experienced the same problem when working with Angular 15. I couldn't even imagine that the order of src and srcset attributes does matter.

Thanks for finding out what the reason is.

ahorovyi avatar Nov 15 '23 21:11 ahorovyi

Hi 719media and everyone!

The related Safari bug tracker ticket: https://bugs.webkit.org/show_bug.cgi?id=190031

Perhaps someone here can help get it fixed.

gdubicki avatar Jan 11 '24 14:01 gdubicki

That's a longshot, but maybe you could help getting the bug fixed, @jensimmons? Please see the Safari bug tracker link above.

gdubicki avatar Jan 21 '24 12:01 gdubicki