Introducing the Quicklink Module for Drupal

Man getting ready to start a race

The mobile web is too slow. According to the HTTP Archive, the median time to first contentful paint is 5.8 seconds — this means that the average person waits almost 6 seconds just to view an average website on their phone. 

Recently, Google started evangelizing the PRPL pattern to combat this. PRPL stands for Push, Render, Pre-cache and Lazy-load. At its core, it’s a strategy to push down and render content within your browser and then “prefetch” links on the page. This makes subsequent page loads nearly instantaneous. 

Until recently, there really wasn’t any good way to do the “prefetching” part with traditional server-rendered systems similar to Drupal. This recently changed with the advent of the link prefetching and Intersection Observer API capabilities in modern browsers. Building upon those capabilities, GoogleChromeLabs created a JavaScript library called Quicklink that integrates these features with prefetch and lazy-loading functionality. 

About the Quicklink JavaScript Library

Quicklink is a small (less than 1kb compressed) JavaScript library that “attempts to make navigations to subsequent pages load faster.”

Out of the box, it detects links within the viewport and downloads them when the browser is idle. It also attempts to detect your connection type, and if it detects a slow connection, it’ll skip prefetching.

After links are prefetched, Quicklink uses the Intersection Observer API to detect when hyperlinks enter into the browser’s viewport. If the browser is idle, it will also prefetch these links.

Introducing the Quicklink Drupal module

Integrating these capabilities into Drupal, the Quicklink module enables a number of Drupal-specific tweaks including:

  • Integration with the Drupal behaviors system
  • Only loading the library for anonymous users (by default)
  • Option to disable loading the library if sessions are present — this is useful for Drupal Commerce sites
  • By default, the Quicklink module ignores admin links, AJAX-enabled links, and the logout link
  • By default, it ignores links that end with a file extension. We don’t want the browser to waste bandwidth downloading PDFs, MP3s, etc
  • Gives an option to load the Intersection Observer polyfill, which is necessary for Quicklink to work with Safari or Microsoft Edge browsers
  • Lots more!

Installation and configuration

Once installed, Quicklink will do its magic without any additional configuration! 

By default, the module will load the Quicklink library from a CDN. This is necessary because Quicklink’s license is incompatible with GPLv2 and can’t be hosted on Drupal.org. If you install the module with Composer (see the readme file for instructions), a local copy of the file will automatically be downloaded and installed at /libraries/quicklink/dist/quicklink.umd.js. If the module detects this file, it will be used instead of the CDN version.

Once installed, you’ll have access to a configuration form at /admin/config/development/performance/quicklink.

Quicklink configuration form

Besides the default options, the module provides several options:

  • A “URL patterns to ignore” field to enter custom patterns that Quicklink will ignore if found within the link’s URL. This is useful if there are specific paths or links that shouldn’t be prefetched.
  • An “Override parent selector” option. This can be used to limit the element in which Quicklink searches for links.
  • An “Override allowed domains” option.  By default, Quicklink will only prefetch links from the origin domain. If you add domains in here, be sure to also include the origin domain. 
  • An option to disable loading of Quicklink on specified content types.

Troubleshooting prefetches (and lack of prefetches) with debug mode

There’s a lot of logic involved when deciding whether or not to prefetch a link. This can make figuring out why a link isn’t being prefetched pretty tricky. Fortunately, we can use your browser’s built-in developer tools, plus the module’s debug mode to figure out exactly what’s going on.

Watching links get prefetched

Checking which linked pages get prefetched is pretty straightforward. Open up the network tab in your developer tool of choice, and you can see the HTML documents being retrieved while the browser is idle. When you scroll and additional links enter the viewport, you will see them being prefetched. Note the “Initiator” column (seen below in Chrome Developer Tools) shows you that Quicklink initiated the HTTP request.

Chrome developer tools showing quicklink initiating the prefetching of linked pages
Chrome developer tools showing quicklink initiating the prefetching of linked pages

Troubleshooting links that do not get prefetched

During testing, it took a good deal of effort to determine why links were not being prefetched. To help, I implemented a debug mode that’s enabled by selecting the “Enable debug mode” checkbox at the bottom of the Quicklink configuration form. 

Debug mode outputs a lot of useful info. Once enabled, it will append a “no entry” emoji (🚫) on links that Quicklink is ignoring. Hovering over the links will give helpful info.

Quicklink debug mode output

Console output gives useful information

In addition to inserting emojis, the Quicklink module’s debug mode gives a ton of useful information within the JavaScript console:

  • Quicklink config object: an object that’s passed when calling the Quicklink library
  • Quicklink module debug log: this will tell you if you’re using the CDN version of the library, and what options you have selected
  • Quicklink ignored selectors log: this is an array of objects for each ignored element, which includes an elem object on which you can hover and highlight the particular element. You’ll also see a message, matched pattern, rule name, and URI.

Quicklink debug mode console output
Quicklink debug mode console output

Using Quicklink in production

We’re using the module here on Lullabot.com — you can open up the network tab in your browser’s developer tools to watch the linked pages get prefetched. 

That being said, test your site extensively before deploying this library to production. Quicklink will prefetch many more pages than your server is currently serving. Be sure that Drupal’s caching is enabled (it is by default), and bonus points for using a content delivery network. If you have any feedback, I’d love to hear in comments below or the Quicklink module issue queue.

Postscript: Quicklink is not a panacea for your slow website

Quicklink will not fix your slow website. 

 80-90% of the end-user response time is spent on the frontend. Start there. — Steve Souders

Quicklink will only solve the time to first byte problem — and only on subsequent page loads. If your website is slow, you need to identify and address the issues that are making it slow. To have a truly performant website, you need to enable the browser to render it without being tied up with unnecessary resources, processing, and downloads. Don’t know where to start? Contact us, we can help.

Learn more

I’ll be giving a Web Performance Clinic at Florida DrupalCamp, speaking on Identifying and Fixing Front-end Performance Issues at DrupalCamp London, in addition to giving a 90-minute Front-end Web Performance Clinic at DrupalCon Seattle. Come say hi!

Special thanks

Special thanks to Matt Olivera for helping me get started on the development of the module. Also thanks to Mateu Aguiló Bosch, Brian Tully,  Andy Giles, and Jim Birch for submitting helpful patches to make Quicklink’s functionality even better.

If you enjoyed this Article, you may also enjoy...

Mike Herchel

Thumbnail
Front-end Developer, community organizer, Drupal lover, and astronomy enthusiast