 Thanks, Adam. That was really funny. Hi, everybody. I'm Sam Breed, and I'm going to be talking today about Backbone and React Forever Together. I've retitled this talk a couple times, so I'm not 100% sure what the title is. The original title was supposed to be Backbone View as a joke, but I figured that that wasn't a good way to win favor when I was submitting my talk to this conference. This is really a story, actually. About a year and a half I spent ferreting out good performance in a really, really, really, really large backbone app. What I discovered along the way is that Backbone View does so little for you that it's actually comical. It's not Backbone View's fault, so don't take this as an indictment of what Backbone View's doing. It's built a lot of really cool apps that use it heavily. Particularly the talk yesterday that Matt gave from Pitchfork was really impressive, cool use of Backbone View's. For about the past year and a half I've been working on an application called Sprintly. It's project management software, so basically it's a big Kanban board to help developers and product managers talk about what they're building and what they want to build. Sprintly started life in 2011, actually, well before I was involved with the project. I knew a few people that worked on it, so it says established 2010, it was really 2011. Sprintly started as the way that a lot of ambitious or soon to be ambitious web apps started. It started as a big sea of jQuery selector soup. A couple dozen files, lots and lots and lots of just raw jQuery code, which totally worked for prototyping purposes and they actually managed to build a pretty impressive app with it. Enter Backbone. Sprintly adopted Backbone in the 0.5 release. Who here has been using Backbone that long? Show of hands? Okay, it's impressive that you guys are still here. The 0.5 release of Backbone definitely had some flaws in it. It was really, really easy to create memory leaks. It was kind of a hard upgrade path to get from that release to where Backbone is at today, which soon to be 1.2, right? Sprintly started life as first a jQuery app and then it got some structure refactored into it. It got a module system along the way, used RequireJS for quite a long time. What that really enabled the app to do is get just a tiny bit of structure and then add in lots and lots and lots of code. Sprintly, it turns out, is an enormous app. By the time that I started working on it in the summer of 2013, it was an even bigger app than it was when they first converted to Backbone. Talking like hundreds of files, dozens of views, dozens of models, and it was really, really hard to make heads and tails of it. There was a lot of duplicated code. This is really what happens when you let software entropy take hold in a large product. Sprintly is a complicated product. While they were innovating and adding features and listening to customer feedback, no one was paying too close attention to the state of the code from a cleanliness perspective. The module system really just allowed us to make a treasure trove of all of these junk drawers where we had views and classes that were 700, 800, sometimes 2,000 lines long that you don't know what was in them, you get blame it, and it's some contractor that's long gone with a cloud of dust and a person-shaped hole left in their wake. Don't leave apps unattended. It's one of those first things. I've said this before in talks. Software entropy and code debt are stuff that happens because people are going quickly, it happens because maybe you're a little lazy, maybe you want to get out the door at 5 p.m. on a Friday, but software entropy really sucks because it can pull down your application's performance, especially on the front end, in a really, really raw way. The overwhelming thing about this code base was that it was fine when they first wrote it. From a performance perspective, things worked really well. When you tested the app out from a QA perspective, Sprintly is basically a big Kanban board, right? You can drag and drop cards. The maximum number of cards that we were dealing with, like in our QA environment and our staging environment, was maybe 30 or 40, and we felt like that was a lot. Then we looked at our data and we realized that some of our customers were leaving hundreds of cards on their Kanban board all the time, and in some cases even more than a thousand cards. Each one of those cards is a backbone view. Each one of those cards had event bindings in it, and each one of those cards was instrumented with a jQuery UI drag and drop. All of these expensive things essentially amounted to a thousand paper cuts or rather a thousand wax with a hammer. Big Bang rewrites are pretty terrible and they're really, really difficult to do. We were in a state where some of our largest customers that really, really liked the application found that it was really unusable based on the way that they were using it. Changing user behavior, especially when it's a tool that they're in every day that they're really used to, it's really difficult. We didn't have the balls to say, no, you're really doing this wrong. You shouldn't have a thousand of anything on the screen at one time. These are really difficult problems. We just had to suck it up and make sure that the app would keep on performing well. But we couldn't do that by rewriting it. Too much time and too much effort had been spent just to get the app functional to the place where it was when I joined the Sprintly team last year. What did we start doing? First, I looked at the view layer. The view layer has a lot of loosely related concepts thrown together. Things like sub-views, templating layer, event handlers, data binding, most importantly testing. All of these things kind of work against one another, unfortunately, if you don't have the right organizational structure and if you really don't take great care to make sure that these things are managed in a really pristine way, you're going to be in for a really, really bad time. Views create side effects. In Henrik's talk this morning, he was talking about the DOM is essentially this big kind of mutable global state. I'm not going to touch it now. I'll stand back here and put my hands behind my back. Everything you do in the DOM seems like it creates a side effect. Everything you do in a backbone view seems like it's creating a side effect. If you code review a lot and I code review a lot of code for Quick Left and for Sprintly, you just kind of see these view methods and everything in them, every single line is calling out to some other thing. It's writing to the DOM, it's using a jQuery plugin or something. Those things are really hard to test. The testing is the layer that the bottom falls out first and you stop doing it, you get lazy. Groups of views have natural structures that if you're diligent, you're not just using one monolithic view or a backbone view for your application. You've got a whole bunch of them. They're forming a tree or kind of writing an application that in some ways mirrors what's going on in the DOM. You've got all of these sub-views, but then you kind of run into the problem of creating memory leaks, build up and tear down, becoming really, really expensive if you're trying to create a thousand item cards on the page inside of the first couple seconds that the application is loading. These kind of patterns are emergent. They form in an organic way while you're building your application. These things kind of amount to a situation that's really unfortunate, but it's not really anyone's fault. Even though you can get blame and hate the folks that wrote the code before you because it's riddled with bugs and it's not performing and it's like, what are they thinking? That doesn't help either. You've kind of got to strike out and either fix the stuff on your own or find something else that you can put into your app in a progressive way. Some of the early optimizations that I did when I was working on the Sprintly app kind of followed along this trajectory. The first thing that I always look at in an application that's not performing very well is the templating layer. Unfortunately, when we all kind of, the templating renaissance of 2010 and 2011 happened where you had dozens and dozens of new fancy templating libraries coming out a new one every week, right? They all had these examples of putting them in a script tag and then compiling them in the browser runtime and then using them. That's one of the worst things that you can try to do when you're initializing your application because that's when you're doing literally everything else to initialize your app. You're fetching data from the server, you're rendering all of your views, and so it's just this time that you can shave off. In the tens of milliseconds usually, if you have complex templates or enough of them, and so I did that and that was a pretty easy quick win and it really was just kind of, it was like hitting an elephant with a fly swatter. It didn't even move, didn't even notice it. The app was still performing like complete shit. Then I kind of went a little further and the things that I went through are frame budget trickery. Thank God the Chrome Dev Tools had released their memory profiling and their performance frame rate profiling stuff last summer because without that I would have been completely screwed. I realized it's like, oh yeah, I'm trying to do 500 milliseconds of rendering inside of a single frame. Of course it's hanging up and I can't scroll for two seconds. There are a bunch of things that we started adding in, getting our rendering flow within our backbone app to be as asynchronous as possible. What that means is adding, underscore has this great method of defer that is just a set timeout with zero, right? But it kicks something forward far enough so that if you're doing a lot of complex rendering work it will usually be the solve that will heal that wound a little bit. We went back to using native DOM methods for a lot of stuff. Actually doing things that were kind of unsafe, we realized that when we were tearing down views, the call stack was like a yard deep because there was all of these jQuery protections and recursively walking the DOM to make sure that it was cleaning up all of its data bindings and all that crazy stuff. We love jQuery 4 because those are things that ultimately make your app really efficient, but they can also really slow your app down. It's so perplexing that it's like, hold on, the reason why I'm having chuggy frame rate when I'm switching views is because I'm removing stuff out of the DOM, it seemed really counterintuitive at the time. It's super annoying. Fixing memory leaks, that's the kind of old classic nightmarish tale of using the early releases of Backbone is that you discover that you can bind on to all these great model events and you can have this life cycle that takes your application from being primarily something that is procedural, if you're coming from a jQuery selector soup app to something that's more evented and feels more natural, feels like an MVC. Those things like Jeremy talked about yesterday when he went through the deep dive of the event system and before Listen 2, you just had all of these manual bindings on and off and they were really hard to hunt down, and not everybody working on the application kind of understood how to even find where a memory leak is and the lengths you have to go to to chase those things down are still kind of annoying even with modern DevTool stacks in Chrome and Firefox. JQuery plugins are great, but they are kind of a terrible hellscape when you get into them and you use enough of them and with JQuery UI, you know that you're using it because you're looking at the source every 15 minutes when you're trying to solve problems. So we had a bunch of JQuery plugins that were kind of brought in really innocently and then we're doing things that were hurting performance. We had heavy use of JQuery UI, drag and drop, which is really fantastic and I've used it and abused it for years, but it's also really expensive to do. So there are all these kind of things that like a rough combination of those techniques. We threw them together, made all of our rendering super asynchronous, made sure that we were waiting as long as possible to turn on drag and drop on elements and basically getting really militant about not introducing UI changes that we're going to kind of drive over that surface area of performance, which for us is literally the whole app. And then we got to the dreaded double render. I'll render this again just to prove the point. So the double render happens in your backbone app. I almost guarantee it. So what happens is that you've bound your render method to an event, like a change event on a model or a sync event. And it seems great. Stuff works right away. Your Ajax call comes back from the server. Your page renders, you see new data. That's awesome. And then it happens again and again and sometimes four or five more times just for good measure. And we were doing things that kind of magnified and made this problem way worse than it otherwise would have been because we were using some extensions to backbone collections to allow us to have a single master collection that was heavily filtered down to the... so that we can have one God collection and then all these other collections are just views so they share all the same models and memory. We probably should have used Supermodel but we didn't. Somebody else chose something kind of lame and it made it so that all of our events were firing four or five times. And I looked at this and the first day I saw it, I had to pull other people over. I'm like, look, when you drag an item card from one column to the other, not only does it needlessly re-render every single card on the page, it does it like seven times. So if you're not looking for this stuff, your app will just appear to be working and it's probably double rendering. And if you feel like your frame rate's getting chunky, just put a console.count in your render method and see how many times it fires off. So this is the code part of the talk, I guess. So this is like a really naive implementation of a backbone view with a render method. Obviously this is like four lines of code so it's nowhere near complete. But this is kind of the pattern that we followed quite a bit. We had a pre-compiled template that we're pulling in with, in this case it would be like a browser-ify extension to compile the handlebars template at compile time rather than at runtime. And then we're just dumping the whole thing into the jQuery element that the view's associated with, dumping out the models to JSON. And so I haven't talked about React much yet in this talk and I promise that I'm getting to it. So I just wanted to show kind of like the equivalent React thing. I know Henrik talked about it a little bit earlier today. So like the equivalent React view is not too much more code except the main difference is that like the template you can see is just like slapped in there in line in the middle of the function. Unfortunately this is like aesthetically the least appealing thing about React when you first see it. And I will admit that at JSConf in 2012, 2013, when they first like announced React and the Facebook guys were up on stage and really excited about it, I was laughing like an asshole in the back row because I was like, yeah, XML, that seems like a great idea, guys. So, yeah, Adam remembers that. So I have to officially apologize today because I kind of looked at it at face value and didn't realize that there was, there's something else going on here and it's actually something, you know, aside from like the transformation, like the source code transformation, the JSX compilation step that you have to go through, what this is really doing is putting the context of your template back into the view. And you know, we kind of like that first kind of preliminary early optimization step that I was talking about right where like we take this template file and you know, we make sure that's not just like sitting like raw in a script tag on your page waiting to be like pre-compiled at runtime. Like we put it off in another file, you know, if we're being good about organizing things, we maybe have it close by to where we are, you know, actually storing this view, but still it's in a separate file and these templates can get really, really big if you're doing complex stuff, especially if you're, you know, needing to have lots of conditionals in them, if you know they're like, if you ever like open up Sprintly and like look through like the DOM, like our DOM is super complex. It's, you know, heavily designed and it could probably get refactored, but it's like when you're building features, solving bugs, and like chasing down these terrible performance problems because customers are churning out of your application, you know, like the last thing that you're going to do is being like, okay, well, yeah, let's go clean up every single template while we have 500 of them and they're all enormous. So putting the template into the context of your view layer is actually something that ends up being really beneficial. You don't have to have, you know, and like four splits open in your editor to look at two views, like right, you know, I end up with this problem all the time and like in backbone apps where I'm just like looking at like half a dozen files at once just so that I can have the right context so that I can fix the bug that I'm trying to solve or kind of reason about figuring out the lay of the land. So this JSX kind of inline, I think it's a really bad rap and if this is what's holding you up from like wanting to use React or wanting to give it a try, I really encourage you to try to look past this because at the end of the day, all of this just gets compiled down to function calls and the function calls are a huge pain in the ass to write. Like using the JSX compilation step actually turns out a really good idea. So the next thing we're going to look at is again another naive implementation that's missing a bunch of stuff. Don't expect to run this code. But I was talking earlier about views having structure and kind of naturally forming into a hierarchy. It's based on the DOM and it's based on kind of a smart reasonable way to structure your application into something approaching swappable components. Especially in Sprintly, again, big Kanban board, we have item cards everywhere. Item cards appear on every single view of the application and if we duplicated all of the code for them everywhere it would be, this one megabyte app would probably be a 10 megabyte app. So this is again a naive implementation where we're saying like, okay, I'm going to loop over a collection and again, you should probably be using Marionette to do something like this. But if you have an application and you are doing this manually, this is the part where you should perk up your ears and pay attention. So right, you know, we're initializing, we're initializing like a new item card view. We're making sure that it's cash so that, you know, we don't like double, we don't double instantiate it because that's super expensive. And then we're ultimately like mapping over the collection, rendering a view for every one of those, dumping those things out into the DOM. And this gets a lot simpler in React. This is something where React, especially when you use it with Backbone or put it into an already existing Backbone app, you get some benefits of like the built-in, the built-in underscore methods that are associated with collections where you go from, you know, kind of having to do either manual bookkeeping, pulling in a dependency like a Marionette or Layout Manager to really, you know, just have something where it's like, okay, well, this React View will accept a collection. It expects it as a property, it will blow up without it. And then maps over it and returns some more JSX, which is just an element in our item card view. The item card view is what we were looking at a little bit earlier. So, again, this is something that, you know, at first blush, I was like, you know, really not into the JSX thing, but then I was like, oh, this makes a lot of sense. This seems like I'm actually able to use and reuse components at will without having to go through a bunch of histrionics to make it work with backbone views or with pulling in, like, yet another dependency. React is like, you have to, like, it's a big dependency, right? Like, it's not small. It does a lot for you. In my experience, though, like, it hasn't yet been this draw that broke the camel's back and Sprintly has, like, a bajillion dependencies. So, what's one more? But, so, you know, when I was preparing for this talk, it just kind of got me thinking along the lines of, like, you know, why backbone in the first place? And I think John Paul, who's not here today, had, you know, a really good talk yesterday that where he kind of describes, like, this, you know, progressive learning about, you know, going from prototype to jQuery to backbone to Angular and then eventually to Ember. And I went through a really similar phase. You know, I started writing JavaScript with prototype and then, you know, I learned jQuery and was really excited about it, you know, got involved in the jQuery community and stuff. And backbone really does represent this awesome, you know, kind of building block that you can use as a crutch to learn how to make sensible applications. And, you know, batteries don't come included with it, though. So, it's not something where you're going to, you know, literally write an application without writing any code, like John was showing us yesterday. Like, that's really cool. I'm not saying, but like, I don't, I would question how much you're really learning when you're just kind of, like, using entirely, like, batteries included off the shelf tools. Anyway, so, you know, React, I think, is another incremental building block. Because while it is doing something that is quite complex, and I avoided putting the term virtual DOM in my slides, but I'll talk about it a little bit. You know, Facebook had this problem where, like, every feature that they were shipping had some, like, visual impact, like, on, like, they're building a fucking web app, like, you know, and a really performance-sensitive one. Like, look at, scroll through your, scroll through your feed if you're a Facebook user, and like, look at how many images are on there. Look at, you know, videos that are auto-playing. They've got a native chat, they've got, like, a chat app in there. Like, they're doing really, really complex stuff. They have literally thousands of engineers. How do you guarantee that, like, what the new guy is committing when he fixes a bug isn't gonna hose performance on your whole page? Well, you get a group of the best kind of developers, and you make them solve this front-end problem. I think that the solution that React came up with is really novel and really unique. And, again, Henrik talked about it a little bit this morning with regards to, you know, how it can be emulated and how you can, you know, kind of pull the best parts of it out. But it already exists, and Facebook is really going whole hog into it. So, you know, it's something that if it's good enough for their, you know, hundreds of engineers that have to ship front-end features all the time, it's probably good enough for you to try using, especially if you're dealing with things that are performance-sensitive. So the reasons why I think React is really attractive are first and foremost the performance. You know, we've started refactoring parts of Sprintly to use React, and essentially it obviates the needs to have myself spend, like, you know, slaving over code reviews for hours to make sure that they're not going to have performance impact, having to, you know, teach all the developers at Quick Left that end up touching Sprintly code, you know, what to watch out for, how to, you know, use the timelines panel and their dev tools. Like, they all know that, but it's not kind of like, you know, the day-to-day course of what they're doing to, you know, kind of closely, hawkishly monitor performance in their app. So that's one. Components is another. You know, React, essentially, everything, the only things you create are components, and React components can be consumed by other React components. And essentially, once you start using React on your page, it becomes turtles all the way down. And when we first started using this and refactoring it into some apps that already existed, backbone apps, that is, it became really obvious, like, how to refactor these views and how to split them up into their kind of, like, base primitive components and then how to enforce the properties that they're receiving and then how to write tests for them. And these are things that, like, doing it in raw backbone views just seemed like insurmountable. You know, we're not going to componentize every single little thing, especially if we're only using it maybe one or two places. It's just too much work. And so, you know, what's fallen out of this is that, like, we've actually contributed more open-source than we usually do specifically around React components because it just makes sense. It's like, oh, well, you have a calendar widget, pull it out and make it a component, put it on GitHub, put it on NPM. So Browserify is a really slick tool. How many show hands, how many people use Browserify? That's not nearly enough. I hear really good things about Webpack, too. But Browserify, right, uses the NPM ecosystem, uses common.js. It essentially just works. And I've been a big fan of modules in JavaScript for a long time, and I have to apologize to all the people that I recommended to use Require.js because even though Require is really cool, it kind of gets you into a pretty terrible configuration feedback loop where you just have these very esoteric config files. You probably have more than one of them if you're actually writing tests. You have these asynchronous bugs that kind of breaks in unpredictable ways. And ultimately, if you're using Require.js, you end up with a Require.js expert on your team because you have to. So Browserify really eliminates the need for that entirely. In my experience, it works out of the box just fine. And React essentially goes out of its way to play nicely with Browserify. So the JSX transform is available as a Browserify transform called Reactify. Now you can even use some ES6 things like destructuring assignment, splat arguments, the short objects in tax, which I'm a big fan of. And these things, they're behind a flag still, but you can start using that stuff just out of the box because the ecosystem is nice and it lets you do it and it's not hyper-constructive. Facebook, another compelling reason to do it. I talked about that a little bit already. And so what this led to at SprintLame and at Quick Left in general, and a lot of the work that I do with clients, is a movement towards SDKs. It really forced us to think about where the complexity in our application sits and how it's dependent on one another. And most front-end MVC apps look something like this, where you have a medium-sized stack of models of models or collections. You have a thinner stack of routers and controllers and then you have an unending, never-ending, like enormous jumbo-sized stack of views. Lots and lots and lots of views. So what I mean by a movement towards SDKs is we realized that we could actually split out the model and collection layer of our application and make it work with our Corez API. And it meant that we could start writing really rich, complicated applications that build and are additive on top of all the other work that we had done in the model and collection, in the data layer of our application. Backbones are really small dependency. It represents this really nice kind of separation of concerns and you can also make that stuff open source. You can make it available to your customers directly. And this is something that, when we first started thinking about this, it seemed like, okay, well, are people actually going to use it? And then we found that since we've started working on the project, we've had customers that have bypassed asking us questions about the API because we've provided the tooling that comes out of the box and just works and is more than just, you know, a call to an age accent point, but rather something that like imbibes the collection and gives you, you know, some really, really rich functionality out of the box. And then on the application side, it allows us to focus on cleaning up that view layer and on reducing the overall cognitive load that it takes to get into the application. So this work's not yet complete, but when it is, we'll be able to take out, you know, probably two dozen files or something, just take them out of the application and have it be a dependency that is pulled in via MPM. So some other cool stuff about React. Prop enforcement, I put explanation points to make this stuff exciting. So property enforcement is something that's near and dear to my heart. Last year I gave a talk here about dependency injection, and Jeremy tweeted afterwards that dependency injection isn't a thing in Backbone. So I'll also recant that and just call it dependency enforcement. Enforcing that the things that you expect a class to have when you create it is a really, really good idea. It's eminently testable, and so when I saw the property of enforcement in React, I was like, hey, that's really cool. Like instead of having to build your own stuff to make that happen, which I've done, you know, half a dozen times over, half a percent module. This is just something that made my heart fill with joy, because it's really nice. The one thing that I should say is that it's actually really similar to the prop enforcement syntax that comes with HappyJS is module joy, and I wish that they were compatible, but they're not, but it's really similar. Slight differences, though. Mixins. Mixins are pretty cool. It allows you to do something like this, where you can literally take the backbone events object, as is, off the shelf, toss it into a React class, and just have it work as you would expect it to. This is one of the ways that we've made it really seamless to, you know, kind of translate some of our old view code into new view code, and the Mixins system is really robust and has a lot more to it than this, but this is a pretty neat example. Internal state is another thing that is a concept that seems probably a little bit obtuse at first, because well, you have properties, and those come from the outside, and you have state that, yeah, you can also affect it from the outside, but you're really, like it says in big bold letters in the React docs, like initializing the state object with properties that you inject from the outside world as an anti-pattern don't do it, but it actually lets you, you know, it gives you a place to do some of the bookkeeping in your views that otherwise is just kind of, like, lying all over the place. One of my favorite analogies for describing code is like a junk drawer, because, you know, you have, like, even in the most pristine projects, sometimes you just have a whole bunch of shit lying around, and, like, you have to have a class that's, you know, two or 300 lines long just because it's doing something that complex, and, you know, the more that you can kind of synchronize and, you know, shuffle that junk around, it, like, the appearance of organization it actually does lead to things being a little bit easier to understand. So, you know, in this example, you know, this would be a, you know, something for, you know, toggling whether or not something is hidden in the UI. And, you know, you would wire this up with a click handler or something, and, you know, just by the act of, you know, kind of touching the state object, it'll cause a re-render, but it'll cause a really smart re-render, where it's just going to bump the property, the properties that have changed. I put this slide up again because I really want to impress upon you that Big Bang re-writes are not only terrible, they're usually not even possible. So, like, take this with a grain of salt, like, Ember and Angular and React are all fantastic, but the main thing that makes React stand apart from Ember and Angular is that you do not have to rewrite your entire application to benefit from it. Like, Ember is really great, and I encourage the teams at Quick Left to start and do projects with Ember, because I think that it has a lot going for it. We also do a ton of work with Angular projects, and you know, they both have their merits, but what's really frustrating to me is that, like, if you have a big application that you've been, you know, pulling behind you for a number of years, you're not going to rewrite the whole thing in a day. No matter how many, you know, kind of CLI helpers it comes out of the box with. So, being able to do things progressively is a really big benefit, and I think that, you know, that's one of the things that, you know, not only React, you know, representative of doing something really modern and really novel, but it's also something that can be progressively factored into old code. JSX is actually pretty okay, you know. It gets a really a really bad rap, but I would encourage you to try it out and to use and to, you know, make a little side project that uses React or something. You might really like it. And let Facebook solve the fucking hard problems. Like, you've got shit to do, like right? Like, focus on writing your app. Don't spend a year fixing performance problems because even though, like, that led to us being able to move a little bit faster and lose fewer customers because of performance complaints, at the end of the day it was kind of work that I regret doing because somebody else has come along and solved this problem in a way more clever than I would have ever done. And, you know, being able to stand on the shoulders of giants is one of the fantastic things about software. I did that, too. I don't know. It kind of, like, lines up to get... Right? So that's the React logo and the Backbone logo. Clever. That was my talk. Thanks, everybody.