👉 Live demo 👈

Omnipedia is running RefreshLess.

Problem/Motivation

Issue to organize and track the minimum viable implementation of a Hotwire Turbo port.

Proposed resolution

Move/disable the 8.x-1.x code and re-implement on top of Turbo.

Remaining tasks

Blocking issues

Non-blocking issues

Postponed issues

Most of these have had workarounds implemented that are good enough for now but will need additional work to refine to a point that is satisfactory enough from code quality, robustness, and/or forward compatibility perspectives:

Ongoing issues

These are ongoing in the sense that they don't have a clear finished state for the time being:

User interface changes

Mostly none? Should just work.

API changes

TBD. Probably quite a bit.

Data model changes

Probably none unless we start adding some basic configuration.

Archived notes

Problem/Motivation

After thinking about and exploring the Symfony UX Turbo code (see #3238865: META: Incorporate Symfony UX Turbo Into Module), 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.

Proposed resolution

Bypass the existing Ajax implementation and server-side optimizations for now; see #3294430: RefreshLess 2.x roadmap. 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 #3397367: Turbo: implement partial page updates

Comments

Ambient.Impact created an issue. See original summary.

ambient.impact’s picture

ambient.impact’s picture

ambient.impact’s picture

Issue summary: View changes
ambient.impact’s picture

Issue summary: View changes
ambient.impact’s picture

Issue summary: View changes
ambient.impact’s picture

Issue summary: View changes

Reworked "Proposed resolution" section.

ambient.impact’s picture

Issue summary: View changes

Added checklist to "Remaining tasks" section.

  • Ambient.Impact committed d14779ef on 2.x
    Issue #3393105: super basic Hotwire Turbo sub-module mostly working.
    
ambient.impact’s picture

Added updated demo with behaviours now working.

ambient.impact’s picture

Issue summary: View changes

Added drupalSettings list item.

  • Ambient.Impact committed dddd35a1 on 2.x
    Issue #3393105: Rewrote Turbo attach/detach; add drupalSettings update.
    

ambient.impact’s picture

ambient.impact’s picture

Issue summary: View changes

Completed moving JavaScript to <head> and update drupalSettings; added list of remaining issues that need to be solved.

ambient.impact’s picture

Issue summary: View changes
ambient.impact’s picture

Issue summary: View changes
ambient.impact’s picture

Issue summary: View changes
ambient.impact’s picture

Issue summary: View changes

Moved #3397370: Turbo: Improve drupalSettings updating to separate list for non-blocking follow-ups.

ambient.impact’s picture

Issue summary: View changes

Replaced old "API changes" section with new note.

ambient.impact’s picture

Issue summary: View changes

Minor issue summary wording change.

ambient.impact’s picture

Issue summary: View changes

Reworked Concerns section.

ambient.impact’s picture

Issue summary: View changes

Hiding old videos

ambient.impact’s picture

Issue summary: View changes

Edits to the "Proposed resolution" section for tone and to clarify current approach.

ambient.impact’s picture

  • Ambient.Impact committed cb16027b on 2.x
    Issue #3393105 & #2708615: Added Turbo JavaScript alter kernel test.
    
ambient.impact’s picture

Issue summary: View changes

Reworked "Current issues that still need to be solved" and "Follow-ups that aren't blocking" to "Blocking issues" and "Non-blocking issues" headings, respectively.

ambient.impact’s picture

Issue summary: View changes

Added #3401146: Turbo: Automated tests to blocking issues.

wim leers’s picture

Just posted #3238865-7: META: Incorporate Symfony UX Turbo Into Module, but looks like I'm way behind?! 😅

Wow wow wow! I'll try to review this in the coming weeks 🤩

ambient.impact’s picture

Heck yeah. Thanks!

ambient.impact’s picture

Issue summary: View changes

Added #3411449: Turbo: Support Turbo cache to non-blocking issues.

ambient.impact’s picture

ambient.impact’s picture

ambient.impact’s picture

ambient.impact’s picture

ambient.impact’s picture

ambient.impact’s picture

ambient.impact’s picture

Issue summary: View changes

Added live demo heading and links.

ambient.impact’s picture

Issue summary: View changes

Reformatted live demo as list for readability.

sebastix’s picture

Really awesome work! Zero page refreshes ftw!

ambient.impact’s picture

ambient.impact’s picture

Issue summary: View changes

Moved #3414538: Turbo: Implement additive JavaScript aggregation to prevent multiple evaluation from blocking to non-blocking for the time being; see that issue's summary for more information.

ambient.impact’s picture

Issue summary: View changes

Moved #3422964: Turbo: Visiting pages with 4xx response codes causes re-evaluation of <head> JavaScript to non-blocking as we now have a Turbo patch to work around it for the time being.

ujin’s picture

Hello,
I tried a module on my local machine and works well. I can see you have addressed most of the task from the list. Is there anything I can help with?
Thanks.

ambient.impact’s picture

Glad to hear it's working well for you. I'd say the following still need work:

  1. #3401146: Turbo: Automated tests - while I've created some basic stuff to test Turbo requests, there's only a basic navigation test at the moment so we need a whole bunch more tests for the various items listed in that issue.
  2. #3399243: Turbo: Tracking issue of core and contrib behaviours that need fixes to correctly detach and then attach - there are still a couple of Drupal core problems that need to fixed, ideally by contributing to core itself but can be worked around in the meantime
  3. #3414538: Turbo: Implement additive JavaScript aggregation to prevent multiple evaluation - Drupal's aggregation needs to be augmented to serve just the JS libraries not already present on a page during a Turbo request because enabling JS aggregation currently breaks JS over time as you navigate. More details in the issue.

Those are the main ones I can think of right now. Any help is appreciated!

ambient.impact’s picture

ambient.impact’s picture

Issue summary: View changes

Moved #3401146: Turbo: Automated tests to non-blocking.

ambient.impact’s picture

Issue summary: View changes

Significant restructure of issue summary; moved the old stuff to a section at the end as archived notes.

ambient.impact’s picture

Issue summary: View changes

Removed some lingering old stuff that's no longer relevant.

ambient.impact’s picture

Issue summary: View changes

Added postponed issues and ongoing issues lists, and moved linked issues where appropriate.

ambient.impact’s picture

ambient.impact’s picture

Issue summary: View changes

Removed #3422216: Turbo: Configuration and form for toggling Turbo features as it's not really relevant to a minimum viable implementation right now, though might be done down the road.

ambient.impact’s picture

ambient.impact’s picture

ambient.impact’s picture

Issue summary: View changes

Moved #3480618: Turbo: Drastically simplify installation for end users to postponed as immediate goal is achieved.

ambient.impact’s picture

Issue summary: View changes
sebastix’s picture

Awesome work on this @ambient.impact.

It's already quite long on my backlog, but I'm going to refreshless https://nostrver.se and will see how it goes!