Quicklink

repository·main·Indexed 11 days ago

https://github.com/googlechromelabs/quicklink

A lightweight library (< 2KB) that improves perceived performance by prefetching or prerendering links in the user's viewport during browser idle time. Version 3.0.2 supports the Speculation Rules API for prerendering, integrates with Workbox runtime caching, and provides a Higher-Order Component (HOC) for React SPAs.

Tokens
6.4K
Snippets
23
Records
31
Agent score
95%

What's inside Quicklink

  1. Avoid prefetching ads

    main

    To prevent inflating Ad CTR (click-through-rate) by unintentionally counting prefetch requests as clicks, follow these guidelines:

    1. If ads are in iframes: Quicklink will not prefetch them by default because the lookup is restricted to the top-level origin.
    2. If ads are outside iframes (same-origin): You must explicitly tell Quicklink to avoid them by adding the ad-link URL, subpath, or the containing element to the ignores list in quicklink.listen().
  2. Prefetch JavaScript chunks in Single-Page Apps (SPAs)

    main

    In a Single-Page Application (SPA), links typically navigate between routes using JavaScript rather than requesting new HTML documents. To make Quicklink work effectively in this environment, you must provide an hrefFn option. This function maps a standard link's href to the actual URL of the JavaScript chunk required for that route. This ensures Quicklink prefetches the necessary code instead of attempting to fetch an HTML document that won't be used for navigation.

    // Example pattern for an SPA
    quicklink.listen({
      hrefFn: (url) => {
        // Map the route URL to the specific JS chunk URL
        return `/chunks/${url}.js`;
      }
    });
  3. How quicklink works

    main

    quicklink speeds up subsequent page loads by prefetching or prerendering links that are currently in the user's viewport during browser idle time.

    It follows these steps:

    1. Detects links in viewport: Uses the Intersection Observer API.
    2. Waits for idle time: Uses requestIdleCallback to ensure prefetching doesn't interfere with critical tasks.
    3. Checks connection quality: Uses navigator.connection.effectiveType and navigator.connection.saveData to avoid prefetching on slow connections or when data-saver is enabled.
    4. Executes prefetch/prerender: Uses <link rel=prefetch> or XHR for prefetching, or the Speculation Rules API for prerendering. It can also use fetch() for high-priority requests if supported.
  4. Use quicklink in Multi-page apps

    main

    You can initialize quicklink to automatically prefetch in-viewport links during idle time.

    Using via Script Tag (UMD)

    Include the script from the dist folder and call quicklink.listen().

    <script src="dist/quicklink.umd.js"></script>
    <script>
      quicklink.listen();
    </script>

    It is recommended to initialize after the load event:

    <script>
      window.addEventListener('load', () => {
        quicklink.listen();
      });
    </script>

    Using via ES Modules

    For modern browsers, use the smaller quicklink.modern.mjs build which lacks legacy transforms:

    import {listen, prefetch} from 'quicklink/dist/quicklink.modern.mjs';

    Standard ES Module import:

    import {listen, prefetch} from 'quicklink';
    <!-- Include quicklink from dist -->
    <script src="dist/quicklink.umd.js"></script>
    <!-- Initialize (you can do this whenever you want) -->
    <script>
      quicklink.listen();
    </script>
  5. Install and use quicklink with React (Single Page Apps)

    main

    For React SPAs, quicklink provides a Higher-Order Component (HOC) to wrap routes. This requires a route manifest to function correctly.

    1. Installation

    Install quicklink and webpack-route-manifest as dev dependencies:

    npm install quicklink webpack-route-manifest --save-dev

    2. Configuration

    Configure webpack-route-manifest in your project to generate a rmanifest.json file. This file maps routes and chunks. It can be accessed via a URL (site_url/rmanifest.json) or the window.__rmanifest object.

    3. Usage

    Wrap your route components with the withQuicklink() HOC.

    import {withQuicklink} from 'quicklink/dist/react/hoc.js';
    
    const options = {
      origins: [],
    };
    
    <Suspense fallback={<div />}>
      <Route path='/' exact component={withQuicklink(Home, options)} />
      <Route path='/blog' exact component={withQuicklink(Blog, options)} />
      <Route path='/blog/:title' component={withQuicklink(Article, options)} />
      <Route path='/about' exact component={withQuicklink(About, options)} />
    </Suspense>;
  6. Integrate Quicklink with Workbox runtime caching

    main
    Quicklink works by triggering <link rel="prefetch"> tags for links in the viewport. To layer Workbox runtime caching on top of Quicklink, register a service worker that is configured to cache navigations or static assets. Because Quicklink only initiates the prefetch request, any caching strategy defined in your Workbox service worker will be applied to those prefetched requests as expected.
  7. How prefetching and prerendering work together

    main

    Quicklink supports three primary modes of operation:

    1. Prefetching (Default): Downloads the resource in the background. This is widely supported and uses standard fetch mechanisms.
    2. Prerendering: Uses the Speculation Rules API to actually render the page in a hidden state, making navigation nearly instantaneous. This is used when options.prerender is true.
    3. Hybrid Mode: When options.prerenderAndPrefetch is true, the library attempts to use both.

    Warning: If you call prefetch() and prerender() manually on the same document without setting prerenderAndPrefetch: true, a warning will be logged to the console: [Warning] You are using both prefetching and prerendering on the same document.

  8. Define custom filters with FilterMatcher

    main

    The ignores option accepts FilterMatcher values to exclude specific links from prefetching. A matcher can be:

    1. RegExp: Tests against the full URL (node.href).
    2. Function: Receives (href: string, node: Element) as arguments.
    3. Array: An array of any of the above.

    Example of a function matcher:

    // Ignore links that point to a specific section or have a specific class
    const myFilter = (href, node) => node.classList.contains('no-prefetch');
    
    listen({ ignores: [myFilter] });
  9. Import and use the prefetch method directly

    main

    You can import the prefetch method as a standalone module to use in your own projects. This is useful for manual control over prefetching logic.

    <script type="module">
      import {prefetch} from 'quicklink';
      prefetch(['1.html', '2.html']).catch(error => {
        // Handle own errors
      });
    </script>
  10. Configure quicklink.listen(options)

    main

    The quicklink.listen(options) method starts observing the viewport for links. It returns a reset function that clears the active IntersectionObserver and the URL cache. Call this function between page navigations or after significant DOM changes.

    Options Reference

    OptionTypeDefaultDescription
    prerenderBooleanfalseSwitches from prefetching to prerendering mode using the Speculation Rules API. Falls back to prefetching if unsupported.
    eagernessString'immediate'Determines the mode used for prerendering in speculation rules.
    prerenderAndPrefetchBooleanfalseActivates both prefetching and prerendering modes simultaneously.
    delayNumber0Milliseconds a link must stay in the viewport before being fetched.
    elHTMLElement|NodeList<A>document.bodyThe container to observe for links.
    limitNumberInfinityTotal number of requests allowed while observing el.
    thresholdNumber0Decimal (0-1) representing the area percentage of a link that must enter the viewport to trigger a fetch.
    throttleNumberInfinityConcurrency limit for simultaneous requests.
    timeoutNumber2000requestIdleCallback timeout in milliseconds.
    timeoutFnFunctionrequestIdleCallbackCustom function for specifying the timeout delay.
    priorityBooleanfalseIf true, uses fetch() (if supported) instead of <link rel=prefetch>.
    originsArray<String>[location.hostname]Allowed hostnames. Use [] to allow all origins.
    ignoresRegExp|Function|Array[]URLs to exclude. Can be a RegExp, a function returning true, or an array of values. Checked after origin matching.
    onErrorFunctionNoneError handler for failed requests.
    hrefFnFunctionNoneFunction to generate the URL to prefetch. Receives the Element as an argument.