00:00:15.240
Hello everyone! Oh, now it's working. Hello, hello! As I was saying, I'm incredibly grateful and excited to be here in this first edition of Rails World.
00:00:23.439
A very quick introduction: my name is Jorge Manrubia. I work at 37signals as a lead programmer. In terms of Rails and open source, I'm the main author behind ActiveRecord encryption and its companion gems such as Console 1984.
00:00:36.320
Since this is a Rails conference, you might find it interesting to check out a series of articles I'm writing on how we use Rails at 37signals. It's called 'What I Like,' and you can find it on the company's development blog.
00:00:42.280
Today, I'm going to start telling you about my favorite Turbo feature. The foundational idea behind Turbo is that when you're rendering a web page, rather than loading new content in a new HTML document, you replace the body of the existing document. This results in a much faster operation because you don't need to reprocess all the JavaScript and CSS.
00:01:04.640
You can combine that with handling the URL change and the browser history under the hood to achieve seamless and much faster navigation. It took me a long time to appreciate this idea; it took me years.
00:01:19.040
I remember when Turbolinks was released in 2012, and David made the announcement. I felt incredibly disappointed. I thought they were aiming at the wrong target because back then, I believed that the single-page application paradigm was the future, and the right approach for many applications.
00:01:45.520
I also believed that Rails would provide some kind of answer in that space, but what I got was Turbo Links. However, after many years of trying different JavaScript frameworks and battling with multiple approaches, when Rails announced Stimulus in 2018, everything clicked for me.
00:02:02.799
Many things clicked, especially the full body replacement idea. Back in 2018, I wrote an article reflecting on the single-page application paradigm, and I believe that most of the points I made there are still valid today, five years later.
00:02:35.360
When discussing frontend web applications, if we focus solely on programmer happiness, I believe the best programming model we have is the traditional HTTP request and full-page response programming model. It's very simple and incredibly productive. You can think of your application as a set of standalone screens, focusing on the initial rendering, which is a well-solved problem in Rails.
00:02:55.760
The idea of body replacement in Turbo is revolutionary because it improves responsiveness and UI fidelity without sacrificing that programming model at all. In my view, putting programming happiness first is one of the pillars of the Rails doctrine.
00:03:30.360
In the frontend space, it is rare to see this priority. Typically, we chase capabilities and then create programming models to accommodate them. However, with Turbo, we start with the programming model first and then explore ways to enhance performance.
00:04:01.079
Now, of course, with full body replacement, there are scenarios where it doesn't give you the UI fidelity you want. After its last revision, Hotwire introduced two new tools to perform high-fidelity updates in an application: Turbo Stream actions and Turbo Frames. Turbo Frames let you define and capture specific regions of the page you want to update, allowing seamless updating and defining local navigation context within them.
00:04:40.560
Turbo Stream actions let you execute JavaScript in a declarative way, offering a standard set of actions for common DOM operations, along with support for custom stream actions. Both are fantastic options, but you are paying a 'happiness tax' to use them. This is why we often state that Turbo is a progressive framework; you are supposed to start with the happiest path and deviate from it only when higher fidelity is needed.
00:05:36.639
But you have to do that mindfully because if you disregard developer happiness and productivity, you could use Turbo Stream actions for all your interactions, and your application would be incredibly fast. However, that's not the intended use case.
00:06:04.720
Last week, Jason Fried from 37signals confirmed that the company was developing a new product: a calendar application. I had the wonderful opportunity to work on this application right from the start. The development began in February of this year.
00:06:38.640
There had been some prototyping and design exploration before that, but coding officially began in February. I remember having a meeting with Jeffrey Hardy, our principal programmer, to discuss the technical foundation for this new calendar application. One key aspect of our discussion was our desire to avoid diving deep into a JavaScript rabbit hole.
00:07:17.920
A calendar application demands a high level of interactivity, which naturally calls for JavaScript-heavy solutions. 37signals has extensive experience creating calendar features, especially in Basecamp, where we have a graphical calendar utilizing Backbone and MVVM on the client-side.
00:07:57.440
This time, we decided to explore Hotwire along with Turbo Frames and Stream actions. We aimed to avoid JavaScript heavy lifting while developing the application. Our approach was straightforward: we used the default happy path of full body replacement that Turbo provides.
00:09:02.720
By taking this approach, we began building screens and initiated discussions on the various interactions. However, as I was creating those screens, I kept the notion of high fidelity in the back of my mind. It was clear we needed to revisit some aspects to achieve the fidelity we wanted.
00:09:39.600
Rendering in a calendar application is inherently complex. It’s more complicated than rendering in a standard application because partial updates in a calendar need to accommodate a two-dimensional canvas.
00:10:09.120
How you render certain elements can affect the rendering of others due to overlapping elements. Managing these partial updates is complex, and we realized we couldn't solve this challenge with individual standard stream actions.
00:10:46.760
On top of that, we were introducing novel elements on the calendar, which led to an explosion of partial updates. This complexity not only posed a burden but necessitated a re-evaluation of our paths with Turbo.
00:11:15.000
After analyzing alternatives, I looked into Phoenix LiveView from the Elixir world. It employs a sophisticated rendering pipeline, utilizing a library called MorphDOM that applies a minimal set of changes to update the DOM efficiently.
00:11:38.320
The concept behind DOM tree morphing is straightforward. For example, if you're rendering 'Hello World' and want to change it to 'Hello Amsterdam,' you replace just the necessary text nodes while keeping the rest of the elements intact.
00:12:10.160
When I tested it with our calendar prototype, I was astounded by how effective and smooth it felt. It was a revelation for rendering HTML and maintaining client-side state like scroll positions, CSS transition states, and input focus.
00:12:57.320
We plan to introduce this new concept in Turbo, allowing it to detect page refresh events whenever you're rendering the same page again. This will enhance the experience as Turbo automatically handles updates based on a similar structure.
00:13:39.200
This new morphing behavior is about seamlessly integrating updates without the disruption traditionally associated with page refreshes. We aim to allow developers a configurable way to implement it with various scroll capture options and additional attributes.
00:14:34.960
While conducting further testing for our updates, we decided to use a library called Idiomorph, which proved more efficient than MorphDOM in our use case because it doesn't require as strict ID matching.
00:15:05.520
In our calendar application, we're using full body replacement for operations like adding columns or new cards. We wanted to ensure that adding and deleting elements felt as seamless as possible.
00:15:40.560
With the new behavior we are introducing, you won’t need to modify the existing code. This declarative configuration will achieve a smoother and more responsive set of updates for our users.
00:16:44.160
The way in which broadcasting changes will work across the app will depend on stream actions. When something changes on the server, we can communicate that to all active browser sessions, allowing them to reflect that update without requiring a page refresh.
00:18:08.960
For example, if an email arrives, it should broadcast that change in real-time to customers so they see it without reloading their page. We will offer a new standard page refresh action that can signal any models to broadcast updates.
00:19:02.000
Via morphing, this refresh action will feel smooth and maintain the necessary visual state, which we saw in our testing. We placed that action at the board level within the calendar application.
00:19:37.240
We needed to ensure significant simplification in the codebase, allowing us to replace hundreds of lines of code needed for the individual stream actions with a more integrated approach.
00:20:21.600
The result showcases how smooth it is to perform actions such as renaming or adding new fields. The user experiences seamless updates across the interface without interruptions, as the new elements show up responsively.
00:21:10.000
By utilizing page refresh actions, we can efficiently introduce interactivity for more minor adjustments. This approach ensures that changes propagate without needing granular updates for every action.
00:21:50.560
The introduced mechanism will leverage turbo permanent attributes to preserve specific DOM elements across refreshes. This allows users to maintain certain state elements, like open menus, even as the page updates.
00:22:19.440
In scenarios like pagination, when additional elements load dynamically, we also introduced a new flag called 'refresh reload' for Turbo Frames to ensure consistency even as the page updates.
00:22:56.640
Our goal is to streamline how Turbo detects and handles page refreshes automatically, enhancing user experience while maintaining developer happiness.
00:23:32.440
With the digital landscape advancing, frontend development is becoming more exciting than ever, thanks to innovative technologies. Several key agents are propelling this forward, including browser capabilities and community-driven advancements.
00:24:19.280
However, the risk lies in prioritizing shiny visual effects over a solid programming model. We witnessed trends that look impressive in demos but struggle in real applications.
00:25:01.840
An illustrative example is with React's virtual DOM diffing technique, which, while innovative, failed to address fundamental programming issues many developers face. Turbo aims to be the solution that prioritizes clarity and developer satisfaction.
00:25:50.040
The new updates to Turbo will provide a fast rendering path that enhances responsiveness while delivering a seamless user experience. The balance of ease of coding and efficient real-time updates remains at the forefront of our innovations.
00:26:59.640
I invite everyone to explore what we've integrated into Turbo and Fast Stimulus, as we continuously strive for optimum experiences that foster both programmer satisfaction and end-user comfort.
00:27:54.080
In conclusion, I believe the future of Turbo holds fantastic promise. We must prioritize innovation while maintaining the foundational purpose of enhancing developer happiness. Simplifying processes and creating a unified experience will drive success.
00:28:51.760
Thank you all so much for your time! I look forward to seeing how we can all innovate together while keeping programming happiness at the forefront of our development.