Code Monkey home page Code Monkey logo

unlazy's Introduction

unlazy library

unlazy

npm version bundle

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.

Features

  • ๐ŸŽ€ 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

Setup

๐Ÿ“– Read the documentation

# pnpm
pnpm add -D unlazy

# npm
npm i -D unlazy

Basic Usage

๐Ÿ“– Read the documentation

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.

๐Ÿ’ป Development

  1. Clone this repository
  2. Enable Corepack using corepack enable
  3. Install dependencies using pnpm install
  4. Run pnpm run dev:prepare
  5. Start development server using pnpm run dev inside the one of the packages directories

License

MIT License ยฉ 2023-PRESENT Johann Schopplich

unlazy's People

Contributors

aloky avatar danielroe avatar eric-hc avatar felixranesberger avatar hacknug avatar johannschopplich avatar ndom91 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

unlazy'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

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

[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

image
image

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

image

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

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

Uncaught RangeError: Maximum call stack size exceeded

Reproduction

I don't know what's causing this issue, but I can help you investigate. just message me.

Describe the bug

This is the error in v0.10.0.
CleanShot 2023-09-12 at 17 42 26@2x
CleanShot 2023-09-12 at 17 41 38@2x

I get a similiar error in v0.9.0, just for a different type of code.
CleanShot 2023-09-12 at 17 46 40@2x

Additional context

No response

Logs

No response

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

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

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.

image

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

[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.

image

The image doesn't display properly. Did I miss any Settings

image

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
image

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.

Xnapper-2024-03-11-15 06 55

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

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

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

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

  1. HTML is loaded
  2. CSS is loaded main-[hash].css
  3. Hidden images are loaded by Chrome (not Firefox)
  4. Images have no size => sizes attribution fails => no sizes attribute set
  5. Srcset is still injected
  6. Without sizes attribute, browser fallbacks to 100vw.
  7. Loads large mega-navi.jpg (example - happens with other images in the menu too)
Screenshot 2023-11-07 at 12 19 41

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

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

image

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

`<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

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.

38291

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 photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.