unlazy
Version:
Universal lazy loading library for placeholder images leveraging native browser APIs
1 lines • 4.42 kB
JavaScript
var UnLazy=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});let t=!(typeof window>`u`)&&(!(`onscroll`in window)||/(?:gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent));function n(e,t=document){return typeof e==`string`?[...t.querySelectorAll(e)]:e instanceof Element?[e]:[...e]}function r(e){let t=Date.now();return`data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'%3E%3C/svg%3E`.replace(/\s/,` data-id='${t}-${e}' `)}function i(e,t){let n;return function(...r){n!=null&&clearTimeout(n),n=setTimeout(()=>{e(...r),n=void 0},t)}}let a=!1;function o(){if(!a){a=!0;try{new PerformanceObserver(e=>{for(let t of e.getEntries()){let e=t.element;if(!e||e.tagName!==`IMG`)continue;let n=e.loading===`lazy`,r=e.hasAttribute(`data-src`)||e.hasAttribute(`data-srcset`);(n||r)&&console.warn('[unlazy] LCP element is configured for lazy loading. Set `loading="eager"` to improve Largest Contentful Paint.',e)}}).observe({type:`largest-contentful-paint`,buffered:!0})}catch{}}}let s=new WeakSet;function c(e=`img[loading="lazy"], img[loading="eager"][data-src], img[loading="eager"][data-srcset]`,{hash:i=!0,hashType:a=`blurhash`,placeholderSize:c=32,updateSizesOnResize:d=!1,onImageLoad:f,onImageError:p}={}){let m=new Set;(typeof __UNLAZY_LOGGING__>`u`||__UNLAZY_LOGGING__)&&o();for(let[i,a]of n(e).entries()){if(s.has(a))continue;let e=a.loading===`eager`;if(e&&!a.hasAttribute(`fetchpriority`)&&a.setAttribute(`fetchpriority`,`high`),m.add(l(a,{updateOnResize:d})),!a.dataset.src&&!a.dataset.srcset){(typeof __UNLAZY_LOGGING__>`u`||__UNLAZY_LOGGING__)&&console.error("[unlazy] Missing `data-src` or `data-srcset` attribute",a);continue}if(s.add(a),e||t){if(f){let e=()=>f(a);a.addEventListener(`load`,e,{once:!0}),m.add(()=>a.removeEventListener(`load`,e))}if(p){let e=e=>p(a,e);a.addEventListener(`error`,e,{once:!0}),m.add(()=>a.removeEventListener(`error`,e))}g(a),h(a,`srcset`),h(a,`src`);continue}if(a.src||=r(i),a.complete&&a.naturalWidth>0){m.add(u(a,{onImageLoad:f,onImageError:p}));continue}let n=()=>{m.add(u(a,{onImageLoad:f,onImageError:p}))};a.addEventListener(`load`,n,{once:!0}),m.add(()=>a.removeEventListener(`load`,n))}return()=>{for(let e of m)e();m.clear()}}function l(e=`img[data-sizes="auto"], source[data-sizes="auto"]`,{updateOnResize:t=!1}={}){let r=[];for(let i of n(e))r.push(d(i,t));return()=>{for(let e of r)e();r.length=0}}function u(e,{onImageLoad:t,onImageError:n}={}){let r=[],i=()=>{for(let e of r)e();r.length=0};if(v(e)){if(t){let n=()=>t(e);e.addEventListener(`load`,n,{once:!0}),r.push(()=>e.removeEventListener(`load`,n))}if(n){let t=t=>n(e,t);e.addEventListener(`error`,t,{once:!0}),r.push(()=>e.removeEventListener(`error`,t))}return g(e),h(e,`srcset`),h(e,`src`),i}let{srcset:a,src:o,sizes:s}=e.dataset;if(!a&&!o)return i;let c=new Image,l=()=>{h(e,`srcset`),h(e,`src`),t?.(e)},u=t=>{e.dispatchEvent(new Event(`error`)),n?.(e,t)};if(c.addEventListener(`load`,l,{once:!0}),c.addEventListener(`error`,u,{once:!0}),r.push(()=>{c.removeEventListener(`load`,l),c.removeEventListener(`error`,u),c.src=``}),s===`auto`){let t=_(e);t&&(c.sizes=`${t}px`)}else e.sizes&&(c.sizes=e.sizes);return a&&(c.srcset=a),o&&(c.src=o),i}function d(e,t){let n=p(e);for(let e of n)m(e);if(!t||!n.some(f))return y;let r=e instanceof HTMLImageElement?e:e.parentElement?.getElementsByTagName(`img`)[0]??null;if(!r)return y;let a=i(()=>{for(let t of p(e))m(t)},500),o=new ResizeObserver(a);return o.observe(r),()=>o.disconnect()}function f(e){return e.dataset.sizes===`auto`}function p(e){let t=[e];if(e instanceof HTMLImageElement&&e.parentElement?.tagName.toLowerCase()===`picture`)for(let n of e.parentElement.querySelectorAll(`source[data-sizes="auto"]`))t.push(n);return t}function m(e){if(e.dataset.sizes!==`auto`)return;let t=_(e);if(!t)return;let n=`${t}px`;e.sizes!==n&&(e.sizes=n)}function h(e,t){let n=e.dataset[t];n&&(e[t]=n,e.removeAttribute(`data-${t}`))}function g(e){let t=e.parentElement;if(t?.tagName.toLowerCase()===`picture`)for(let e of t.querySelectorAll(`source[data-srcset]`))m(e),h(e,`srcset`)}function _(e){return e instanceof HTMLSourceElement?e.parentElement?.getElementsByTagName(`img`)[0]?.offsetWidth:e.offsetWidth}function v(e){return e.parentElement?.tagName.toLowerCase()===`picture`}function y(){}return document.currentScript?.hasAttribute(`init`)&&c(),e.autoSizes=l,e.lazyLoad=c,e.triggerLoad=u,e})({});