{"id":22489337,"url":"https://github.com/johannschopplich/loadeer","last_synced_at":"2025-08-02T21:32:37.946Z","repository":{"id":37717401,"uuid":"401811435","full_name":"johannschopplich/loadeer","owner":"johannschopplich","description":"🦌 Tiny, performant, SEO-friendly lazy loading library. Deprecated, please use https://unlazy.byjohann.dev","archived":true,"fork":false,"pushed_at":"2023-04-15T10:21:47.000Z","size":1005,"stargazers_count":43,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-12-01T03:50:12.430Z","etag":null,"topics":["lazy-loading","lazyload","lozad","native-lazy-loading","seo"],"latest_commit_sha":null,"homepage":"https://unlazy.byjohann.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johannschopplich.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"custom":["https://paypal.me/jschopplich"]}},"created_at":"2021-08-31T18:52:20.000Z","updated_at":"2024-09-12T17:49:13.000Z","dependencies_parsed_at":"2023-01-29T19:30:38.235Z","dependency_job_id":null,"html_url":"https://github.com/johannschopplich/loadeer","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johannschopplich%2Floadeer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johannschopplich%2Floadeer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johannschopplich%2Floadeer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johannschopplich%2Floadeer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johannschopplich","download_url":"https://codeload.github.com/johannschopplich/loadeer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228500221,"owners_count":17930020,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lazy-loading","lazyload","lozad","native-lazy-loading","seo"],"created_at":"2024-12-06T17:19:40.315Z","updated_at":"2025-08-02T21:32:37.903Z","avatar_url":"https://github.com/johannschopplich.png","language":"TypeScript","funding_links":["https://paypal.me/jschopplich"],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./.github/icon.svg\" alt=\"Loadeer.js Logo\" width=\"180\" height=\"180\"\u003e\n\u003c/p\u003e\n\n\u003ch3 align=\"center\"\u003eLoadeer.js\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n  Tiny, performant, SEO-friendly lazy loading library\u003cbr\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n\u003e **Note**\n\u003e\n\u003e It's 2023 – by now most browsers support native lazy loading with `loading=\"lazy\"`. If you're looking for a library that combines native lazy loading with blurry placeholder support, I recommend [unlazy](https://github.com/johannschopplich/unlazy). It's the spiritual successor of Loadeer.js.\n\u003e\n\u003e [unlazy](https://github.com/johannschopplich/unlazy) has a smaller footprint and doesn't require an Intersection Observer. I recommend using it instead of Loadeer.js.\n\n## Loadeer.js\n\nIf you have used [Lozad.js](https://github.com/ApoorvSaxena/lozad.js), then you already know how to use Loadeer.js. This library is basically an overhauled and opinionated version of Lozad.js, which includes `sizes` support, makes usage of `data` attributes instead of classes and is written in TypeScript.\n\nLoadeer.js is intended to be used with `\u003cimg\u003e`, `\u003cpicture\u003e` and `\u003cvideo\u003e` tags. It supports the `srcset` and `sizes` attributes, as well as the `loading` attribute. It is also possible to use the `data` attributes instead of the native attributes.\n\n### Key Features\n\n- 🍃 **Zero dependencies**: 1 kB minified \u0026 gzipped\n- 🏎 **Auto initialize**: with the `init` script attribute\n- 🪄 **Sizing**: Automatically calculates the `sizes` attribute\n- 🎀 **Native**: Use [native `loading=\"lazy\"`](#native-lazy-loading) if you prefer\n- 🔧 **Customizable**: Use `data` attributes for image sources\n- 🎟 **`\u003cpicture\u003e`**: Supports multiple image formats\n- 🔍 **SEO-friendly**: Detects e.g. Google Bot and preloads all images\n\n## Installation\n\nLoadeer.js can be used without a build step. Simply load it from a CDN:\n\n```html\n\u003cscript src=\"https://unpkg.com/loadeer\" defer init\u003e\u003c/script\u003e\n\n\u003c!-- Anywhere on the page --\u003e\n\u003cimg\n  data-lazyload\n  data-srcset=\"/foo.png 1024w, /foo-2x.png 2048w\"\n/\u003e\n\n\u003c!-- Or use the picture tag instead --\u003e\n\u003cpicture\u003e\n  \u003csource data-lazyload data-srcset=\"/bar.jpg\" media=\"(min-width: 800px)\"\u003e\n\u003c/picture\u003e\n```\n\n- The `defer` attribute makes the script execute after HTML content is parsed.\n- The `init` attribute tells Loadeer.js to automatically initialize and watch all elements that have a `data-lazyload` attribute.\n\n### Manual Initialization\n\nIf you don't want the auto initialize, remove the `init` attribute and move the scripts to end of `\u003cbody\u003e`:\n\n```html\n\u003cscript src=\"https://unpkg.com/loadeer\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  const loadeer = new Loadeer()\n  loadeer.observe()\n\u003c/script\u003e\n```\n\nOr, use the ES module build by installing the [`loadeer` npm package](https://www.npmjs.com/package/loadeer):\n\n```js\nimport Loadeer from 'loadeer'\n\nconst loadeer = new Loadeer()\nloadeer.observe()\n```\n\n### Production CDN URLs\n\nThe short CDN URLs are meant for prototyping. For production usage, use a fully resolved CDN URL to avoid resolving and redirect cost:\n\n- Global build: https://unpkg.com/loadeer@2.1.3/dist/loadeer.iife.js\n  - Exposes `Loadeer` global property, supports auto initializing\n- ESM build: https://unpkg.com/loadeer@2.1.3/dist/loadeer.es.js\n  - Must be used with `\u003cscript type=\"module\"\u003e`\n\n## Usage\n\n### Basic\n\nAdd the `data-lazyload` attribute to an element of your choice which you seek to lazily load. Set a `data-src` or `data-srcset` attribute as well.\n\n```html\n\u003c!-- You can use the img tag --\u003e\n\u003cimg data-lazyload data-src=\"image.png\" /\u003e\n\n\u003c!-- … or the picture element --\u003e\n\u003cpicture\u003e\n  \u003csource data-lazyload data-srcset=\"/foo.jpg\" media=\"(min-width: 800px)\"\u003e\n\u003c/picture\u003e\n```\n\nAlthough Loadeer.js' default selector is `data-lazyload`, you may configure it to a selector of your choice. See the libraries options for more information.\n\nFinally, instantiate Loadeer.js as follows:\n\n```js\nconst instance = new Loadeer()\n// Lazily loads all `data-lazyload` images\ninstance.observe()\n```\n\n### Native Lazy Loading\n\n\u003e **Note**\n\u003e\n\u003e Use with caution. Especially if placeholder images are used, the native lazy loading attribute interferes, since all `data-src` attributes will be converted to `src` once Loadeer.js runs. All placeholder images will be overwritten and if the images are loaded slower than the user scrolls, blank spaces will occur. Thus, Loadeer.js doesn't enable native lazy loading by default.\n\nBrowser support for `loading=\"lazy\"` is decent. At the time writing, only Safari lacks support. If the option `useNativeLoading` is set to `true` and Loadeer.js detects the browser supports lazy loading, the `loading` attribute will be set to `lazy` and all `data-src` attributes changed to `src`. No intersection observer will be initialized.\n\nUse the default selector:\n\n```html\n\u003cimg data-lazyload data-src=\"image.png\" /\u003e\n```\n\nOr use the future-proof `loading` attribute as selector:\n\n```html\n\u003cimg loading=\"lazy\" data-src=\"image.png\" /\u003e\n```\n\nFinally, change the default selector parameter for the latter case:\n\n```js\nconst instance = new Loadeer('img[loading=\"lazy\"]')\ninstance.observe()\n```\n\n### Auto Calculation of the `sizes` Attribute\n\nLoadeer.js supports setting the sizes attribute automatically, corresponding to the current size of your image – just set the value of `data-sizes` to `auto`.\n\nThe automatic sizes calculation uses the display width of the image.\n\n```html\n\u003cimg\n  data-lazyload\n  data-srcset=\"image-480w.jpg 480w, image-800w.jpg 800w\"\n  data-sizes=\"auto\"\n/\u003e\n```\n\n### Custom Selector\n\nYou may pass an element or array of elements to the constructor as well:\n\n```js\nconst root = document.querySelector('#app')\nconst instance = new Loadeer(root)\ninstance.observe()\n```\n\nSee the [API](#api) for all available options.\n\n### Trigger Loading of Images Manually\n\nIf you want to load the images before they appear, use the `triggerLoad` method.\n\n```js\nconst instance = new Loadeer()\ninstance.observe()\n\nconst coolImage = document.querySelector('.image-to-load-first')\n// Trigger the load before the image appears in the viewport\nobserver.triggerLoad(coolImage)\n```\n\n### Custom Options\n\nPass a `onLoaded` function to either manipulate the loaded element or do anything else with it.\n\n```js\nfunction onLoaded(element) {\n  console.log('Lazily loaded element:', element)\n}\n\nconst instance = new Loadeer('[data-lazyload]', {\n  root: document.querySelector('#app'),\n  rootMargin: '10px 0px',\n  threshold: 0.1,\n  onLoaded,\n})\n\ninstance.observe()\n```\n\nBoth the [`rootMargin`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/rootMargin) and [`thresholds`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/thresholds) options are passed to directly to the `IntersectionObserver` and thus infer their respective types.\n\n## API\n\n### `new Loadeer(selector, options: LoadeerOptions = {})`\n\n#### `Selector`\n\nDefaults to `[data-lazyload]`. Allowed types are every valid CSS selector string, an element, an array of elements, or a `NodeListOf` elements:\n\n```ts\ntype LoadeerElement = HTMLImageElement | HTMLSourceElement | HTMLVideoElement\n\ntype LoadeerInput\u003cT extends HTMLElement\u003e =\n  | string\n  | T\n  | T[]\n  | NodeListOf\u003cT\u003e\n```\n\n#### `LoadeerOptions`\n\n\u003e Note: Every property is optional and will be set to its default value if not provided.\n\n| Option             | Default     | Type                                          | Description                                                                                                                                      |\n| ------------------ | ----------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `root`             | `document`  | `Element`, `Document`, `null`, `undefined`    | The container within elements will be lazily loaded.                                                                                             |\n| `rootMargin`       | `0px`       | `string`, `undefined`                         | See `IntersectionObserver` [`rootMargin` parameter](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/IntersectionObserver). |\n| `threshold`        | `0`         | `number`, `number[]`, `undefined`             | See `IntersectionObserver` [`threshold` parameter](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/IntersectionObserver).  |\n| `onLoaded`         | `undefined` | `(element: HTMLElement) =\u003e void`, `undefined` | Custom function to run after each image is loaded.                                                                                               |\n| `useNativeLoading` | `false`     | `boolean`, `undefined`                        | Indicates if the native `loading=\"lazy\"` attribute should be used (if supported by the browser).                                                 |\n\n## Cookbook\n\n### Animated Blurry Placeholder with GSAP\n\nA fellow Kirby developer ([Thomas Günther](https://github.com/medienbaecker)) using Loadeer.js in a project of his came up with a nice idea to use a blurry placeholder image with a blurred version of the actual image. The code below will create a smooth animation effect for the image placeholders, transitioning from a blurry state to the fully loaded image, using the powerful GSAP library for animations.\n\n👉 [Animate blurry-placeholder with Loadeer and GSAP on CodePen](https://codepen.io/medienbaecker/pen/yLEMdoN)\n\n## SEO\n\nLoadeer.js does not hide elements from Google. The library detects whether the user agent is probably a bot or crawler and will load all images.\n\n## Credits\n\n- [Lozad.js](https://github.com/ApoorvSaxena/lozad.js) for heavy inspiration.\n\n## License\n\n[MIT](./LICENSE) License © 2021-2023 [Johann Schopplich](https://github.com/johannschopplich)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohannschopplich%2Floadeer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohannschopplich%2Floadeer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohannschopplich%2Floadeer/lists"}