Universal lazy loading library leveraging native browser APIs. It's intended to be used with the loading="lazy"
attribute alongside (blurry) placeholder images and with a BlurHash or ThumbHash string.
- ๐ Native: Utilizes the
loading="lazy"
attribute - ๐๏ธ Framework-agnostic: Works with any framework or no framework at all
- ๐ BlurHash & ThumbHash support: SSR & client-side BlurHash and ThumbHash decoding
- ๐ช Sizing: Automatically calculates the
sizes
attribute - ๐ SEO-friendly: Detects search engine bots and preloads all images
- ๐
<picture>
: Supports multiple image tags - ๐ Auto-initialize: Usable without a build step
# pnpm
pnpm add -D unlazy
# npm
npm i -D unlazy
To apply lazy loading to all images with the loading="lazy"
attribute, import the lazyLoad
function and call it without any arguments:
import { lazyLoad } from 'unlazy'
// Apply lazy loading for all images by the selector `img[loading="lazy"]`
lazyLoad()
You can target specific images by passing a CSS selector, a DOM element, a list of DOM elements, or an array of DOM elements to lazy-load to lazyLoad
.
- Clone this repository
- Enable Corepack using
corepack enable
- Install dependencies using
pnpm install
- Run
pnpm run dev:prepare
- Start development server using
pnpm run dev
inside the one of thepackages
directories
MIT License ยฉ 2023-PRESENT Johann Schopplich
unlazy's People
Forkers
gearsdigital eric-hc jjjuulliiaann felixranesberger hazizkhan codesharpdev hacknug aloky danielroe chrispreislerunlazy's Issues
Don't include hashing algorithms, if not necessary
Describe the bug
When importing unlazy using import { lazyLoad } from 'unlazy'
, the Thumbhash and Blurhash algorithms for decoding the hash to a valid data uri are always included.
This may not always be necessary, since we can also create a valid data uri on the serverside.
Nuxt integration with picture tag
Describe the feature
Thanks for this great plugin!
I think it would be a great addition to be able to use the Nuxt UnLazyImage component together with a picture tag and multiple sources.
I tried it with the following code snippet, but Chrome devtools shows that both the PNG as well as the webp version is loaded:
<picture>
<source
type="image/webp"
:data-srcset="imageSrcSetWebP"
data-sizes="auto"
/>
<UnLazyImage
:blurhash="blurhash"
:data-srcset="imageSrcSetPNG"
width="640"
height="320"
auto-sizes
/>
</picture>
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
Transition
Describe the feature
Will it be possible to add transitions in a future update?
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
Transition for Blurhash to Image
Describe the feature
Add transition like
:transition="200"
200ms transition
example https://docs.expo.dev/versions/latest/sdk/image/#transition
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
[nuxt] document is not defined
Reproduction
Repo: https://github.com/ArthurSegato/portfolio-frontend
Node v20.5.0
PNPM 8.7.4
Nuxt 3.7.2
Nitro 2.6.3
Unlazy 0.10.1
Describe the bug
I have a dynamic project page on my frontend that is accessible via the index page, the project page consumes images from my backend (served statically) and project data (consumed via a REST request), when accessing the project page via the home page, no error occurs, but when refreshing the page the following error appears
500
document is not defined
at Module.lazyLoad (/C:/Users/segato/Documents/Github/portfolio-frontend/node_modules/.pnpm/@unlazy+core@0.10.1/node_modules/@unlazy/core/dist/index.mjs:14:23)
at setup (C:\Users\segato\Documents\Github\portfolio-frontend\pages\projects\[id].js:19:27)
at _sfc_main.setup (C:\Users\segato\Documents\Github\portfolio-frontend\pages\projects\[id].js:248:23)
at callWithErrorHandling (C:\Users\segato\Documents\Github\portfolio-frontend\node_modules\.pnpm\@vue+runtime-core@3.3.4\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:156:18)
at setupStatefulComponent (C:\Users\segato\Documents\Github\portfolio-frontend\node_modules\.pnpm\@vue+runtime-core@3.3.4\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:7190:25)
at setupComponent (C:\Users\segato\Documents\Github\portfolio-frontend\node_modules\.pnpm\@vue+runtime-core@3.3.4\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:7151:36)
at renderComponentVNode (C:\Users\segato\Documents\Github\portfolio-frontend\node_modules\.pnpm\@vue+server-renderer@3.3.4_vue@3.3.4\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:614:15)
at renderVNode (C:\Users\segato\Documents\Github\portfolio-frontend\node_modules\.pnpm\@vue+server-renderer@3.3.4_vue@3.3.4\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:743:14)
at renderComponentSubTree (C:\Users\segato\Documents\Github\portfolio-frontend\node_modules\.pnpm\@vue+server-renderer@3.3.4_vue@3.3.4\node_modules\@vue\server-renderer
Additional context
The error only appears when the 'lazyLoad()' function is added to the code
Logs
No response
Allow optional non-native lazy loading with intersection observer
Describe the feature
First of all, thanks for the great tool!
I want to migrate a website I built with loadeer to unlazy, mainly because of the inbuilt support for thumb-hash. Unfortunately Chrome's native lazy loading is way too eager for my usecase. I Have a website with a lot! of accordions stacked on top of each other, each accordion content is display: none
. But nevertheless Chrome loads the images inside the closed accordions, and worse, because the closed accordions don't take up much vertical space Chrome loads nearly all of the hundreds of images on the initial page load.
I guess I have quite a niche setup, but it might be also helpful in other unusual/complicated setups to have the option of using an intersection observer based solution for the lazy loading part. What do you think?
I guess I could also built my own intersection observer and manually load the images with loadImage
.
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
Svelte 4 support
Describe the feature
npm ERR! Found: [email protected]
npm ERR! peer svelte@"^3.54.0" from @unlazy/[email protected]
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
Uncaught RangeError: Maximum call stack size exceeded
Feature request (Nuxt): manually load images
Describe the feature
There is a method in the docs to manually load an image before it enters the viewport. This is not yet possible when using the Nuxt integration, or am I missing something?
A practical use case could be a horizontal slideshow, where you could preload the previous and the next slide image manually, so that they are already loaded when the user switches slides.
I tested it with a new prop named immediateLoad
(see jjjuulliiaann@5784246) that triggers the loading when set to true. Do you think that could be a useful addition? I noticed you already had a similar implementation a while ago but removed it in 4e03c62.
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
Error event
Describe the feature
How can you tell if there was an error while downloading?
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
Support async createPngDataUri
Hi! I believe it would be nice to add an asynchronous method that reads data using FileReader and does it faster.
Here is an example
Image is loaded twice
Reproduction
https://stackblitz.com/edit/nuxt-3-xqdc5j?file=app.vue
Describe the bug
Hey,
I maybe found another bug, but I am not sure why it is happening. Is hapens with src and srcset attribute. Also tested it on localhost and on a nuxt build. The image is loaded twice. Also the image is only shown, when the image is loaded the second time.
You can test this, when you go into the network panel and selected the img filter.
Thanks for your help in advance again.
Best regards
Chris
Additional context
No response
Logs
No response
Suggestion: Implement evanw/thumbhash
Describe the feature
Great library! Thumbhash was released a couple of days, which also supports the alpha channel in the image, could there be an option to enable this?
Resources
Thumbhash
JS implementation
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
[nuxt] Image not loaded when `src` attribute is set
Reproduction
None
Describe the bug
After I install @ unlazy/nuxet and add it to nuxt.config.ts.
The image doesn't display properly. Did I miss any Settings
When I set the placeholder src attribute, the image can be displayed normally, but it doesn't seem like lazy loading mode anymore. How can I achieve simple lazy loading? Also, by the way, I only want to display the original image without any other processing required
Additional context
"nuxt": "^3.7.0"
"@unlazy/nuxt": "^0.9.3"
Logs
None
[vue] No `sizes` attribute set when using `preload="true"`
Reproduction
<UnLazyImage
:src-set="sourceSet"
:placeholder-src="placeholderSrc"
:auto-sizes="true"
:width="image.width"
:height="image.height"
:alt="image.alt"
:title="image.title"
:preload="true"
class="u-object-cover"
/>
Describe the bug
When using :auto-sizes="true"
in conjunction with :preload="true"
the sizes attribute is not set.
This happens because UnLazyImage.vue
checks if props.preload === true
and uses the loadImage
method to load the image directly. But the loadImage
function is not checking, if the sizes
attribute should be calculated.
Additional context
No response
Logs
No response
Nuxt Hydration Attribute Mismatch
Reproduction
- Running the nuxt playground within this package.
- Opening the developer console.
- You will see a few Hydration attribute mismatch warnings.
- The Hydration mismatch only applies to images where the placeholder is SSR rendered.
Describe the bug
The package is expected to not
throw hydration attribute mismatch warnings on every single SSR placeholder rendered image that is being loaded.
I tried multiple things like applying a key
attribute. However, I was unable to prevent these warnings.
I understand they are just warnings, but they are immensely annoying in developing because they clog the console output significantly.
My best guess would be that the nuxt component may need a way to wait for hydration before the placeholders are replaced with the actual image?
Additional context
Screenshot showing the warnings after installing and running this repository itself and starting the Nuxt playground.
Logs
No response
Conditionally disable error logging
Discussed in #34
Originally posted by chrisspiegl October 25, 2023
I am trying to just display a thumbhash
in some instances.
But if I do this with UnlazyImage
I always get the error on the console:
[unlazy] Missing `data-src` or `data-srcset` attribute
I agree that this makes sense, but is there a way to make it known that I really don't want any src
to load? Or maybe a way to prevent the src
from loading in any kind of automatic way and only do so when there is a parameter set to true
?
I have achieved something like this with a workaround to manually create the src
from the thumbhash with the provided functions. But thought this could be cleaner by providing something of a parameter?
Warm regards,
Chris
Allow adding media attribute to picture element
Describe the feature
Hey,
I love your plugin. It is super helpful. I now have the case where I would like to add media attributes to a picture element with your plugin, but unfortunately it is not possible right now, correct? When I add media property to the sources array, it doesn't show up in the code.
So I would like to get something like this:
<picture>
<source
media="(orientation: landscape)"
srcset="image-320w.jpg 320w, image-640w.jpg 640w"
/>
<source
media="(orientation: portrait)"
srcset="image-320w.jpg 320w, image-640w.jpg 640w"
/>
<img src="/images/foo.jpg" />
</picture>
Is it possible to allow this for the sourcesObject:
const exampleSources = [
{
media: "(orientation: landscape)",
srcSet: "image-320w.jpg 320w, image-640w.jpg 640w",
},
{
media: "(orientation: portrait)",
srcSet: "image-320w.jpg 320w, image-640w.jpg 640w",
},
];
Thanks for your help in advance.
Best regards
Chris
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
Lazyload videos
Describe the feature
Are there any plans to handle videos or is this library for images only (or do I miss something)?
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
feat: Fixed size, varying density
Describe the feature
as fixed-size-varying-density said, this feature provides,
- base on the biggest DPI image, e.g. 3x/image.png
- auto generate lower DPI image, e.g. 2x/image.png, 1x/image.png
- auto caculate the fixed width/height of image in 1x/image.png. e.g. width1x
- finally something like
<img src="~assets/1x/image.png" srcset="~assets/2x/image.png 2x, ~assets/3x/image.png 3x" :width="width1x"
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
Incorrect loading behaviour in Chrome web browser
Reproduction
I cant share the link to the customer, but it happens on two webpages in the menu.
Describe the bug
Chrome preloads menu images on a customer webpage of mine, even if they are hidden initially.
Hidden images have no width
and height
and the auto-sizes
calculation skips and sets no sizes
attribute.
The srcset
injection still occurs and replaces the data-srcset
with srcset
.
Without a sizes
attribute set, the image will fallback to the default 100vw
value and will load the largest image possible (with a large screen).
The images are loaded after the CSS is loaded, so the image should already hidden by then.
Only Chrome has this issue, Firefox behaves correctly.
Order of events
- HTML is loaded
- CSS is loaded main-[hash].css
- Hidden images are loaded by Chrome (not Firefox)
- Images have no size => sizes attribution fails => no sizes attribute set
- Srcset is still injected
- Without sizes attribute, browser fallbacks to 100vw.
- Loads large mega-navi.jpg (example - happens with other images in the menu too)
Additional context
No response
Logs
No response
Loaded event is not fired when used with preload attribute
Reproduction
https://stackblitz.com/edit/nuxt-3-xqdc5j?file=app.vue
Describe the bug
Hey,
I think I found a bug for the loaded event. When using the preload prop the loaded event is not fired.
You can see this in the reproduction link. When you remove the preload attribute, it is working as expected and will remove the opacity-0 css class and also set the isLoaded ref to true.
If you have more questions, don't hesitate to ask me. :)
Thanks for your help.
Best regards
Chris
Additional context
No response
Logs
No response
Disable console errors when only placeholder is used
Discussed in #34
Originally posted by chrisspiegl October 25, 2023
I am trying to just display a thumbhash
in some instances.
But if I do this with UnlazyImage
I always get the error on the console:
[unlazy] Missing `data-src` or `data-srcset` attribute
I agree that this makes sense, but is there a way to make it known that I really don't want any src
to load? Or maybe a way to prevent the src
from loading in any kind of automatic way and only do so when there is a parameter set to true
?
I have achieved something like this with a workaround to manually create the src
from the thumbhash with the provided functions. But thought this could be cleaner by providing something of a parameter?
Warm regards,
Chris
Img sizes attribute not updating on image resize
Describe the feature
When resizing the browser window, some image sizes may change.
Currently the sizes
attribute of the image is not updated, when a resize occurs.
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
Missing reactivity for `src` prop in `UnLazyImage`
Reproduction
Reproduction link: link
Insert any image from the ones provided, for example Ivan Grozny, and click on the "Update Image" button.
The image is expected to change.
In fact, what happens is that the image remains the same
Describe the bug
After reactively changing the image URL, the UnLazyImage component does not render the new value inside the src prop.
Additional context
Logs
No response
Angular Integration
Reproduction
import { lazyLoad } from 'unlazy'
// Apply lazy loading for all images by the selector img[loading="lazy"]
lazyLoad()
Describe the bug
i have follow all the step but nothing happen in img tag
Additional context
No response
Logs
No response
`data-sizes="auto"` not triggering on `<source>` tag
Reproduction
Use the picture tag example from the docs: https://unlazy.byjohann.dev/guide/usage.html#usage
Describe the bug
data-sizes="auto"
is not resolved on the source tag, but only on the img tag. No sizes tag is set on <source>
tags.
Additional context
No response
Logs
No response
`<picture>` tag support
Describe the feature
Most of my current projects use <picture>
tags with different sizes and image codecs (WebP / JPG / PNG etc.) and I would love to be able to use unlazy for them, but it seems like currently only the <img>
tag is supported.
Additional information
- Would you be willing to help implement this feature?
- Can you think of other implementations of this feature?
Final checks
- Check existing issues.
Usage with `<picture>` tag loads images twice
Reproduction
https://github.com/tobimori/kirby-baukasten/blob/main/site/snippets/picture.php
Describe the bug
When using unlazy with the <picture>
tag, multiple source
elements that each have data-srcset
and an img
element with the necessary data-src
attribute, the image specified in data-src
is downloaded before data-srcset
which results in a duplicated download of those images.
Some sites where I noticed this:
Additional context
No response
Logs
No response
No error messages provided on incorrect implementation
Reproduction
.
Describe the bug
If you forget to add data-src
or data-srcset
, the lazy loading for the given image is skipped without a error message. This can be hard to debug for new users.
Additional context
No response
Logs
No response
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.