quicklink
Version:
Faster subsequent page-loads by prefetching in-viewport links during idle time
2 lines (1 loc) • 2.33 kB
JavaScript
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e||self).quicklink={})}(this,function(e){function n(e,n,t,o){var r={headers:{accept:"*/*"}};return n||(r.mode="no-cors"),t&&(r.credentials="include"),r.priority=o?"high":"low",window.fetch?fetch(e,r):function(e,n){return new Promise(function(t,o,r){(r=new XMLHttpRequest).open("GET",e,r.withCredentials=n),r.setRequestHeader("Accept","*/*"),r.onload=function(){200===r.status?t():o()},r.send()})}(e,t)}var t,o=(t=document.createElement("link")).relList&&t.relList.supports&&t.relList.supports("prefetch")?function(e,n){return new Promise(function(t,o,r){(r=document.createElement("link")).rel="prefetch",r.href=e,n&&r.setAttribute("crossorigin","anonymous"),r.onload=t,r.onerror=o,document.head.appendChild(r)})}:n,r=window.requestIdleCallback||function(e){var n=Date.now();return setTimeout(function(){e({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-n))}})},1)},i=new Set;function c(e,n){return Array.isArray(n)?n.some(function(n){return c(e,n)}):(n.test||n).call(n,e.href,e)}function u(e,t){var r=navigator.connection;if(r){if(r.saveData)return Promise.reject(new Error("Cannot prefetch, Save-Data is enabled"));if(/2g/.test(r.effectiveType))return Promise.reject(new Error("Cannot prefetch, network conditions are poor"))}return Promise.all([].concat(e).map(function(e){return i.has(e)?[]:(i.add(e),(t?n:o)(new URL(e,location.href).toString()))}))}e.listen=function(e){if(void 0===e&&(e={}),window.IntersectionObserver){var n=function(e){e=e||1;var n=[],t=0;function o(){t<e&&n.length>0&&(n.shift()(),t++)}return[function(e){n.push(e)>1||o()},function(){t--,o()}]}(e.throttle||1/0),t=n[0],o=n[1],s=e.limit||1/0,f=e.origins||[location.hostname],a=e.ignores||[],l=e.timeoutFn||r,d=e.prefetchChunks,h=function(n){u(n,e.priority).then(o).catch(function(n){o(),e.onError&&e.onError(n)})},p=new IntersectionObserver(function(e){e.forEach(function(e){e.isIntersecting&&(p.unobserve(e=e.target),i.size<s&&t(function(){d?d(e,h):h(e.href)}))})});return l(function(){(e.el||document).querySelectorAll("a").forEach(function(e){f.length&&!f.includes(e.hostname)||c(e,a)||p.observe(e)})},{timeout:e.timeout||2e3}),function(){i.clear(),p.disconnect()}}},e.prefetch=u});