Faster subsequent page-loads by prefetching in-viewport links during idle time.
Introduction to the
Quicklink is a javascript library developed by Google that preloads resources to make subsequent web pages easier to access.
How it works
Quicklink attempts to make navigations to subsequent pages load faster. It:
Quicklink tries to make navigation to subsequent pages load faster
Detects links within the viewport (using Intersection Observer)
Waits until the browser is idle (using requestIdleCallback)
Checks if the user isn’t on a slow connection (using
navigator.connection.effectiveType
) or has data-saver enabled (usingnavigator.connection.saveData
)Prefetches URLs to the links (using
<link rel=prefetch>
or XHR). Provides some control over the request priority (can switch tofetch()
if supported).
Quicklink on Github. It introduces quickLink’s four features, each of which is described below.
1. Detects links within the viewport
Examine the links inside the viewport using the Intersection Observer. The Intersection Observer API provides a way to asynchronously observe changes in the Intersection of a target element and a top-level document viewport.
Usage:
const observer = new IntersectionObserver(callback, option?) ; // eg: Const observer = new IntersectionObserver(entries=>{endies.foreach (entry=>{const link = entry.target; console.log(link) }) }); Array.from(document.querySelectorAll("a"),link=>{ observer.observe(link); })Copy the code
See Intersection Observer API-mDN for details
2. Waits until the browser is idle
Wait until the browser is idle to do this without affecting the user’s current page experience. It is implemented via requestIdleCallback.
* * * * window. RequestIdleCallback () method will be called function in browser free time line. This enables developers to perform background and low-priority work on the main event loop without affecting the delay of critical events such as animations and input responses.
var handle = window.requestIdleCallback(callback[, options])
Copy the code
For details, see requesTIDlecallback-mDN
3. Checks if the user isn’t on a slow connection
Check whether the user is on a slow connection (using the navigator. Connection. EffectiveType for current network type) or enabled data protection program (use The navigator. Connection. SaveData user is set up to reduce the data on the user agent to use option). Typical use of traffic in exchange for user experience optimization.
The use of specific methods refer to: the navigator. Connection. EffectiveType – MDN and NetworkInformation. SaveData – MDN
4. Prefetches URLs to the links
Preload the URL link. By using or XHR. Provide some control over the priority of requests (switch to FETCH if supported). Resources Hints contains the following:
- prefetch
- preconnect
- preload
- prerender
The source code interpretation
Quicklink loading process:
-
Check whether the link in the web page is displayed in the viewport, wait until the link is displayed, and go to Step 2.
-
Wait until the browser is idle and go to 3.
-
Check whether the current network connection is 2G. If yes, stop the operation. If no, go to Step 4.
-
Preloaded links point to resources.
Find the entrance through its use method, click to see the specific use method.
The entry function
Prefetch an array of urls if the user’s valid connection type and data protector preferences indicate that this would be useful. By default, view the in-viewport link for “Document”. You can also work with supplied DOM elements or static URL arrays.
/ SRC /index.mjs
/* Parameter information * @param {Object} options - Configuration options for QuickLink * @param {Object} [options.el] -dom element to prefetch in-viewport links of * @param {Boolean} [options.priority] - Attempt higher priority fetch (low or high) * @param {Array} [options.origins] - Allowed origins to prefetch (empty allows all) * @param {Array|RegExp|Function} [options.ignores] - Custom filter(s) that run after origin checks * @param {Number} [options.timeout] - Timeout after which prefetching will occur * @param {Number} [options.throttle] - The concurrency limit for prefetching * @param {Number} [options.limit] - The total number of prefetches to allow * @param {Function} [options.timeoutFn] - Custom timeout function * @param {Function} [options.onError] - Error handler for failed `prefetch` requests */ export function Listen (options) {} / / callback function timeoutFn (() = > {(options. El | | document). QuerySelectorAll (' a '). The forEach (link = > {the if (! allowed.length || allowed.includes(link.hostname)) { isIgnored(link, ignores) || observer.observe(link); }}); }, { timeout: options.timeout || 2000 });Copy the code
Initialize the parameters first, combining the default configuration with the set configuration using the object. assign function.
Check that link appears in the window
Quicklink monitors node elements through observer.observe(link). Observer is an instance of IntersectionObserver, which monitors link appearing in the window. If the conditions are met, the prefetch method is called to create a resource link.
/ SRC /index.mjs
const observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { observer.unobserve(entry = entry.target); // Do not prefetch if will match/exceed limit Size < limit) {toAdd(() => {prefetch(entry.href, options.priority).then(isDone).catch(err => { isDone(); if (options.onError) options.onError(err); }); }); }}}); });Copy the code
Prefetch function
Prefetch a given URL using an optional preferred fetch priority. Return a Promise object that loads multiple link resources using the promise. all function.
/ SRC /index.mjs
@param {String} url - the url to fetch * @param {Boolean} [isPriority] -if is "high" priority * @param {Object} [conn] - navigator.connection (internal) * @return {Object} a Promise */ const toPrefetch = new Set(); export function prefetch(url, isPriority, conn) { if (conn = navigator.connection) { if (conn.saveData || /2g/.test(conn.effectiveType)) return; } return Promise.all( [].concat(url).map(str => { if (! toPrefetch.has(str)) { toPrefetch.add(str); Return (isPriority? priority : supported)( new URL(str, location.href).toString() ); }})); }Copy the code
An asynchronous function
If the browser supports requestIdleCallback, the native function is used, if not, ployfill is done using the setTimeout function.
/ SRC /request-idle-callback.mjs
const requestIdleCallback = window.requestIdleCallback || function (cb) { const start = Date.now(); return setTimeout(function () { cb({ didTimeout: false, timeRemaining: function () { return Math.max(0, 50 - (Date.now() - start)); }}); }, 1); }; export default requestIdleCallback;Copy the code
The resource request
Quicklink has three strategies for preloading resources
Source path: / SRC /prefetch. MJS
1. prefetch
function viaDOM(url) {
return new Promise((res, rej, link) => {
link = document.createElement(`link`);
link.rel = `prefetch`;
link.href = url;
link.onload = res;
link.onerror = rej;
document.head.appendChild(link);
});
};
Copy the code
2. XHR
function viaXHR(url) {
return new Promise((res, rej, req) => {
req = new XMLHttpRequest();
req.open(`GET`, url, req.withCredentials=true);
req.onload = () => {
(req.status === 200) ? res() : rej();
};
req.send();
});
}
Copy the code
3. fetch
export function priority(url) {
return window.fetch ? fetch(url, {credentials: `include`}) : viaXHR(url);
}
Copy the code
The preloading policy is degraded
Function hasPrefetch(link) {link = document.createElement('link'); return link.relList && link.relList.supports && link.relList.supports('prefetch'); } export const supported = hasPrefetch() ? viaDOM : viaXHR;Copy the code
conclusion
Quicklink is a means of front-end performance optimization that speeds up a user’s first visit to a sequenced page. It detects the scrolling of the page, can preload the page links that appear in the window, preload the resources of the next page, and improve the user experience. It is a means to exchange user network traffic for experience. We can also combine the user behavior preference of the website and only preload the pages with high probability. At the same time, I am familiar with the optimization of front-end loading resources through its source code. PWA technology is to optimize the user’s secondary access efficiency and experience.
Write in the last
Share my possession of TS tutorials, from zero to high order all series, click a link, 0 RMB for www.yidengxuetang.com/pub-page/in…