#+TITLE: High-Performance React #+AUTHOR: Thomas Hintz * Preface * Introduction It was the late 90's and I was just a kid visiting my Aunt and Uncle and their family in Denver. The days were packed with endless playing and goofing around. I didn't get to see my cousins much and we were having a good time. But it was the late 90's and the Internet was booming. And my cousin was in on it. A "startup", that's what he called it. I didn't understand any of what he was saying about it. Grown-up stuff. Then he showed us the webpage for the startup and I thought that was impressive. "How did you make that"? I asked him. I think he was a little confused at first about what I was even talking about but he quickly brought me over to the computer and showed me a screen full of text. "You just type HTML, that's how you make the webpage." I thought this was the coolest. "What do you type that into? What program is it? Can I do that?" He told me it was easy: just use Notepad. I wasn't going to let him go without some hook I could grab into this alien world. He told me it's really easy to learn: do an AOL search for "HTML tutorial". So began my journey with web development. I AOL searched my way through as many blinking text tutorials as I could find. It wasn't long until I was building AJAX. We had IE 5.5 and 6 and Mozilla Pheonix. And GMail came out. That changed things, now web apps were "legitimate." A lot of the technologies and libraries came and went over the years but one thing remained constant in large web apps: poor performance. From the very early days I was timing things with my stop watch. Sometimes things were slow and I had to understand why and how to fix them. Over the years I learned all about the browser's DOM and its APIs and how they work. I learned how jQuery worked and backbone.js and all the rest. I made apps that didn't lag or have jank. I was able to do this because I understood the performance implications of the tools and libraries I was using and I learned how to measure performance. I had discovered the recipe for high-performance code. And that is what this book is: a recipe for producing high-performance React applications. First, we learn how React works. Then we learn how to measure performance. And last we learn how to address the bottlenecks we find. Parts of any technical book will go stale as technology changes and that is no less true for this book. But what I hope you learn is not just the technical details but more importantly the method for writing high-performance code. The API might change but the method will remain the same. * Mini React Baking bread. When I first began to learn how to bake bread the recipe told me what to do. It listed some ingredients and told me how to combine them and prescribed times of rest. It gave me an oven temperature and a period of wait. It gave me mediocre bread of wildly varying quality. I tried different recipes but the result was always the same. Understanding: that's what I was missing. The bread I make is now consistently good. The recipes I use are simpler and only give ratios and general recommendations for rests and waits. So why does the bread turn out better? Before baking is finished bread is a living organism. The way it grows and develops and flavors depend on what you feed it and how you feed it and massage it, care for it. If you have it grow and ferment at a higher temperature and more yeast it overdevelops producing too much alcohol. If you give it too much time acidity will take over the flavor. The recipes I used initially were missing a critical ingredient: the rising temperature. But unlike a lot of ingredients: temperature is hard to control for the home cook. So the recipe can't just tell you exactly what temperature to grow the bread at. My initial recipes just silently made assumptions for the temperature, which rarely turn out to be true. This means that the only way to consistently make good bread is to have an understanding of how bread develops so that you can adjust the other ingredients to complement the temperature. Now the bread can tell me what to do. While React isn't technically a living organism that can tell us what to do it is, in its whole, a complex, abstract entity. We could learn basic recipes for how to write high-performance React code but they wouldn't apply in all cases and as React and things under it change our recipes would fall out-of-date. So like the bread, to produce consistently good results we need to understand how React does what it does. ** Basic React Conceptually React is very simple. It starts by walking a tree of components and building up a tree of their output. Then it compares that tree to the tree currently in the browser's DOM to find any differences between them. When it finds differences it updates the browser's DOM to match its tree. But what does that actually look like? If your app is janky does that explanation point you towards what is wrong? No. It might make you wonder if maybe it is too expensive to re-render the tree or if maybe the diffing React does is slow but you won't really know. When I was initially testing out different bread recipes I had guesses at why it wasn't working but I didn't really figure it out until I had a deeper understanding of how making bread worked. It's time we build up our understand of how React works so that we can start to answer our questions with solid answers. React is made up of a few pieces: ~createElement~, ~render~, and reconciliation. The first building block is ~createElement~. While ~createElement~ is itself unlikely to be a bottleneck it's a good to understand how it works so that we can have a complete picture of the entire process. The more black-boxes we have in our mental model the harder it will be for us to diagnose performance problems. *** ~JSX~ But before we get to ~createElement~ we should talk about JSX. While not strictly a part of React it is almost universally used with it. And if we understand it then ~createElement~ will be less of a mystery since we will be able to connect all the dots. Before JSX the normal way of injecting HTML into the DOM was via directly utilizing the browser's DOM APIs. This was very cumbersome. The code's structure did not match the structure of the HTML that it output which made it hard to quickly understand what the output of a piece of code would be. So naturally programmers have been endlessly searching for better ways to mix HTML with Javascript. And this brings us to JSX. It is nothing new; nothing complicated. Forms of it have been made and used long before React adopted it. Now let's see if we can discover JSX for ourselves. To start with we need to create a data structure that both represents a DOM tree and can also be used to insert one into the browser's DOM. And to do that we need to understand what a tree of DOM nodes is constructed of. What parts do you see here? TODO include text element (Hello) TODO change to using objects instead of arrays? probably do after what we've already done { type: 'h1', props: { x: y }, children: [] } #+BEGIN_SRC html