Comparing version 0.0.4 to 0.1.0
@@ -1,1 +0,1 @@ | ||
var t={};function e(t){return new Promise(function(e,n){var r=new XMLHttpRequest;r.open("GET",t,!0),r.withCredentials=!0,r.onload=function(){200===r.status?e():n()},r.send(null)})}var n=function(t){if("undefined"==typeof document)return!1;var e=document.createElement("link");try{if(e.relList&&"function"==typeof e.relList.supports)return e.relList.supports(t)}catch(t){return!1}}("prefetch")?function(t){return new Promise(function(e,n){if("undefined"!=typeof document){var r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",t),r.onload=e,r.onerror=n,(document.getElementsByTagName("head")[0]||document.getElementsByName("script")[0].parentNode).appendChild(r)}else n()})}:e;function r(r,i){return new Promise(function(o,u){if(t[r])return o();if("connection"in navigator){if((navigator.connection.effectiveType||"").includes("2g"))return o();if(navigator.connection.saveData)return o()}var c=function(){try{return o()}catch(t){return u(t)}},a=function(t){try{return c()}catch(t){return u(t)}};try{return i&&"high"===i?function(t){return void 0===self.fetch?e(t):fetch(t,{credentials:"include"})}(r).then(function(t){try{return f.call(this)}catch(t){return a()}}.bind(this),a):n(r).then(function(t){try{return f.call(this)}catch(t){return a()}}.bind(this),a);function f(){return t[r]=!0,c()}}catch(t){a()}})}var i=i||function(t){var e=Date.now();return setTimeout(function(){t({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-e))}})},1)},o=new Map,u=new IntersectionObserver(function(t){t.filter(function(t){return t.isIntersecting}).forEach(function(t){var e=t.target.href;o.has(e)&&o.get(e).call(null)})});module.exports=function(t){(t=Object.assign({},{priority:"low",timeout:2e3,timeoutFn:i,el:document},t)).timeoutFn(function(){if(t.urls)t.urls.forEach(function(e){return r(e,t.priority)});else{var e=Array.from(t.el.querySelectorAll("a"));e.forEach(function(t){return u.observe(t)}),e.map(function(t){return t.href}).forEach(function(e){o.set(e,function(){o.delete(e),r(e,t.priority)})})}},{timeout:t.timeout})}; | ||
var e={};function t(e){return new Promise(function(t,n){var r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=function(){200===r.status?t():n()},r.send()})}var n=function(e){if("undefined"==typeof document)return!1;try{var t=document.createElement("link");if(t.relList&&"function"==typeof t.relList.supports)return t.relList.supports(e)}catch(e){return!1}}("prefetch")?function(e){return new Promise(function(t,n){var r=document.createElement("link");r.rel="prefetch",r.href=e,r.onload=t,r.onerror=n,(document.head||document.querySelector("script".parentNode)).appendChild(r)})}:t;function r(r,i){if(!e[r]){if("connection"in navigator){if((navigator.connection.effectiveType||"").includes("2g"))return;if(navigator.connection.saveData)return}return(i?function(e){return null==self.fetch?t(e):fetch(e,{credentials:"include"})}:n)(r).then(function(){e[r]=!0})}}var i=i||function(e){var t=Date.now();return setTimeout(function(){e({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-t))}})},1)},o=new Set,u=new IntersectionObserver(function(e){e.forEach(function(e){if(e.isIntersecting){var t=e.target.href;o.has(t)&&c(t)}})});function c(e){o.delete(e),r(e,u.priority)}module.exports=function(e){e=Object.assign({timeout:2e3,priority:!1,timeoutFn:i,el:document},e),u.priority=e.priority,e.timeoutFn(function(){e.urls?e.urls.forEach(c):Array.from(e.el.querySelectorAll("a"),function(e){u.observe(e),o.add(e.href)})},{timeout:e.timeout})}; |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.quicklink=e()}(this,function(){var t={};function e(t){return new Promise(function(e,n){var r=new XMLHttpRequest;r.open("GET",t,!0),r.withCredentials=!0,r.onload=function(){200===r.status?e():n()},r.send(null)})}var n=function(t){if("undefined"==typeof document)return!1;var e=document.createElement("link");try{if(e.relList&&"function"==typeof e.relList.supports)return e.relList.supports(t)}catch(t){return!1}}("prefetch")?function(t){return new Promise(function(e,n){if("undefined"!=typeof document){var r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",t),r.onload=e,r.onerror=n,(document.getElementsByTagName("head")[0]||document.getElementsByName("script")[0].parentNode).appendChild(r)}else n()})}:e;function r(r,i){return new Promise(function(o,u){if(t[r])return o();if("connection"in navigator){if((navigator.connection.effectiveType||"").includes("2g"))return o();if(navigator.connection.saveData)return o()}var c=function(){try{return o()}catch(t){return u(t)}},f=function(t){try{return c()}catch(t){return u(t)}};try{return i&&"high"===i?function(t){return void 0===self.fetch?e(t):fetch(t,{credentials:"include"})}(r).then(function(t){try{return a.call(this)}catch(t){return f()}}.bind(this),f):n(r).then(function(t){try{return a.call(this)}catch(t){return f()}}.bind(this),f);function a(){return t[r]=!0,c()}}catch(t){f()}})}var i=i||function(t){var e=Date.now();return setTimeout(function(){t({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-e))}})},1)},o=new Map,u=new IntersectionObserver(function(t){t.filter(function(t){return t.isIntersecting}).forEach(function(t){var e=t.target.href;o.has(e)&&o.get(e).call(null)})});return function(t){(t=Object.assign({},{priority:"low",timeout:2e3,timeoutFn:i,el:document},t)).timeoutFn(function(){if(t.urls)t.urls.forEach(function(e){return r(e,t.priority)});else{var e=Array.from(t.el.querySelectorAll("a"));e.forEach(function(t){return u.observe(t)}),e.map(function(t){return t.href}).forEach(function(e){o.set(e,function(){o.delete(e),r(e,t.priority)})})}},{timeout:t.timeout})}}); | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):e.quicklink=n()}(this,function(){var e={};function n(e){return new Promise(function(n,t){var r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=function(){200===r.status?n():t()},r.send()})}var t=function(e){if("undefined"==typeof document)return!1;try{var n=document.createElement("link");if(n.relList&&"function"==typeof n.relList.supports)return n.relList.supports(e)}catch(e){return!1}}("prefetch")?function(e){return new Promise(function(n,t){var r=document.createElement("link");r.rel="prefetch",r.href=e,r.onload=n,r.onerror=t,(document.head||document.querySelector("script".parentNode)).appendChild(r)})}:n;function r(r,i){if(!e[r]){if("connection"in navigator){if((navigator.connection.effectiveType||"").includes("2g"))return;if(navigator.connection.saveData)return}return(i?function(e){return null==self.fetch?n(e):fetch(e,{credentials:"include"})}:t)(r).then(function(){e[r]=!0})}}var i=i||function(e){var n=Date.now();return setTimeout(function(){e({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-n))}})},1)},o=new Set,u=new IntersectionObserver(function(e){e.forEach(function(e){if(e.isIntersecting){var n=e.target.href;o.has(n)&&c(n)}})});function c(e){o.delete(e),r(e,u.priority)}return function(e){e=Object.assign({timeout:2e3,priority:!1,timeoutFn:i,el:document},e),u.priority=e.priority,e.timeoutFn(function(){e.urls?e.urls.forEach(c):Array.from(e.el.querySelectorAll("a"),function(e){u.observe(e),o.add(e.href)})},{timeout:e.timeout})}}); |
{ | ||
"name": "quicklink", | ||
"version": "0.0.4", | ||
"version": "0.1.0", | ||
"description": "Faster subsequent page-loads by prefetching in-viewport links during idle time", | ||
@@ -40,3 +40,4 @@ "main": "dist/quicklink.js", | ||
"microbundle": "^0.7.0", | ||
"mocha": "^5.2.0" | ||
"mocha": "^5.2.0", | ||
"puppeteer": "^1.10.0" | ||
}, | ||
@@ -48,6 +49,3 @@ "bundlesize": [ | ||
} | ||
], | ||
"dependencies": { | ||
"puppeteer": "^1.10.0" | ||
} | ||
] | ||
} |
@@ -0,1 +1,10 @@ | ||
<p align="center"> | ||
<img src="https://i.imgur.com/NVRZLHv.png" width="640" alt="quicklink"> | ||
<br> | ||
<a href="https://www.npmjs.org/package/quicklink"><img src="https://img.shields.io/npm/v/quicklink.svg?style=flat" alt="npm"></a> | ||
<a href="https://unpkg.com/quicklink"><img src="https://img.badgesize.io/https://unpkg.com/quicklink/dist/quicklink.js?compression=gzip" alt="gzip size"></a> | ||
<a href="https://www.npmjs.com/package/quicklink"><img src="https://img.shields.io/npm/dt/quicklink.svg" alt="downloads" ></a> | ||
<a href="https://travis-ci.org/GoogleChromeLabs/quicklink"><img src="https://travis-ci.org/GoogleChromeLabs/quicklink.svg?branch=master" alt="travis"></a> | ||
</p> | ||
# quicklink | ||
@@ -9,3 +18,3 @@ > Faster subsequent page-loads by prefetching in-viewport links during idle time | ||
* **Detects links within the viewport** (using [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)) | ||
* **Waits until the browser is idle** (using [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback)) or **waits until network activity is idle** (using [networkIdleCallback](https://github.com/pastelsky/network-idle-callback)) | ||
* **Waits until the browser is idle** (using [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback)) | ||
* **Checks if the user isn't on a slow connection** (using `navigator.connection.effectiveType`) or has data-saver enabled (using `navigator.connection.saveData`) | ||
@@ -74,6 +83,6 @@ * **Prefetches URLs to the links** (using [`<link rel=prefetch>`](https://www.w3.org/TR/resource-hints/#prefetch) or XHR). Provides some control over the request priority (can switch to `fetch()` if supported). | ||
* `timeoutFn`: Function for specifying a timeout. Defaults to `requestIdleCallback`. Can also be swapped out for a custom function like [networkIdleCallback](https://github.com/pastelsky/network-idle-callback) (see demos) | ||
* `priority`: String specifying preferred priority for fetches. Defaults to `low`. `high` will attempt to use the `fetch()` API where supported (rather than rel=prefetch) | ||
* `priority`: Boolean specifying preferred priority for fetches. Defaults to `false`. `true` will attempt to use the `fetch()` API where supported (rather than rel=prefetch) | ||
TODO: | ||
* Explore detecting file-extension of resources and using [rel=preload](https://w3c.github.io/preload/) for `high` priority fetches | ||
* Explore detecting file-extension of resources and using [rel=preload](https://w3c.github.io/preload/) for high priority fetches | ||
* Explore using [Priority Hints](https://github.com/WICG/priority-hints) for importance hinting | ||
@@ -129,7 +138,6 @@ | ||
Defaults to low-priority (`rel=prefetch` or XHR). For high-priority, | ||
attempts to use `fetch()` or falls back to XHR. | ||
Defaults to low-priority (`rel=prefetch` or XHR). For high-priority (`priority: true`), attempts to use `fetch()` or falls back to XHR. | ||
```js | ||
quicklink({ priority: 'high' }); | ||
quicklink({ priority: true }); | ||
``` | ||
@@ -144,8 +152,22 @@ | ||
Certain features have layered support. If opting for `{priority:'high'}` and `fetch()` isn't available, XHR will be used instead. | ||
Certain features have layered support. If opting for `{priority: true}` and `fetch()` isn't available, XHR will be used instead. | ||
## Using the prefetcher directly | ||
`quicklink` includes a prefetcher that can be individually imported for use in other projects. After installing `quicklink` as a dependency, you can use it as follows: | ||
```html | ||
<script type="module"> | ||
import prefetch from '../src/prefetch.mjs'; | ||
const urls = ['1.html', '2.html']; | ||
const promises = urls.map(url => prefetch(url)); | ||
Promise.all(promises); | ||
</script> | ||
``` | ||
## Related projects | ||
* Using [Gatsby](https://gatsbyjs.org)? You already get most of this for free baked in. It uses `Intersection Observer` to prefetch all of the links that are in view and provided heavy inspiration for this project. | ||
* Want a more data-driven approach? See [Guess.js](https://guessjs.com). It uses analytics and machine-learning to prefetch resources based on how users navigate your site. It also has plugins for Webpack and Gatsby. | ||
* Want a more data-driven approach? See [Guess.js](https://guessjs.com). It uses analytics and machine-learning to prefetch resources based on how users navigate your site. It also has plugins for [Webpack](https://www.npmjs.com/package/guess-webpack) and [Gatsby](https://www.gatsbyjs.org/docs/optimize-prefetching-with-guessjs/). | ||
@@ -152,0 +174,0 @@ ## License |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
222943
0
30
174
11
393
- Removedpuppeteer@^1.10.0
- Removedagent-base@4.3.0(transitive)
- Removedasync-limiter@1.0.1(transitive)
- Removedbalanced-match@1.0.2(transitive)
- Removedbrace-expansion@1.1.11(transitive)
- Removedbuffer-crc32@0.2.13(transitive)
- Removedbuffer-from@1.1.2(transitive)
- Removedconcat-map@0.0.1(transitive)
- Removedconcat-stream@1.6.2(transitive)
- Removedcore-util-is@1.0.3(transitive)
- Removeddebug@2.6.93.2.74.4.0(transitive)
- Removedes6-promise@4.2.8(transitive)
- Removedes6-promisify@5.0.0(transitive)
- Removedextract-zip@1.7.0(transitive)
- Removedfd-slicer@1.1.0(transitive)
- Removedfs.realpath@1.0.0(transitive)
- Removedglob@7.2.3(transitive)
- Removedhttps-proxy-agent@2.2.4(transitive)
- Removedinflight@1.0.6(transitive)
- Removedinherits@2.0.4(transitive)
- Removedisarray@1.0.0(transitive)
- Removedmime@2.6.0(transitive)
- Removedminimatch@3.1.2(transitive)
- Removedminimist@1.2.8(transitive)
- Removedmkdirp@0.5.6(transitive)
- Removedms@2.0.02.1.3(transitive)
- Removedonce@1.4.0(transitive)
- Removedpath-is-absolute@1.0.1(transitive)
- Removedpend@1.2.0(transitive)
- Removedprocess-nextick-args@2.0.1(transitive)
- Removedprogress@2.0.3(transitive)
- Removedproxy-from-env@1.1.0(transitive)
- Removedpuppeteer@1.20.0(transitive)
- Removedreadable-stream@2.3.8(transitive)
- Removedrimraf@2.7.1(transitive)
- Removedsafe-buffer@5.1.2(transitive)
- Removedstring_decoder@1.1.1(transitive)
- Removedtypedarray@0.0.6(transitive)
- Removedutil-deprecate@1.0.2(transitive)
- Removedwrappy@1.0.2(transitive)
- Removedws@6.2.3(transitive)
- Removedyauzl@2.10.0(transitive)