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 (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).

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:

  1. Check whether the link in the web page is displayed in the viewport, wait until the link is displayed, and go to Step 2.

  2. Wait until the browser is idle and go to 3.

  3. Check whether the current network connection is 2G. If yes, stop the operation. If no, go to Step 4.

  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…