UNPKG

unlazy

Version:

Universal lazy loading library for placeholder images leveraging native browser APIs

13 lines 8.85 kB
const e=new Uint8Array(128);for(let t=0;t<83;t++)e[`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~`.charCodeAt(t)]=t;const t=(t,n,r)=>{let i=0;for(;n<r;)i*=83,i+=e[t.charCodeAt(n++)];return i},n=Math.pow,r=Math.PI,i=r*2,a=3294.6,o=269.025,s=e=>e>10.31475?n(e/o+.052132,2.4):e/a,c=e=>~~(e>1227e-8?o*n(e,.416666)-13.025:e*a+1),l=e=>(e<0?-1:1)*e*e,u=e=>{for(e+=r/2;e>r;)e-=i;let t=1.27323954*e-.405284735*l(e);return .225*(l(t)-t)+t};function d(e){let n=t(e,2,6);return[n>>16,n>>8&255,n&255]}function f(e,n,i,a){let o=t(e,0,1),f=o%9+1,p=~~(o/9)+1,m=f*p,h=0,g=0,_=0,v=0,y=0,b=0,x=0,S=0,C=0,w=0,T=0,E=0,D=(t(e,1,2)+1)/13446*(a|1),O=new Float64Array(m*3),k=d(e);for(h=0;h<3;h++)O[h]=s(k[h]);for(h=1;h<m;h++)E=t(e,4+h*2,6+h*2),O[h*3]=l(~~(E/361)-9)*D,O[h*3+1]=l(~~(E/19)%19-9)*D,O[h*3+2]=l(E%19-9)*D;let A=new Float64Array(p*i),j=new Float64Array(f*n);for(g=0;g<p;g++)for(v=0;v<i;v++)A[g*i+v]=u(r*v*g/i);for(h=0;h<f;h++)for(_=0;_<n;_++)j[h*n+_]=u(r*_*h/n);let M=n*4,N=new Uint8ClampedArray(M*i);for(v=0;v<i;v++)for(_=0;_<n;_++){for(y=b=x=0,g=0;g<p;g++)for(C=A[g*i+v],h=0;h<f;h++)S=j[h*n+_]*C,w=(h+g*f)*3,y+=O[w]*S,b+=O[w+1]*S,x+=O[w+2]*S;T=4*_+v*M,N[T]=c(y),N[T+1]=c(b),N[T+2]=c(x),N[T+3]=255}return N} /** * Encodes an RGBA image to a PNG data URI. RGB should not be premultiplied by A. * * @remarks * This is optimized for speed and simplicity and does not optimize for size * at all. This does not do any compression (all values are stored uncompressed). * * @see https://github.com/evanw/thumbhash * @author Evan Wallace * @license MIT */ function p(e,t,n){let r=e*4+1,i=6+t*(5+r),a=[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,e>>8,e&255,0,0,t>>8,t&255,8,6,0,0,0,0,0,0,0,i>>>24,i>>16&255,i>>8&255,i&255,73,68,65,84,120,1],o=[0,498536548,997073096,651767980,1994146192,1802195444,1303535960,1342533948,-306674912,-267414716,-690576408,-882789492,-1687895376,-2032938284,-1609899400,-1111625188],s=1,c=0;for(let e=0,i=0,o=r-1;e<t;e++,o+=r-1)for(a.push(e+1<t?0:1,r&255,r>>8,~r&255,r>>8^255,0),c=(c+s)%65521;i<o;i++){let e=n[i]&255;a.push(e),s=(s+e)%65521,c=(c+s)%65521}a.push(c>>8,c&255,s>>8,s&255,0,0,0,0,0,0,0,0,73,69,78,68,174,66,96,130);for(let[e,t]of[[12,29],[37,41+i]]){let n=-1;for(let r=e;r<t;r++)n^=a[r],n=n>>>4^o[n&15],n=n>>>4^o[n&15];n=~n,a[t++]=n>>>24,a[t++]=n>>16&255,a[t++]=n>>8&255,a[t++]=n&255}return`data:image/png;base64,${globalThis.btoa(String.fromCharCode(...a))}`}const m=!(typeof window>`u`)&&(!(`onscroll`in window)||/(?:gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent));function h(e,t=document){return typeof e==`string`?[...t.querySelectorAll(e)]:e instanceof Element?[e]:[...e]}function g(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 _(e,t){let n;return function(...r){n!=null&&clearTimeout(n),n=setTimeout(()=>{e(...r),n=void 0},t)}}function v(e,{ratio:t=1,size:n=32}={}){let{width:r,height:i}=y(t,n);return p(r,i,f(e,r,i))}function y(e,t){let n=e>=1;return{width:n?t:Math.round(t*e),height:n?Math.round(t/e):t}}let b=!1;function x(){if(!b){b=!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{}}}function S(e){let{PI:t,min:n,max:r,cos:i,round:a}=Math,o=e[0]|e[1]<<8|e[2]<<16,s=e[3]|e[4]<<8,c=(o&63)/63,l=(o>>6&63)/31.5-1,u=(o>>12&63)/31.5-1,d=(o>>18&31)/31,f=o>>23,p=(s>>3&63)/63,m=(s>>9&63)/63,h=s>>15,g=r(3,h?f?5:7:s&7),_=r(3,h?s&7:f?5:7),v=f?(e[5]&15)/15:1,y=(e[5]>>4)/15,b=f?6:5,x=0,S=(t,n,r)=>{let i=[];for(let a=0;a<n;a++)for(let o=+!a;o*n<t*(n-a);o++)i.push(((e[b+(x>>1)]>>((x++&1)<<2)&15)/7.5-1)*r);return i},w=S(g,_,d),T=S(3,3,p*1.25),E=S(3,3,m*1.25),D=f&&S(5,5,y),O=C(e),k=a(O>1?32:32*O),A=a(O>1?32/O:32),j=new Uint8Array(k*A*4),M=[],N=[];for(let e=0,a=0;e<A;e++)for(let o=0;o<k;o++,a+=4){let s=c,d=l,p=u,m=v;for(let e=0,n=r(g,f?5:3);e<n;e++)M[e]=i(t/k*(o+.5)*e);for(let n=0,a=r(_,f?5:3);n<a;n++)N[n]=i(t/A*(e+.5)*n);for(let e=0,t=0;e<_;e++)for(let n=+!e,r=N[e]*2;n*_<g*(_-e);n++,t++)s+=w[t]*M[n]*r;for(let e=0,t=0;e<3;e++)for(let n=+!e,r=N[e]*2;n<3-e;n++,t++){let e=M[n]*r;d+=T[t]*e,p+=E[t]*e}if(f)for(let e=0,t=0;e<5;e++)for(let n=+!e,r=N[e]*2;n<5-e;n++,t++)m+=D[t]*M[n]*r;let h=s-2/3*d,y=(3*s-h+p)/2,b=y-p;j[a]=r(0,255*n(1,y)),j[a+1]=r(0,255*n(1,b)),j[a+2]=r(0,255*n(1,h)),j[a+3]=r(0,255*n(1,m))}return{w:k,h:A,rgba:j}}function C(e){let t=e[3],n=e[2]&128,r=e[4]&128;return(r?n?5:7:t&7)/(r?t&7:n?5:7)}function w(e){let{w:t,h:n,rgba:r}=S(T(e));return p(t,n,r)}function T(e){return Uint8Array.from(globalThis.atob(E(e)),e=>e.charCodeAt(0))}function E(e){return e.replaceAll(`-`,`+`).replaceAll(`_`,`/`)}const D=new WeakSet;function O(e=`img[loading="lazy"], img[loading="eager"][data-src], img[loading="eager"][data-srcset]`,{hash:t=!0,hashType:n=`blurhash`,placeholderSize:r=32,updateSizesOnResize:i=!1,onImageLoad:a,onImageError:o}={}){let s=new Set;(typeof __UNLAZY_LOGGING__>`u`||__UNLAZY_LOGGING__)&&x();for(let[c,l]of h(e).entries()){if(D.has(l))continue;let e=l.loading===`eager`;if(e&&!l.hasAttribute(`fetchpriority`)&&l.setAttribute(`fetchpriority`,`high`),s.add(k(l,{updateOnResize:i})),t){let e=j({image:l,hash:typeof t==`string`?t:void 0,hashType:n,size:r});e&&(l.src=e)}if(!l.dataset.src&&!l.dataset.srcset){(typeof __UNLAZY_LOGGING__>`u`||__UNLAZY_LOGGING__)&&console.error("[unlazy] Missing `data-src` or `data-srcset` attribute",l);continue}if(D.add(l),e||m){if(a){let e=()=>a(l);l.addEventListener(`load`,e,{once:!0}),s.add(()=>l.removeEventListener(`load`,e))}if(o){let e=e=>o(l,e);l.addEventListener(`error`,e,{once:!0}),s.add(()=>l.removeEventListener(`error`,e))}L(l),I(l,`srcset`),I(l,`src`);continue}if(l.src||=g(c),l.complete&&l.naturalWidth>0){s.add(A(l,{onImageLoad:a,onImageError:o}));continue}let u=()=>{s.add(A(l,{onImageLoad:a,onImageError:o}))};l.addEventListener(`load`,u,{once:!0}),s.add(()=>l.removeEventListener(`load`,u))}return()=>{for(let e of s)e();s.clear()}}function k(e=`img[data-sizes="auto"], source[data-sizes="auto"]`,{updateOnResize:t=!1}={}){let n=[];for(let r of h(e))n.push(M(r,t));return()=>{for(let e of n)e();n.length=0}}function A(e,{onImageLoad:t,onImageError:n}={}){let r=[],i=()=>{for(let e of r)e();r.length=0};if(z(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 L(e),I(e,`srcset`),I(e,`src`),i}let{srcset:a,src:o,sizes:s}=e.dataset;if(!a&&!o)return i;let c=new Image,l=()=>{I(e,`srcset`),I(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=R(e);t&&(c.sizes=`${t}px`)}else e.sizes&&(c.sizes=e.sizes);return a&&(c.srcset=a),o&&(c.src=o),i}function j({image:e,hash:t,hashType:n=`blurhash`,size:r=32,ratio:i}={}){if(e&&!t){let{blurhash:r,thumbhash:i}=e.dataset;t=i||r,n=i?`thumbhash`:`blurhash`}if(t)try{return n===`blurhash`?(e&&!i&&(i=(e.width||e.offsetWidth||r)/(e.height||e.offsetHeight||r)),v(t,{ratio:i,size:r})):w(t)}catch(e){(typeof __UNLAZY_LOGGING__>`u`||__UNLAZY_LOGGING__)&&console.error(`[unlazy] Failed to generate ${n} placeholder:`,e)}}function M(e,t){let n=P(e);for(let e of n)F(e);if(!t||!n.some(N))return B;let r=e instanceof HTMLImageElement?e:e.parentElement?.getElementsByTagName(`img`)[0]??null;if(!r)return B;let i=_(()=>{for(let t of P(e))F(t)},500),a=new ResizeObserver(i);return a.observe(r),()=>a.disconnect()}function N(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 F(e){if(e.dataset.sizes!==`auto`)return;let t=R(e);if(!t)return;let n=`${t}px`;e.sizes!==n&&(e.sizes=n)}function I(e,t){let n=e.dataset[t];n&&(e[t]=n,e.removeAttribute(`data-${t}`))}function L(e){let t=e.parentElement;if(t?.tagName.toLowerCase()===`picture`)for(let e of t.querySelectorAll(`source[data-srcset]`))F(e),I(e,`srcset`)}function R(e){return e instanceof HTMLSourceElement?e.parentElement?.getElementsByTagName(`img`)[0]?.offsetWidth:e.offsetWidth}function z(e){return e.parentElement?.tagName.toLowerCase()===`picture`}function B(){}document.currentScript?.hasAttribute(`init`)&&O();export{k as autoSizes,O as lazyLoad,A as triggerLoad};