Closed Bug 1441044 Opened 6 years ago Closed 4 years ago

<img> inside <template> is loaded automatically

Categories

(Core :: DOM: Core & HTML, defect, P3)

58 Branch
defect

Tracking

()

RESOLVED DUPLICATE of bug 1669664

People

(Reporter: oom, Assigned: hsivonen)

Details

(Keywords: parity-chrome, parity-safari)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:58.0) Gecko/20100101 Firefox/58.0
Build ID: 20180206200532

Steps to reproduce:

I have a <template> element containing an image with a srcset value.


Actual results:

Navigate to the page, the image in the srcset value is preloaded automatically by the browser, before insert the template content in the dom.


Expected results:

Because the content of a <template> should not be handled unless it is inserted in the doom, the image should not be loaded (as Chrome does).

I've created a demo here: https://codepen.io/oscarotero/pen/PQyZEJ, where you can see in the Network panel that the image https://res.cloudinary.com/css-tricks/image/upload/c_scale,w_1000,f_auto,q_auto/v1519081600/press_gedv7u.png is loaded without need to insert the element in the dom. This does not happens with the src attribute, only with srcset.
Component: Untriaged → DOM
Product: Firefox → Core
Summary: <img> with srcset values inside <template> are loaded automatically → <img> inside <template> is loaded automatically
After a quick test, this bug affects to all images, not only srcset attributes.
Confirmed in 61.0a1 (2018-03-27) (64-bit). Tested also in Safari and Chrome, and indeed they do not load the image.
Andrew, anyone handling images loading code these days?
Flags: needinfo?(overholt)
Priority: -- → P3
(In reply to Marcos Caceres [:marcosc] from comment #3)
> Andrew, anyone handling images loading code these days?

Not really, now. Maybe Andrew Osmond knows?
Flags: needinfo?(overholt) → needinfo?(aosmond)
I'll take a look (unless tnikkel manages first!).
The load is coming from nsIDocument::MaybePreLoadImage, which is called by the parser whenever it encounters an <img> tag.

Is preloading of images covered by any spec?

I think if we wanted to avoid this we would need to teach the parser to recognize this.

Is there a reason why don't want a preload to happen in this case?
(In reply to Timothy Nikkel (:tnikkel) from comment #6)
> The load is coming from nsIDocument::MaybePreLoadImage, which is called by
> the parser whenever it encounters an <img> tag.
> 
> Is preloading of images covered by any spec?

Anne and I checked in HTML... and it was not exactly clear. However, things in <template> are supposed to be inert. 

> I think if we wanted to avoid this we would need to teach the parser to
> recognize this.

Yeah, it should probably check if the image is participating in template. 

> Is there a reason why don't want a preload to happen in this case?

Well, the developer might have the template ready, but it might be the case that the template doesn't need to get used on the page (hence wasted bytes downloading the image unnecessarily).
Ok, clarified that it's indeed a bug on our side (not a spec bug). Seems we need to check if the node is connected to the active  document, which it would not be if it's participating in a template.
The spec only talks about loading of images. This is preloading which is just making a network request, it isn't associated with the img element.
(In reply to Timothy Nikkel (:tnikkel) from comment #10)
> The spec only talks about loading of images. This is preloading which is
> just making a network request, it isn't associated with the img element.

I'm unsure if speculative preloading should occur on something that's might not end up in the document (being in a <template> and all)? If the developer wants to preload the image, they can explicitly do: `<link rel="preload" href="some.png" as="image">`. 

Maybe I'm missing something?
Flags: needinfo?(aosmond)
I feel like Henri would have salient thoughts here.
Flags: needinfo?(hsivonen)
(In reply to Marcos Caceres [:marcosc] from comment #11)
> (In reply to Timothy Nikkel (:tnikkel) from comment #10)
> > The spec only talks about loading of images. This is preloading which is
> > just making a network request, it isn't associated with the img element.
> 
> I'm unsure if speculative preloading should occur on something that's might
> not end up in the document (being in a <template> and all)?

How common is it to have a template and not instantiate it?

> If the developer
> wants to preload the image, they can explicitly do: `<link rel="preload"
> href="some.png" as="image">`. 
> 
> Maybe I'm missing something?

Speculatively loading images isn't about what the developer wants but about making things fast for users most of the time. That is, it preloads images even when the developer doesn't ask for it.

There have been previous complaints about this position e.g. when Web devs were trying to polyfill an early draft of <picture>. Still, on the Web scale, there are many more sites where the Web developer doesn't hand-tune image loading behavior, so I've considered the speculative loading a net benefit to users even if it sometimes counteracts what some Web devs are trying to do.

In that light, should we assume having templates that aren't going to be instantiated to be common enough that it would be a net benefit not to speculatively load images in templates?
Flags: needinfo?(hsivonen)
(In reply to Henri Sivonen (:hsivonen) from comment #13)
> 
> In that light, should we assume having templates that aren't going to be
> instantiated to be common enough that it would be a net benefit not to
> speculatively load images in templates?

Do we need telemetry to make this decision?
Flags: needinfo?(hsivonen)
I don't know if this will be a common use case, but I use templates (in combination with intersection observer) precisely to lazy load content (images, iframes, etc) while scrolling, so if the browser loads all these images before show anything, that makes no sense.

Note also that the content of a template can be manipulated (using slots or DOM Api) before being inserted in the page, so I consider it a non reliable html content to be preloaded. It can contains invalid images src attributes that will be updated with the real data before render.
(In reply to Andrew Overholt [:overholt] from comment #14)
> (In reply to Henri Sivonen (:hsivonen) from comment #13) 
> Do we need telemetry to make this decision?

Yes, but I don't know how tricky it will be to actually understand developer intent and if we can make a probe sophisticated enough to determine if the template was used... maybe we can, I don't know much about probes. It will be challenging without actually being able to look at real code and real usage.   

(In reply to oom from comment #15)
> I don't know if this will be a common use case, but I use templates (in
> combination with intersection observer) precisely to lazy load content
> (images, iframes, etc) while scrolling, so if the browser loads all these
> images before show anything, that makes no sense.

☝️ yeah, this. In combination with `preload` where needed. 

> Note also that the content of a template can be manipulated (using slots or
> DOM Api) before being inserted in the page, so I consider it a non reliable
> html content to be preloaded. It can contains invalid images src attributes
> that will be updated with the real data before render.

This too. 

(In reply to Henri Sivonen (:hsivonen) from comment #13)
> Speculatively loading images isn't about what the developer wants but about
> making things fast for users most of the time. That is, it preloads images
> even when the developer doesn't ask for it.

That holds for `picture`, `img` but I respectfully disagree for things inside templates. 

> There have been previous complaints about this position e.g. when Web devs
> were trying to polyfill an early draft of <picture>. Still, on the Web
> scale, there are many more sites where the Web developer doesn't hand-tune
> image loading behavior, so I've considered the speculative loading a net
> benefit to users even if it sometimes counteracts what some Web devs are
> trying to do.
> 
> In that light, should we assume having templates that aren't going to be
> instantiated to be common enough that it would be a net benefit not to
> speculatively load images in templates?

I guess we would need to gather data - but I personally think :oom's use case, as well the many features we have in the platform now for controlling preloading, and having both the HTML spec and other browsers not doing the preloading of images inside templates, need to be weighted here. As a web developer, I'd be personally surprised if preloading of template things occurred.
(In reply to Marcos Caceres [:marcosc] from comment #16)
> I guess we would need to gather data - but I personally think :oom's use
> case, as well the many features we have in the platform now for controlling
> preloading, and having both the HTML spec and other browsers not doing the
> preloading of images inside templates, need to be weighted here.

We've had industry-leading speculative loading for 7 years. By this logic, we should make it worse to match Chrome.

(I understand that rel=preload has use cases that our speculative loader doesn't address, but we shouldn't think that rel=preload is all awesome. Part of it is filling gaps in browsers with less capable speculative loaders than ours.)

(In reply to oom from comment #15)
> Note also that the content of a template can be manipulated (using slots or
> DOM Api) before being inserted in the page, so I consider it a non reliable
> html content to be preloaded. It can contains invalid images src attributes
> that will be updated with the real data before render.

This is a convincing point, though. I'll write a patch.
Assignee: nobody → hsivonen
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Flags: needinfo?(hsivonen)
Component: DOM → DOM: Core & HTML

Duplicating forward to a bug that has a patch.

Status: ASSIGNED → RESOLVED
Closed: 4 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.