Comparing version 0.0.2 to 0.0.3
@@ -1,1 +0,1 @@ | ||
var n=function(n){return new Promise(function(t,e){var o=new XMLHttpRequest;o.open("GET",n,!0),o.withCredentials=!0,o.onload=function(){200===o.status?t():e()},o.send(null)})},t=function(n){if("undefined"==typeof document)return!1;var t=document.createElement("link");try{if(t.relList&&"function"==typeof t.relList.supports)return t.relList.supports(n)}catch(n){return!1}}("prefetch")?function(n){return new Promise(function(t,e){if("undefined"!=typeof document){var o=document.createElement("link");o.setAttribute("rel","prefetch"),o.setAttribute("href",n),o.onload=t,o.onerror=e,(document.getElementsByTagName("head")[0]||document.getElementsByName("script")[0].parentNode).appendChild(o)}else e()})}:n,e={},o=function(o,i){return new Promise(function(r){if("connection"in navigator){if(navigator.connection.effectiveType&&/\slow-2g|2g/.test(navigator.connection.effectiveType))return void r();if(navigator.connection.saveData)return void r()}e[o]?r():i&&"high"===i?function(t){return new Promise(function(e,o){void 0===self.fetch?n(t).then(function(){e()}):fetch(t,{credentials:"include"}).then(function(){e()})})}(o).then(function(){r(),e[o]=!0}).catch(function(){}):t(o).then(function(){r(),e[o]=!0}).catch(function(){})})},i=i||function(n){var t=Date.now();return setTimeout(function(){n({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-t))}})},1)};var r=function(n,t){n.forEach(function(n){o(n,t)})};module.exports=function(n){return new Promise(function(t,e){i(function(){void 0!==n.urls&&n.urls.length>0?(r(n.urls,n.priority),t(n.urls)):function(n){return new Promise(function(t,e){var o=[],i=n.querySelectorAll("a"),r=new IntersectionObserver(function(n){n.forEach(function(n){n.intersectionRatio>0&&o.push(n.target.href)}),t(o)});i.forEach(function(n){r.observe(n)})})}(n.el||document).then(function(e){r(e,n.priority),t(e)})},{timeout:(n=n||{priority:"low",timeout:2e3}).timeout})})}; | ||
var n={};function t(n){return new Promise(function(t,e){var o=new XMLHttpRequest;o.open("GET",n,!0),o.withCredentials=!0,o.onload=function(){200===o.status?t():e()},o.send(null)})}var e=function(n){if("undefined"==typeof document)return!1;var t=document.createElement("link");try{if(t.relList&&"function"==typeof t.relList.supports)return t.relList.supports(n)}catch(n){return!1}}("prefetch")?function(n){return new Promise(function(t,e){if("undefined"!=typeof document){var o=document.createElement("link");o.setAttribute("rel","prefetch"),o.setAttribute("href",n),o.onload=t,o.onerror=e,(document.getElementsByTagName("head")[0]||document.getElementsByName("script")[0].parentNode).appendChild(o)}else e()})}:t;function o(o,i){return new Promise(function(r){if("connection"in navigator){if(navigator.connection.effectiveType&&/\slow-2g|2g/.test(navigator.connection.effectiveType))return void r();if(navigator.connection.saveData)return void r()}n[o]?r():i&&"high"===i?function(n){return new Promise(function(e,o){void 0===self.fetch?t(n).then(function(){e()}):fetch(n,{credentials:"include"}).then(function(){e()})})}(o).then(function(){r(),n[o]=!0}).catch(function(){}):e(o).then(function(){r(),n[o]=!0}).catch(function(){})})}var i=i||function(n){var t=Date.now();return setTimeout(function(){n({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-t))}})},1)};var r=function(n,t){n.forEach(function(n){o(n,t)})};module.exports=function(n){return new Promise(function(t,e){((n=n||{priority:"low",timeout:2e3}).timeoutFn||i)(function(){void 0!==n.urls&&n.urls.length>0?(r(n.urls,n.priority),t(n.urls)):function(n){return new Promise(function(t,e){var o=[],i=n.querySelectorAll("a"),r=new IntersectionObserver(function(n){n.forEach(function(n){n.intersectionRatio>0&&o.push(n.target.href)}),t(o)});i.forEach(function(n){r.observe(n)})})}(n.el||document).then(function(e){r(e,n.priority),t(e)})},{timeout:n.timeout})})}; |
@@ -1,1 +0,1 @@ | ||
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):n.quicklink=e()}(this,function(){var n=function(n){return new Promise(function(e,t){var o=new XMLHttpRequest;o.open("GET",n,!0),o.withCredentials=!0,o.onload=function(){200===o.status?e():t()},o.send(null)})},e=function(n){if("undefined"==typeof document)return!1;var e=document.createElement("link");try{if(e.relList&&"function"==typeof e.relList.supports)return e.relList.supports(n)}catch(n){return!1}}("prefetch")?function(n){return new Promise(function(e,t){if("undefined"!=typeof document){var o=document.createElement("link");o.setAttribute("rel","prefetch"),o.setAttribute("href",n),o.onload=e,o.onerror=t,(document.getElementsByTagName("head")[0]||document.getElementsByName("script")[0].parentNode).appendChild(o)}else t()})}:n,t={},o=function(o,i){return new Promise(function(r){if("connection"in navigator){if(navigator.connection.effectiveType&&/\slow-2g|2g/.test(navigator.connection.effectiveType))return void r();if(navigator.connection.saveData)return void r()}t[o]?r():i&&"high"===i?function(e){return new Promise(function(t,o){void 0===self.fetch?n(e).then(function(){t()}):fetch(e,{credentials:"include"}).then(function(){t()})})}(o).then(function(){r(),t[o]=!0}).catch(function(){}):e(o).then(function(){r(),t[o]=!0}).catch(function(){})})},i=i||function(n){var e=Date.now();return setTimeout(function(){n({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-e))}})},1)};var r=function(n,e){n.forEach(function(n){o(n,e)})};return function(n){return new Promise(function(e,t){i(function(){void 0!==n.urls&&n.urls.length>0?(r(n.urls,n.priority),e(n.urls)):function(n){return new Promise(function(e,t){var o=[],i=n.querySelectorAll("a"),r=new IntersectionObserver(function(n){n.forEach(function(n){n.intersectionRatio>0&&o.push(n.target.href)}),e(o)});i.forEach(function(n){r.observe(n)})})}(n.el||document).then(function(t){r(t,n.priority),e(t)})},{timeout:(n=n||{priority:"low",timeout:2e3}).timeout})})}}); | ||
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):n.quicklink=e()}(this,function(){var n={};function e(n){return new Promise(function(e,t){var o=new XMLHttpRequest;o.open("GET",n,!0),o.withCredentials=!0,o.onload=function(){200===o.status?e():t()},o.send(null)})}var t=function(n){if("undefined"==typeof document)return!1;var e=document.createElement("link");try{if(e.relList&&"function"==typeof e.relList.supports)return e.relList.supports(n)}catch(n){return!1}}("prefetch")?function(n){return new Promise(function(e,t){if("undefined"!=typeof document){var o=document.createElement("link");o.setAttribute("rel","prefetch"),o.setAttribute("href",n),o.onload=e,o.onerror=t,(document.getElementsByTagName("head")[0]||document.getElementsByName("script")[0].parentNode).appendChild(o)}else t()})}:e;function o(o,i){return new Promise(function(r){if("connection"in navigator){if(navigator.connection.effectiveType&&/\slow-2g|2g/.test(navigator.connection.effectiveType))return void r();if(navigator.connection.saveData)return void r()}n[o]?r():i&&"high"===i?function(n){return new Promise(function(t,o){void 0===self.fetch?e(n).then(function(){t()}):fetch(n,{credentials:"include"}).then(function(){t()})})}(o).then(function(){r(),n[o]=!0}).catch(function(){}):t(o).then(function(){r(),n[o]=!0}).catch(function(){})})}var i=i||function(n){var e=Date.now();return setTimeout(function(){n({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-e))}})},1)};var r=function(n,e){n.forEach(function(n){o(n,e)})};return function(n){return new Promise(function(e,t){((n=n||{priority:"low",timeout:2e3}).timeoutFn||i)(function(){void 0!==n.urls&&n.urls.length>0?(r(n.urls,n.priority),e(n.urls)):function(n){return new Promise(function(e,t){var o=[],i=n.querySelectorAll("a"),r=new IntersectionObserver(function(n){n.forEach(function(n){n.intersectionRatio>0&&o.push(n.target.href)}),e(o)});i.forEach(function(n){r.observe(n)})})}(n.el||document).then(function(t){r(t,n.priority),e(t)})},{timeout:n.timeout})})}}); |
{ | ||
"name": "quicklink", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Faster subsequent page-loads by prefetching in-viewport links during idle time", | ||
@@ -13,9 +13,10 @@ "main": "dist/quicklink.js", | ||
"scripts": { | ||
"lint": "eslint src/*.mjs test/*.js", | ||
"lint-fix": "eslint src/*.mjs test/*.js --fix", | ||
"server": "http-server .", | ||
"lint": "eslint src/*.mjs test/*.js demos/*.js", | ||
"lint-fix": "eslint src/*.mjs test/*.js --fix demos/*.js", | ||
"start": "http-server .", | ||
"test": "npm run build && mocha test/bootstrap.js --recursive test", | ||
"build": "microbundle src/index.mjs --no-sourcemap", | ||
"prepare": "npm run -s build", | ||
"release": "cross-var npm run build -s && cross-var git commit -am $npm_package_version && cross-var git tag $npm_package_version && git push && git push --tags && npm publish --access public" | ||
"bundlesize": "bundlesize", | ||
"release": "cross-var npm run build -s && cross-var git commit -am $npm_package_version && cross-var git tag $npm_package_version && git push && git push --tags" | ||
}, | ||
@@ -32,2 +33,3 @@ "keywords": [ | ||
"babel-preset-env": "^1.7.0", | ||
"bundlesize": "^0.17.0", | ||
"chai": "^4.2.0", | ||
@@ -42,2 +44,8 @@ "cross-var": "^1.1.0", | ||
}, | ||
"bundlesize": [ | ||
{ | ||
"path": "./dist/*.js", | ||
"maxSize": "2 kB" | ||
} | ||
], | ||
"dependencies": { | ||
@@ -44,0 +52,0 @@ "puppeteer": "^1.10.0" |
@@ -8,7 +8,11 @@ # quicklink | ||
* **Detects links within the viewport** (using `IntersectionObsever`) | ||
* **Waits until the browser is idle** (using `requestIdleCallback`) | ||
* **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)) | ||
* **Checks if the user isn't on a slow connection** (using `navigator.connection.effectiveType`) or has data-saver enabled (using `navigator.connection.saveData`) | ||
* **Prefetches URLs to the links** (using `<link rel=prefetch>` or XHR). Provides some control over the request priority (can switch to `fetch()` if supported). | ||
* **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). | ||
## Why | ||
This project aims to be a drop-in solution for sites to prefetch links based on what is in the user's viewport. It also aims to be small (**< 1KB minified/gzipped**). | ||
## Installation | ||
@@ -22,2 +26,4 @@ | ||
You can also grab `quicklink` from [unpkg.com/quicklink](https://unpkg.com/quicklink). | ||
## Usage | ||
@@ -32,3 +38,3 @@ | ||
<script src="dist/quicklink.js"></script> | ||
<!-- Initialize (you can do this to whenever you want) --> | ||
<!-- Initialize (you can do this whenever you want) --> | ||
<script> | ||
@@ -39,2 +45,12 @@ quicklink(); | ||
For example, you can initialize after the `load` event fires: | ||
```html | ||
<script> | ||
window.addEventListener('load', () =>{ | ||
quicklink(); | ||
}); | ||
</script> | ||
``` | ||
ES Module import: | ||
@@ -60,2 +76,3 @@ | ||
* `timeout`: Integer for the `requestIdleCallback` timeout. A time in milliseconds by which the browser must execute prefetching. Defaults to 2 seconds. | ||
* `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) | ||
@@ -78,2 +95,4 @@ | ||
Alternatively, see the [Intersection Observer polyfill](https://github.com/w3c/IntersectionObserver/tree/master/polyfill). | ||
## Recipes | ||
@@ -121,2 +140,16 @@ | ||
## Browser support | ||
The prefetching provided by `quicklink` can be viewed as a [progressive enhancement](https://www.smashingmagazine.com/2009/04/progressive-enhancement-what-it-is-and-how-to-use-it/). Cross-browser support is as follows: | ||
* Without polyfills: Chrome, Firefox, Edge, Opera, Android Browser, Samsung Internet. | ||
* With [Intersection Observer polyfill](https://github.com/w3c/IntersectionObserver/tree/master/polyfill) ~6KB gzipped/minified: Safari, IE9+ | ||
Certain features have layered support. If opting for `{priority:'high'}` and `fetch()` isn't available, XHR will be used instead. | ||
## 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. | ||
## License | ||
@@ -123,0 +156,0 @@ |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
222437
29
434
152
10
5