Skip to content
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

src attribute of img inside picture should be set after img is appended to picture to avoid unnecessary requests #11357

Open
CaseJnr opened this issue Apr 28, 2020 · 8 comments

Comments

@CaseJnr
Copy link

CaseJnr commented Apr 28, 2020

Version

2.6.11

Reproduction link

https://codepen.io/CaseJnr/pen/VwvWbPE

Steps to reproduce

  1. Open the codepen link in safari

  2. Inspect the element

  3. Reduce the view width below 900px and refresh the page

  4. You will notice that both the red and blue image is requested.

  5. Comment out the vue instance and refresh the page.

  6. You will notice only the red image is requested (as expected).

What is expected?

Only the required picture resource is requested.

What is actually happening?

Both of the pictures resources are requested, causing redundant downloads.


In Safari, adding a vue instance to any page will cause redundant picture sources to be requested. The picture element will behave correctly if the vue instance is removed.

E.g.

<picture>
<source media="(max-width: 900px)" srcset="small.jpg">
<img src="large.jpg" alt="">
</picture>

By default, only the small.jpg should be requested when the view width is below 900px. However, if a vue instance is added to the page, then both the small.jpg and large.jpg are requested.

The mobile inspector shows the small.jpg request initiator as the page (expected). The large.jpg initiator is actually the vue instance.

@posva
Copy link
Member

posva commented Apr 29, 2020

It seems to happen with vanilla JS:

if(document.getElementById("app")) {
  // new Vue({ el: '#app'});
}

let picture = document.createElement('picture')
let s1 = document.createElement('source')
s1.media = '(max-width: 900px)'
s1.srcset = "https://www.abc.net.au/radionational/image/6289622-4x3-340x255.png"

let s2 = document.createElement('img')
s2.src = "https://www.solidbackgrounds.com/images/2560x1440/2560x1440-brandeis-blue-solid-color-background.jpg"
s2.alt =''

picture.appendChild(s1)
picture.appendChild(s2)

window.app.innerHTML = 'new'
window.app.appendChild(picture)

Could you open a bug report at https://bugs.webkit.org please?

@posva posva closed this as completed Apr 29, 2020
@CaseJnr
Copy link
Author

CaseJnr commented Apr 30, 2020

@posva The issue is how vue is constructing the picture. Creating an img element and setting the src will initiate a request, as expected. To eliminate the redundant img request, the img element must first be added to a picture element before the img.src is set.

The following code eliminates the redundant img.src request for views with a width less than 900px

let picture = document.createElement('picture')
let source = document.createElement('source')
source.media = '(max-width: 900px)'
source.srcset = "https://www.abc.net.au/radionational/image/6289622-4x3-340x255.png"

let img = document.createElement('img')
img.alt =''

picture.appendChild(source)
picture.appendChild(img) // Append img to picture before setting the src
 
img.src = "https://www.solidbackgrounds.com/images/2560x1440/2560x1440-brandeis-blue-solid-color-background.jpg"

window.app.appendChild(picture)

@posva posva changed the title Vue breaks picture element src attribute of img inside picture should be set after img is appended to picture to avoid unnecessary requests Apr 30, 2020
@posva
Copy link
Member

posva commented Apr 30, 2020

Good to know the order here matters. Did you find the section on the HTML spec defining this behavior? It's still surprising that Chrome handles it but Safari doesn't

@posva posva reopened this Apr 30, 2020
@CaseJnr
Copy link
Author

CaseJnr commented May 4, 2020

@posva Any chance you could recommend a fix for this while I wait for a PR?

@czf1998

This comment has been minimized.

@gnuletik
Copy link

gnuletik commented Jun 1, 2021

I'm currently facing the same issue with vue v3.0.11 and Safari v14.1.1.
Not sure if I should open an issue on https://github.com/vuejs/vue-next.

@gnuletik
Copy link

gnuletik commented Jun 1, 2021

Maybe linked to https://bugs.webkit.org/show_bug.cgi?id=190031

@marcorieser
Copy link

I'm currently facing the same issue with vue 3.2.20 and Chrome 4.0.4606.81

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants