From 704ca2371cadf34398da5e731d3e779516932277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Fern=C3=A1ndez-Capel?= Date: Wed, 7 Feb 2024 10:18:10 +0000 Subject: [PATCH] Document Instaclick (#157) * Document Instaclick * Copy edits * Document it's enabled by default and how to disable it programatically * InstaClick -> InstantClick --- _source/handbook/02_drive.md | 55 ++++++++++++++++++++++++++++++++++++ _source/reference/events.md | 2 ++ 2 files changed, 57 insertions(+) diff --git a/_source/handbook/02_drive.md b/_source/handbook/02_drive.md index 5417c9e..be43195 100644 --- a/_source/handbook/02_drive.md +++ b/_source/handbook/02_drive.md @@ -304,6 +304,61 @@ If the form submission is a GET request, you may render the directly rendered re Servers may also respond to form submissions with a [Turbo Streams](streams) message by sending the header `Content-Type: text/vnd.turbo-stream.html` followed by one or more `` elements in the response body. This lets you update multiple parts of the page without navigating. +## InstantClick + +Turbo can also speed up perceived link navigation latency by automatically loading links on `mouseenter` or `touchstart` events, and before the user clicks the link. This usually leads to a speed bump of 500-800ms per click navigation. + +InstantClick is enabled by default since Turbo v8, but you can disable it by adding this meta tag to your page: + +```html + +``` + +To avoid prefetching links that the user is briefly hovering, Turbo waits 100ms after the user hovers over the link before prefetching it. But you may want to disable the prefetching behavior on certain links leading to pages with expensive rendering. + +You can disable the behavior on a per-element basis by annotating the element or any of its ancestors with `data-turbo-prefetch="false"`. + +```html + + + + + + Articles + About +
+ +
+ + +``` + +You can also disable the behaviour programatically by intercepting the `turbo:before-prefetch` event and calling `event.preventDefault()`. + +```javascript +document.addEventListener("turbo:before-prefetch", (event) => { + if (isUJS(event.target) || isSavingData() || hasSlowInternet()) { + event.preventDefault() + } +}) + +function isUJS(link) { + return link.hasAttribute("data-remote") || + link.hasAttribute("data-behavior") || + link.hasAttribute("data-method") || + link.hasAttribute("data-confirm") +} + +function isSavingData() { + return navigator.connection?.saveData +} + +function hasSlowInternet() { + return navigator.connection?.effectiveType === "slow-2g" || + navigator.connection?.effectiveType === "2g" +} +``` + ## Preload Links Into the Cache Preload links into Turbo Drive's cache using `Home`. diff --git a/_source/reference/events.md b/_source/reference/events.md index 886a0f5..bc55591 100644 --- a/_source/reference/events.md +++ b/_source/reference/events.md @@ -26,6 +26,8 @@ Turbo emits events that allow you to track the navigation lifecycle and respond * `turbo:before-cache` fires before Turbo saves the current page to cache. +* `turbo:before-prefetch` fires before Turbo prefetches a link. Cancel this event to prevent prefetching. + * `turbo:before-render` fires before rendering the page. Access the new `` element with `event.detail.newBody`. Rendering can be canceled and continued with `event.detail.resume` (see [Pausing Rendering](/handbook/drive#pausing-rendering)). Customize how Turbo Drive renders the response by overriding the `event.detail.render` function (see [Custom Rendering](/handbook/drive#custom-rendering)). The `event.detail.renderMethod` will equal either `"replace"` or `"morph"`. * `turbo:before-stream-render` fires before rendering a Turbo Stream page update. Access the new `` element with `event.detail.newStream`. Customize the element's behavior by overriding the `event.detail.render` function (see [Custom Actions](/handbook/streams#custom-actions)).