Hello, forst of all thank you for your work, this library is really good :)
I have a question, I'd need to implement lazy loading on an img tag with srcset. I studied the library a little and it seems to me that srcset is not supported, am i right or am i missing anything?
If it is, can you provide an example with different resolution images ? (1x, 2x etc...)
Thank you very much for your help.
G.
Hi,
This library does unfortunately not support srcset, but it should support it. It is a quite important feature.
With that being said, it is not super easy to support since we need to parse and understand the srcset in the same way the browser does it.
We treat srcset as a special case and do not try to load the image in the background but instead we just set the srcset
when the image is the viewport:
Let's say we have the following html tag:
<img [defaultImage]="defaultImage" lazyLoad="small.jpg 300w, large.jpg 500w">
When the image is in viewport we take a look at srcset
and detects that lazyLoad
contains a srcset
-string and just transform the tag to:
<img srcset="small.jpg 300w, large.jpg 500w">
Pro:
Simple implementation
Con:
The user will never see "defaultImage".
We can never handle network error while loading the image.
We parse the srcset
and pick the best option (like we think that the browser should have done).
Let's say we have the following html tag:
<img [defaultImage]="defaultImage" lazyLoad="small.jpg 300w, large.jpg 500w">
We detect that lazyLoad
contains a srcset
and we parse the string to something like:
[ { url: 'small.jpg', width: 300 }, { url: 'large.jpg', width: 500 } ]
We compare it to the browser width (and device pixel ratio) and pick the best image. Loads the image in the background and when it is loaded we just set srcset
and since the image is in the cache, it will be loaded immediate.
Pro:
The image will be lazyloaded 🎉
The user will see the default image.
We can handle network errors (should we try to load some other image from the srcset
or should we just load the error image?).
Con:
It is always tricky to parse a string in the same way the browser should have done it; we will probably miss some edge use case.
From my understanding, the browser will always use the largest image if it is stored in the cache. Since we have no way of knowing if the image has been already loaded we have to load the best-fitted image (but the largest image will be shown after we set srcset
). e.g. let's say we have the following srcset small.jpg 300w, large.jpg 500w
and the screen is less than 500 px but large.jpg
is already loaded. From my understanding, the browser should have picketed large.jpg
since it is in the cache but since we don't know that we will load small.jpg
and when it is loaded we will set srcset
and the browser will pick large.jpg
(I can however be wrong). i.e. we unnecessarily loaded an image.
I think option 2 is doable (should not be too hard) and I think we should do it. My time is however quite limited right now but I happily accept a PR :)
Hello @tjoskar, thanks for the quick reply, i agree with you that the second option could be feasable. I also do not have too much time right now since i'm under some deadlines but as soon as I've got more time I would like to contribute to this feature, expecially considering that I already extended the behaviour of the library to support lazy loading for the image tag with hlink.href property :)
Or ignore the default browser srcset option and implement it as your own decision making process and tune it with time to make it as best as possible :)
You only have to adhere to the spec and i believe the spec is quite straightforward.
But as you pointed out browser implementation can break what you want to achieve here, so i believe it should be bypassed.
I've submitted a pull request (#231) that adds the responsive image support to both \ I'm awaiting any input.
This is included in 3.4.0
. Thanks @sapierens