Hotwire Turbo minimum viable implementation

Created on 11 October 2023, 9 months ago
Updated 13 April 2024, 3 months ago

πŸ‘‰ Live demo πŸ‘ˆ

If you want to see this in action and compare how the exact same codebase feels both with and without Hotwire Turbo:

Problem/Motivation

After thinking about and exploring the Symfony UX Turbo code (see 🌱 META: Incorporate Symfony UX Turbo Into Module Active ), I'm not convinced that it's required to get Turbo Drive up and running, which is the Turbo equivalent of the homegrown JavaScript in the 8.x-1.x branch. Symfony UX Turbo does provide integration for Turbo Frames and Turbo Streams, which I'd want to eventually support, but I think the wise approach would be to start with basic vanilla support for Turbo Drive without the Symfony integration to keep things simple. After that, we can work on integrating the Symfony stuff as a nice to have.

Steps to reproduce

Take a look at the 2.x branch.

Proposed resolution

Bypass the existing Ajax implementation and server-side optimizations for now; see 🌱 RefreshLess 2.x roadmap Active . This won't be a big deal for the time being:

  1. Serving a mostly standard Drupal response (i.e. full page HTML) removes some complexity, and Turbo Drive is built to handle this really well.
  2. All modern browsers support gzip compression, drastically cutting down on data sent over the wire compared to the dark old days. While it's still technically more data than if we only sent changed regions, it's not as big a deal as it used to be, unless you've got comically complicated pages that you're serving, in which case you probably have bigger problems you should fix.
  3. If you're doing Drupal right, you know how to use the cache API so that stuff only gets rendered (and thus render cached) when it has to be. Drupal's render cache is really fast if there's a cache hit.

Concerns

In #2692343-2 β†’ , Wim Leers makes a good point that detaching and attaching JavaScript behaviours to entire pages is more work for the client than if we only updated the regions that change and detach/attach to those:

Finally, this means once again replacing the entire <body> and detaching/attaching Drupal behaviors (i.e. run all JS) on them. Which means it defeats a significant portion of the purpose: improve perceived speed by having the browser do less work. i.e. using the official Turbolinks JS significantly increases the amount of work the browser has to. This makes sense for that library because it wants to work on almost any HTML. But in the case of Drupal, we can take advantage of its cacheability metadata to automatically figure out which portions of the page change.

While browsers have made a lot of performance optimizations since that was posted almost 8 years ago in 2016, Wim is right that it's not great for client-side performance to detach and attach behaviours to the whole page since we know what regions actually change. To that end, I've opened πŸ“Œ Turbo: implement partial page updates Active

Remaining tasks

  • βœ… Attach Turbo as a library to the page.
  • βœ… Detach behaviours when leaving a page and attach behaviours when rendering the new page.
  • βœ… Force full page loads on links leading to a theme other than the current one.
  • βœ… Force all JavaScript into the <head> with defer attributes[1].
  • βœ… Update drupalSettings during a Turbo render.

[1] This doesn't yet vary by whether fetched via Turbo - this is done on a full page load too; will need additional work to implement that if needed.

Blocking issues

Non-blocking issues

User interface changes

Mostly none? Should just work.

API changes

TBD. Probably quite a bit.

Data model changes

The module doesn't store anything, so probably none I guess?

πŸ“Œ Task
Status

Active

Version

2.0

Component

Code

Created by

πŸ‡¨πŸ‡¦Canada Ambient.Impact Toronto

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.69.0 2024