{"id":34566930,"url":"https://github.com/kasta-ua/lazysrcset","last_synced_at":"2025-12-24T09:09:17.909Z","repository":{"id":53208430,"uuid":"438247384","full_name":"kasta-ua/lazysrcset","owner":"kasta-ua","description":"Minuscule quick self-initializing lazy loader for responsive images.","archived":false,"fork":false,"pushed_at":"2022-07-26T08:20:43.000Z","size":3,"stargazers_count":22,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-03-09T03:41:26.777Z","etag":null,"topics":["javascript","lazyload","lazysizes","performance","responsive-images"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kasta-ua.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-12-14T12:37:55.000Z","updated_at":"2023-01-09T21:00:23.000Z","dependencies_parsed_at":"2022-08-13T02:20:50.542Z","dependency_job_id":null,"html_url":"https://github.com/kasta-ua/lazysrcset","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/kasta-ua/lazysrcset","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kasta-ua%2Flazysrcset","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kasta-ua%2Flazysrcset/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kasta-ua%2Flazysrcset/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kasta-ua%2Flazysrcset/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kasta-ua","download_url":"https://codeload.github.com/kasta-ua/lazysrcset/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kasta-ua%2Flazysrcset/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27999421,"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","status":"online","status_checked_at":"2025-12-24T02:00:07.193Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["javascript","lazyload","lazysizes","performance","responsive-images"],"created_at":"2025-12-24T09:09:17.679Z","updated_at":"2025-12-24T09:09:17.894Z","avatar_url":"https://github.com/kasta-ua.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lazysrcset\n\nMinuscule (\u003c1kb) quick (IntersectionObserver-powered) self-initializing lazy loader for responsive images with automatic `sizes` calculation.\n\n\n## Problem\n\nIf you ever tried to use responsive [`srcset`][1] - the one where you supply a few links to the same image, but resized to different width — you know that it doesn't automatically work like you imagine in the beginning. \n\nFirstly, you have to supply [`sizes` attribute][2], and it can't be relative to your container width, it should be some concrete value (like pixels or something). It supports `vw` (percentage of viewport width), but then your layout could be not as flexible.\n\nSecondly, if you try to determine `sizes` with JavaScript, the browser will automatically download one of the images – most probably the biggest one, since the default value for `sizes` is `100vw`.\n\n[1]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset\n[2]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes\n\n\n## So What\n\nThis is a solution. Instead of putting image sources into `\u003cimg src=\"\" srcset=\"\"\u003e`, you put them in `\u003cimg data-src=\"\" data-srcset=\"\"\u003e`, and then when the image comes close to a viewport:\n\n- If browser does not support `srcset`/`sizes`, `data-src` is copied into `src` \n- If it does support them, then image width is determined and put into `sizes`, and `data-srcset` is copied into `srcset`.\n\n\"Close to a viewport\" means \"at least 1% of an image is closer than 400px to a viewport\". This uses IntersectionObserver to be fast and light.\n\n\n## Usage\n\nSee [kasta.ua](https://kasta.ua) for an example of how this works. Ideally, you load this library as early as possible to make images load earlier (unfortunately, we prevent their preloading by browser by making them lazy). We inlined the script into HTML to make sure it's always loaded as early as possible.\n\nThen we use code like that for displaying images:\n\n```html\n\u003cspan class=\"aspect aspect--wide\"\u003e\n  \u003cnoscript\u003e\n    \u003cimg class=\"aspect-inner\"\n         style=\"aspect-ratio: 20/11\" \n         src=\"/images/640/img.jpg\"\u003e\n  \u003c/noscript\u003e\n  \u003cimg class=\"aspect-inner nojs-hide\"\n       style=\"aspect-ratio: 20/11\"\n       src=\"/images/placeholder.jpg\"\n       data-src=\"/images/640/img.jpg\"\n       data-srcset=\"/images/420/img.jpg 420w, /images/640/img.jpg 640w\"\u003e\n\u003c/span\u003e\n```\n\nThree things are going on here:\n\n- `\u003cimg src\u003e` contains placeholder, which is the same on every image and should be heavily cached (_this is your job_), to look better until real images load;\n- `lazysrcset.js` reacts to `data-srcset` on `DOMContentLoaded` and loads your images;\n- `aspect-ratio` is set so browser knows how much space is taken vertically (provided horizontally image fills all available space), this helps with FCP and LCP. Some CSS is necessary for older browsers;\n- when JS is disabled, browser uses `noscript` markup and shows single image. This needs a bit of CSS to work properly.\n\n\n### Older browsers\n\nIf you want to support [older browsers](https://caniuse.com/mdn-css_properties_aspect-ratio), this CSS is necessary:\n\n```css\n// https://css-tricks.com/aspect-ratio-boxes/\n.aspect {\n  display: block;\n  overflow: hidden;\n  position: relative;\n  height: 0;\n  // default image ratio\n  padding-top: calc(32 / 23 * 100%);\n}\n\n.aspect .aspect-inner {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n\n// if you need more ratios, height / width\n.aspect.aspect--wide   { padding-top: calc(11 / 20 * 100%); }\n.aspect.aspect--square { padding-top: 100%; }\n\n// disable for modern browsers\n@supports (aspect-ratio: 1 / 1) {\n  .aspect { height: inherit; }\n  .aspect .aspect-inner { position: static; }\n\n  .aspect,\n  .aspect.aspect--wide,\n  .aspect.aspect--square {\n    padding-top: 0;\n  }\n}\n```\n\n\n### `noscript`\n\nSupporting disabled JS needs one more thing, putting following markup in your `\u003chead\u003e`:\n\n```html\n\u003cnoscript\u003e\n  \u003cstyle\u003e.nojs-hide { display: none !important; }\u003c/style\u003e\n\u003c/noscript\u003e\n```\n\nThis way lazy-loaded image is hidden from users with disabled JS.\n\n\n## Configuration\n\nAll constants (400px, 1%, etc) are intentionally hardcoded inside to make library size smaller. We found that those are generally sensible defaults, but in case you want to change something, just copy this into your codebase and change things directly in code.\n\nIf you have some way of adding HTML markup dynamically, make sure you're raising an event on the new elements and modify this library to handle this (see `ts-ready` event at the end of the code). I would appreciate ideas how to handle this better.\n\n\n## Acknowledgements\n\nThis library is inspired by [lazysizes](https://github.com/aFarkas/lazysizes/), but is much smaller in scope and in size.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkasta-ua%2Flazysrcset","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkasta-ua%2Flazysrcset","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkasta-ua%2Flazysrcset/lists"}