 So, let's talk about TurboLinks, because everyone loves TurboLinks. You don't, so that's why I'm here to talk about it. My name's Nate Berkepeck. I'm a freelance Rails consultant, and a lot of the progress I work on are really slow. And no business owner likes having their website slow. And I'd like to show you how you can use Rails to have a website that has a less than 100 millisecond time from key press, or click, or whatever, to glass, to final rendering. And there we go. So if you read programming websites, you would think that the only way to get a fast website is to throw whatever you have, rewrite your app with Node and a JavaScript client-side framework, and you got to use Node, Clojure, Go at the same time. I'm not a huge fan of that. It happens I don't really like these languages. I love Ruby, and I like to write Ruby, and not JavaScript, and not all these other languages. And so let's start with some definitions. To glass. Well, that is sort of an informal term. I'm going to define it here as the time from the user interaction, the key press registering, the click registering to the final paint being finished for whatever interaction you were doing. So not DOM content loaded, not load, but when is the page stable? When is that interaction completed? Which sometimes is after the document is ready, because you could have tons of document ready handlers. The great thing about how fast this needs to happen is that while computers have gotten faster in the last 50 years, human beings have not. So back in the 60s, these guys at Xerox or whatever studied how fast computer interactions have to be for humans to have different feelings about them. And if your interaction is less than 100 milliseconds, it's perceived as instantaneous. If it's between 100 milliseconds and a second, the user perceives the delay, but they still have a feeling that they're working directly on the data. And if it's more than a second, but less than 10 seconds, you have their attention, but they feel the delay. And if it's more than 10 seconds, you've lost their attention to checking Twitter or whatever. This is a readout from Chrome Timeline of a typical Rails website that will remain nameless. But Chrome Timeline shows you between the time I hit refresh and the final paint, exactly where all my time went. There's a big timeline thing that I'm not going to show you or get into how to use today, but basically check it out if you haven't already. Most of the time in a typical Rails app page load is not actually in the server response time, which shows up here as idle time because the server's just waiting for a response. And this is slow, which I'm going to get to in a minute. But it's actually all that crap that you threw in a document ready over about three years, that's all this scripting time, the second and a half of, oh, I got to attach an event listener here. I got to, you know, fire up optimizely and then change all the fonts on the page or whatever the guy in BizDev told you to do. And a lot of that time is spent in re-rendering because of all the scripts that get executed at document ready, change all the stuff in the render tree and the render tree is like, oh, fine, OK, I'll re-render everything again. And that really sucks. It's a pain interact with. It's very slow. So that breakdown, again, is you have the network latency going to and from the server. A typical Rails app is 250 to 500 milliseconds in the server response time. And then, so you're already five times past 100 milliseconds. And then you've got to parse the HTML. You've got to create the render tree, the CSS object model. You've got to evaluate all the JavaScript. And then you've actually got to paint the result. So let's talk really quickly about server response time. I'm just going to have to say, if your app is slow, 250 milliseconds, 500 milliseconds, like, sorry, it doesn't have to be that way. It's not Rails. It's you. There are lots of other large websites that have achieved these very fast times. And the way that they do it is caching. So suck it up, figure it out, do it, make your dreams come true, and get a 50 millisecond app. It's totally possible. So we figured out your server response time. It's now 50 milliseconds. You spent 10 milliseconds going to the server, 50 milliseconds at the server, 10 milliseconds on the way back. We're at 70 milliseconds. We have 30 milliseconds left to do all this stuff that took two seconds. How are we going to do that? Well, what if I told you that you just didn't have to do all those things? What if we just didn't do all that stuff on every page load? That's what TurboLynx lets us do. So traditionally, when you come up to this problem of, well, the client needs to attach all these event listeners and do all this stuff, well, you want to avoid the page load. We reach for JSON. We say, all right, we're going to bring the logic into the client. The client's going to decide with the JSON data over the wire how to update the view. It's going to say, OK, well, that means that this list element needs to be updated over here. And that moves all this logic into the client JavaScript. I don't like that, because I don't like writing JavaScript. And the really tough part about this is in a team people perspective is that you had one code base. Now you have two code bases. Now you have a JavaScript app that requires an entirely different set of knowledge, experience, skills, tooling. And that splits your team. And I mostly work with small companies of engineering teams of five, six people. That's a big team. And they just don't have the resources to make that split. It's kind of like adding another service to your architecture. And that can be tough. That can be very tough for smaller teams. So what view over the wire, really all it does is it says, OK, I'm going to go to the server. I'm going to get an HTML document. And then I'm just going to replace the document I have with the document I just got. This is not actually TurboLynx code, but that's basically all it does. And what that lets us not do is all the stuff on my previous slide. We don't have to throw away our entire JavaScript runtime. We don't have to throw away the entire DOM. We get to keep the JS global scope. And we don't have to reparse, re-evaluate the scripts from the head. Even though you don't have to re-download them, you still have to re-evaluate them to rebuild the JavaScript VM if you're not doing this. So just like your fancy pants JavaScript framework, you get all the benefits without all the client logic living in your JavaScript. So as an experiment, I rebuilt a very, the TodoMVC project, which is a sort of project where you build a TodoList in different client-side JavaScript frameworks. I did it with TurboLynx instead of client-side JS. That is available here at this URL, which is going to pop up at the end of this talk again. So this is what a Chrome timeline page load on this do app looks like when you're not using TurboLynx. I just want you to pay attention to the time spent in loading, rendering, and painting. With the TurboLynx page load, that's greatly reduced. Because the head section of the page is exactly the same. It hasn't been touched. And we're just replacing, especially with partial replacement, which I'm going to get to in a second, the parts of the page that actually need to be changed. And all the event listeners that we're on the page to start with are still there. There was only one DOM ready event, which tends to be a source of a lot of your script slowness. So you have to get a lot smarter about the way you write your JavaScript, unfortunately. If you are that kind of developer that throws everything in document.ready, you can't do that anymore. It's difficult. Yes, it's a little teething pain. But it gives you this incredible experience of having an almost instantaneous user interface. It feels pretty awesome. As an interesting comparison, on the left here is my TurboLynx implementation of TodoMVC. And on the right here is a Chrome timeline view of an Ember app. And doing the exact same interaction. I think this was clicking on a Todo item complete. And what's really crazy is the Ember app and the TurboLynx app have very similar amounts of time spent, except for the waiting for the server part. Because all the TodoMVC apps that use JavaScript just use local storage. So you can see that the idle time is quite a bit different. But other than that, they both take about 35 milliseconds in scripting and rendering. And the only difference is how much time they spent waiting for the data to be updated. Which is pretty incredible. And I got that from basically writing 10 lines of JavaScript and dropping in TurboLynx, which is awesome from a development perspective. Hopefully this will work on here. Yes. One of these videos is my TodoMVC implementation in TurboLynx. And one of them is an Ember app. I don't know if you can figure out which one is which just from looking at it, because I can't. So that's pretty cool. It really does feel instantaneous. It's kind of incredible to realize that this is going to a server on Heroku, updating an active record model, and coming back in the same amount of time or feeling like a similar amount of time the Ember app is taking just to go to my local storage, which is pretty incredible. So TurboLynx 3 coming up with Rails 5, although you can use TurboLynx 3 today if you go to GitHub and point your gem source at GitHub. Mostly it's just Shopify's incredible production experience being merged into TurboLynx core. Tbo's doing a lot of incredible work. We have partial replacement, which replaces not the entire body, like you saw in my example, but just parts of the page. Or if there's a list of models, it will replace just the models instances that have changed, which is incredible. And you now get a progress bar at the top of the page, which has a public API on how you can control it. It's really cool. And there's a couple other things you have to do to stay under 100 milliseconds to glass. Caching, mentioned that. Don't forget. Rack mini profiler, an incredible gem by the incredible Sam Saffron. I would use this in any Rails project I've ever put on. It puts this really cool little badge at the top left that lets you look at the current, how fast everything on your page loaded. It breaks it down by how many queries you ran. There's even a flame graph extension that lets you see the stack profile from the entire page load. It's incredible for breaking down slow page loads and figure out exactly where you went. Chrome Timeline, like I've been showing you the graphs from. It's an awesome tool for everything except the server response time. So breaking down, it's basically just flame graphs of where your JavaScript execution time goes. Very valuable for getting that down. For if you're living in this magical world of sub 200 milliseconds to glass, I've found that the new TurboLynx progress bar, or spinners or whatever, is actually sort of, it makes the site feel slower. I don't know what it is about our minds. We're like, we're just, now that we see progress bar, we think, oh, it's slow. I got to sit here and wait. If your app is actually that fast, I think disabling these things can actually make it, you can perceive a little bit more speed, which is kind of weird. And when you're living in this world of 100 milliseconds, the network actually becomes a big problem. So your typical Rails controller, when you go to the create action for a post, you say, OK, you succeeded at doing that. Here's your 301 redirect. Come back to me later for your get request. But that, you just double the amount of back and forths. And with network latency, that can actually add up, but now all of a sudden you're outside of 100 milliseconds. So experimenting with not using redirects in 100 millisecond UIs is interesting. You can see examples in my get repo here at the end. So your two options for view over the wire technology, sending HTML over the wire instead of JSON right now is TurboLynx, which is awesome for new projects, but it's very difficult to use on existing projects. If you have a big existing project and you want to use this technology, I would recommend PJAX. You do need to have jQuery installed, unfortunately. But PJAX lets you take this a little bit more piecemeal. It's more in an opt-in API rather than opt-out like TurboLynx is. So definitely give that a shot. In conclusion, view over the wire is fast. It lets you write less JavaScript. And it's been battle-tested by really big companies that have millions and millions of users and are in the top 1,000 websites in the world. I've been Nate Berkepeck, and that is TurboLynx in view over the wire. Awesome. Thank you.