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

QImg loads twice when source changes #7053

Closed
razorness opened this issue May 15, 2020 · 11 comments
Closed

QImg loads twice when source changes #7053

razorness opened this issue May 15, 2020 · 11 comments
Assignees

Comments

@razorness
Copy link

Describe the bug
QImg is loading the given source twice when source changes.

Codepen/jsFiddle/Codesandbox (required)
https://quasar.dev/vue-components/img#Example--Basic

To Reproduce

  • Open DevTools
  • Click on change image
  • Look how every image get's loaded twice

Expected behavior

  • Load it once.

Platform (please complete the following information):
OS: Windows 10 1909
Browsers: Edge Chromium v81.0.416.72, Google Chrome v81.0.4044.138

@pdanpdan
Copy link
Collaborator

pdanpdan commented May 15, 2020

It doesn't do anything like this - please check your browser extensions.
I have checked in Chrome, Edge and Firefox on windows and none of them show the reported problem.

@razorness
Copy link
Author

Okay ... tested with fresh browser without any extensions installed. It depends on cache mode in DevTools. If you deactive cache, you get this behavior. So, I guess, this is no real bug.
Sorry for quick shot!

@Nexulo
Copy link

Nexulo commented Aug 19, 2020

Excuse me, but I think there's already a problem.

The images are loaded twice or more in Safari. I can also see this behaviour on the iPhone in Safari and as far as i know, there is no option on iOS to disable the cache or something like that.

I am pretty sure changing src triggers multiple times. Even if cache is disabled, Vue/Quasar should not load the image multiple times.

@pdanpdan
Copy link
Collaborator

@maisen20 cab you provide a screenshot from the dev tools, network tab? All the calls except the first should be already cached.

@Nexulo
Copy link

Nexulo commented Aug 19, 2020

Bildschirmfoto 2020-08-19 um 21 18 41

I did some tests and made some outputs directly in the QImg component of Quasar.

It's really weird. The QImg component really seems to load each image only once. However, I see in the console under network that the image is loaded twice.

@Nexulo
Copy link

Nexulo commented Aug 19, 2020

Bildschirmfoto 2020-08-19 um 22 31 17

Bildschirmfoto 2020-08-19 um 22 33 17

Here some more Infos.

It seems that the initiator by "vue.runtime.esm.js" is the second, unnecessary initiator.

@Nexulo
Copy link

Nexulo commented Aug 19, 2020

Pretty sure the problem comes from the file "vue.runtime.esm.js".

I don't know exactly what this file and all its functions are needed for, but I found the one where the problem originated.

The QImg components are included by QImg.js as div tags in the document, then all style properties of the component are run through by vue.runtime.esm.js - And that's where the "problem" seems to be.
The runtime-script changes/sets the properties, so "background-image" will be set new, too.

The Safari browser will probably reload the (already loaded) background image.

Can this be?

Does anyone have an idea what I can do?

@Nexulo
Copy link

Nexulo commented Aug 20, 2020

Sorry for all the posts, but this behaviour in the Safari browser can also be observed directly on https://quasar.dev/vue-components/img#Example--Basic When I click on the trigger button in the "Transitions" section of this website, I see in the Firefox console under "Network" that the next image is loaded once. If I now do the same steps in the Safari browser, I see that the image is always loaded twice. And i didn't disabled ressource caching.

@Nexulo
Copy link

Nexulo commented Sep 2, 2020

Any news about this issue?

@eyedean
Copy link

eyedean commented Feb 2, 2021

I ran into this.

Screenshot at Feb 02 11-27-51

I tested various scenarios (e.g. <q-img> vs <img> on different positions, classes, image types, etc.) and I think I found the root cause of the problem @maisen20 @pdanpdan @rstoenescu.

Why is this happening?

The way q-img works is it first loads the image as a new Image() Javascript object (QImg.js#L155-L192), then it most cases it creates a <div> and sets the CSS style of that div to have backgroundImage: url(<imageSrcHere>) as per QImg.js#L87.

Chrome actually detects this as two different requests for the image (one for <img> and one for <div>) and that's why you see two requests. One might call it a bug in Chrome DevTool as per this comment, that is not fixed yet (February 2021). But it is what it is.

PS. It doesn't happen very consistently. I have seen this simply not happening on svg/png files at all (I guess due to the way they are loaded/fed to the browser.) Also I have seen this happening only for one of the images when there are multiple <q-img> elements (with different sources) in a row.

What can you do about it?

Good News: It's not as bad as it sounds!

You will only see this in Chrome DevTools when you have "Disable Cache" on! In production, it loads the second time from the cache. (also noted here: tuupola/lazyload#158 (comment))

Solution 1) Do nothing!

It will keep bothering you if you have "Disable Cache" checked (which most developers do!) But, in production reality to the users, it will be cached the second time by the browser just like a lot of other things during a re-render.

Solution 2) Use <img>

If you are still skeptical about it, use <img> when you don't need any <q-img> feature like sizes, transitions, captions, etc.

Solution 3) Add native-context-menu to <q-img :src="foo" native-context-menu> (as of quasar 1.8.4)

I think it worth adding to the doc for https://quasar.dev/vue-components/img#Native-context-menu that it will cause the image to be rendered as an actual <img> tag as well (See QImg.js#L227-L234).

Screenshot at Feb 02 11-53-04

Now, the interesting thing is, apparently when Chrome sees both the <div style="... background-image: URL(<imageSrcHere)> and the <img src="<imageSrcHere>"> within, it doesn't freak out to load it twice. :)

PS. In this solution, if you use a dynamic path, Vue RunTime is actually still double calling here as it finds out src attribute of the <img> element is changed. :-/

Hope it helps! :)

@rstoenescu
Copy link
Member

Please upgrade to Quasar v2 which has a completely different approach (way more efficient). This is due to the fact that we don't have to support IE11 anymore.

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