quicklink
Version:
Faster subsequent page-loads by prefetching in-viewport links during idle time
2 lines (1 loc) • 5.67 kB
JavaScript
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((e="undefined"!=typeof globalThis?globalThis:e||self).quicklink={})}(this,function(e){"use strict";function r(e,r){(null==r||r>e.length)&&(r=e.length);for(var n=0,t=Array(r);n<r;n++)t[n]=e[n];return t}function n(e,n){var t="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(t)return(t=t.call(e)).next.bind(t);if(Array.isArray(e)||(t=function(e,n){if(e){if("string"==typeof e)return r(e,n);var t={}.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?r(e,n):void 0}}(e))||n){t&&(e=t);var o=0;return function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function t(e,r,n,t){var o={headers:{accept:"*/*"}};return r||(o.mode="no-cors"),n&&(o.credentials="include"),o.priority=t?"high":"low",window.fetch?fetch(e,o):function(e,r){return new Promise(function(n,t,o){(o=new XMLHttpRequest).open("GET",e,o.withCredentials=r),o.setRequestHeader("Accept","*/*"),o.onload=function(){200===o.status?n():t()},o.send()})}(e,n)}var o,i=(o=document.createElement("link")).relList&&o.relList.supports&&o.relList.supports("prefetch")?function(e,r){return new Promise(function(n,t,o){(o=document.createElement("link")).rel="prefetch",o.href=e,r&&o.setAttribute("crossorigin","anonymous"),o.onload=n,o.onerror=t,document.head.append(o)})}:t,a=window.requestIdleCallback||function(e){var r=Date.now();return setTimeout(function(){e({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-r))}})},1)},c=new Set,s=new Set,u=!1;function l(e,r){return Array.isArray(r)?r.some(function(r){return l(e,r)}):(r.test||r).call(r,e.href,e)}function f(e){return!e||(e.saveData?new Error("Save-Data is enabled"):!/2g/.test(e.effectiveType)||new Error("network conditions are poor"))}function d(e,r,o,a,l){var d=f(navigator.connection);return d instanceof Error?Promise.reject(new Error("Cannot prefetch, "+d.message)):(s.size>0&&!u&&console.warn("[Warning] You are using both prefetching and prerendering on the same document"),Promise.all([e].flat().map(function(e){return c.has(e)?[]:(c.add(e),function(e,r,t){for(var o=arguments.length,i=new Array(o>3?o-3:0),a=3;a<o;a++)i[a-3]=arguments[a];if(!t)return e.apply(void 0,[r].concat(i));for(var c,s=document.querySelectorAll('a[href="'+r+'"]'),u=new Map,l=function(){var n=c.value,t=function(){var a=setTimeout(function(){return n.removeEventListener("mouseenter",t),n.removeEventListener("mouseleave",o),e.apply(void 0,[r].concat(i))},200);u.set(n,a)},o=function(){var e=u.get(n);e&&(clearTimeout(e),u.delete(n))};n.addEventListener("mouseenter",t),n.addEventListener("mouseleave",o)},f=n(s);!(c=f()).done;)l()}(r?t:i,new URL(e,location.href).toString(),l,o,a,r))})))}function h(e,r){void 0===r&&(r="immediate"),e=[e].flat();var t=f(navigator.connection);if(t instanceof Error)return Promise.reject(new Error("Cannot prerender, "+t.message));if(!HTMLScriptElement.supports("speculationrules"))return d(e,!0,!1,!1,"moderate"===r||"conservative"===r),Promise.reject(new Error("This browser does not support the speculation rules API. Falling back to prefetch."));for(var o,i=n(e);!(o=i()).done;){var a=o.value;s.add(a)}c.size>0&&!u&&console.warn("[Warning] You are using both prefetching and prerendering on the same document");var l=function(e,r){var t=new Map;try{for(var o,i=n(e);!(o=i()).done;){var a=o.value,c=document.createElement("script");c.type="speculationrules",c.text=JSON.stringify({prerender:[{source:"list",urls:[a],eagerness:r}]}),document.head.append(c),t.set(a,c)}}catch(e){return e}return t}(e,r);return l.size>0?Promise.resolve(l):Promise.reject(l)}e.listen=function(e){if(void 0===e&&(e={}),!window.IntersectionObserver||!("isIntersecting"in IntersectionObserverEntry.prototype))return function(){};var r=function(e){e=e||1;var r=[],n=0;function t(){n<e&&r.length>0&&(r.shift()(),n++)}return[function(e){r.push(e)>1||t()},function(){n--,t()}]}(e.throttle||1/0),t=r[0],o=r[1],i=e.limit||1/0,f=e.threshold||0,v=e.origins||[location.hostname],m=e.ignores||[],p=e.delay||0,g=new Map,w=new Map,y=e.timeoutFn||a,b="function"==typeof e.hrefFn&&e.hrefFn,E=e.prerender||!1;u=e.prerenderAndPrefetch||!1;var A=new IntersectionObserver(function(r){for(var a,l=function(){var r=a.value,l=g.get(r.target.href)||new Set;g.set(r.target.href,l),r.isIntersecting?(r=r.target,l.add(r),function(e,r){r?setTimeout(e,r):e()}(function(){l&&l.size&&(E||u||A.unobserve(r),(u||E)&&s.size<i&&!w.has(r.href)?h(b?b(r):r.href,e.eagerness).then(function(e){for(var r,t=n(e);!(r=t()).done;){var o=r.value,i=o[0],a=o[1];w.set(i,a)}}).catch(function(r){if(!e.onError)throw r;e.onError(r)}):c.size<i&&!E&&t(function(){d(b?b(r):r.href,e.priority,e.checkAccessControlAllowOrigin,e.checkAccessControlAllowCredentials,e.onlyOnMouseover).then(o).catch(function(r){o(),e.onError&&e.onError(r)})}))},p)):(r=r.target,l.delete(r),w.has(r.href)&&w.set(function(e,r){var n=e.get(r);try{n.remove(),e.delete(r)}catch(e){return e}return e}(w,r.href)))},f=n(r);!(a=f()).done;)l()},{threshold:f});return y(function(){for(var r,t=n(e.el&&e.el.length>0&&"A"===e.el[0].nodeName?e.el:(e.el||document).querySelectorAll("a"));!(r=t()).done;){var o=r.value;v.length&&!v.includes(o.hostname)||l(o,m)||A.observe(o)}},{timeout:e.timeout||2e3}),function(){c.clear(),A.disconnect()}},e.prefetch=d,e.prerender=h});