These modern tools further diminish the role of server-side HTML generation and HTTP form processing in favour of manipulating the DOM within the browser and calling out to server-side REST services.
So we got together to talk about how this impacts modern software development practice.
React and Angular are two popular UI frameworks, but what’s the difference?
DC: They are different beasts, Angular is a full MVC framework, and React is just a view layer with an ecosystem around it that will give you everything, but you can take bits as you want, so it’s effectively like how we view microservices. You take little bits in and out. React is the extreme view of that, Angular is the more monolithic view.
CA: React is nice way for developers not to have to interact with DOM directly. Angular gives you that, and a whole slew of everything else you could possibly need under the sun, and a sink. If all you need is that your DOM manipulation is too complex, React helps you to solve that by giving you a good set of conventions, a good set of technologies, lots of support. Adopting Angular is more of a case of rewriting your whole app in the Angular way.
What do they do?
DC: React is just a view layer nothing else, it isn’t a full framework like Angular that does Models, Views and Controllers. All you do is define some components in React, modularly, and it helps you render elements on the page.
The magical thing in React, compared to most frameworks is this concept of a virtual DOM, so when you make changes, instead of doing direct DOM manipulation on the page, which can be quite slow, it updates a virtual DOM, and then in cycles does a diff comparison between the actual DOM and the virtual DOM, only making necessary changes to the actual DOM. That’s where the magic of React comes in.
The main key of it, to me, is that it makes everything really easy from a developer’s point of view, to build UI with, because you’re just creating composable UI elements and patching them all together. It’s really that simple.
How does React work?
DC: The Flux pattern is a really common way to write apps in React. Redux is a really popular implementation of this pattern. React is unidirectional, you can’t go back and edit the state from your UI whatsoever.
AH: Yes, so your UI components can trigger actions, you attach some data to the action and dispatch it, a UI component only has to care how it gets rendered, and what actions it makes.
DC: That’s a key difference between say, WPF apps, where you’re propagating events through to the UI elements with bidirectional flows, and React. In the Flux pattern, you have to call an action, it goes through a specific flow and that’s the only way you’re supposed to do it.
In things like XAML in WPF desktop apps, you tend to have bidirectional flow, where updates are pushing back and forwards, which can be a bit of a mess. That’s what this pattern is supposed to solve.
As you scale up with a bidirectional flow, as you get more controllers, more views, things start becoming intertwined, really difficult to test and really difficult to manage.
In this model, the UI components never directly interact with the state. They just create actions which cause functions to modify the state and the modifications to the state result in the UI being re-rendered. So, it’s a one-way data flow.
ND: So it’s a bit like CQRS for the browser?
DC: That’s right, yeah.
AH: React comes with some new tooling, pretty much all of the examples use ES2015 and JSX, and it makes sense to use packing tools like Webpack, and Node.js tooling for running unit tests.
It’s got classes, which you can extend, there’s a whole new slew of operators, rocket syntax from C# to create Lambda expressions instead of using the function keyword, it’s got async/await, destructuring, spread operators and stuff. It’s a very different language than what I knew.
BB: A lot of the examples are written in that, but strictly speaking it’s optional.
DR: So, ES2015, ECMAScript 2015, that’s the latest version?
AH: Yes, there’s definitely a time investment required to learn this stuff.
DR: So what’s JSX then?
AH: So, when you’re writing JQuery, you’d add elements to the DOM with a put [draws on board]
$("#id").append("<div/>") and all that. In JSX, you can return HTML-like syntax and there’s a parsed which will turn that into
BH: It’s in the context of a component, right, so you’re actually implementing a
render function for your React component, so it’s weird at the start, but it feels like you’re building a composable single thing you can use.
CA: And you can use your component names as tags in JSX. When it renders it, it expands out, instantiates another component, fills it in, and it’s composable that way.
DR: Ah, so that’s why I can’t understand anyone’s HTML any more?
Why is writing React useful?
??: Now we have the opposite extreme of when you had your HTML with inline scripts injected in it, we have inline HTML inside scripts. How are we determining that this is … better?
AH: It’s the reusability of the components. The component essentially defines an interface – the properties that it accepts and renders, the actions that are initiated by that component.
CA: Essentially, it’s a very lightweight template library that you have inline with your code instead of in a separate file.
React lets you have that state in the component, instead of being spread across input fields and the content of various HTML elements. It’s self-contained within that component, which makes that component reusable, but also allows you to build dynamic complex bits of UI and not have to worry about how it interacts outside of that component.
Having the HTML inline means that you just have to write the initial HTML and a bit of view logic and that’s it. You’re not worried about anything outside manipulating it.
DC: Yeah, using Mocha or another test runner.
ND: So what are the benefits from a developer perspective?
DC: It’s easier, it’s more testable. Performance is arguably better.
??: It doesn’t sound easier.
DC: It isn’t at first, it’s counter-intuitive at first, but once you start writing apps in it, you get the gist of it, you write UI faster because you can reuse things, and you where your abstractions lie.
CA: Because there’s an agreed set of conventions, plus this JSX technology, you end up with composable components.
DC: Progressive enhancement is still a big thing, and it’s possible to do server-side React, to render your HTML using isomorphic techniques. You’re still doing your styles with external CSS, there are some people who do it inline of course…
What’s the HTTP request lifecycle of a React application?
What’s the development experience like?
AH: Fortunately, React development tools are really good, and you can set breakpoints and all that kind of stuff in the browser, but you do need to understand a number of tools, npm, basics of Node.js, pick a testing library…
DC: There’s so many of them, that’s so annoying.
??: So is that in addition to Yeoman, Bower, Grunt?
AH: Not really.
??: So it’s a case of bin those, forget those?
AH: Pretty much.
You can do React without Webpack and Babel, but it’s the way to go.
CA: There’s a subtle distinction between simple and easy, it’s very easy to set up with one line of code, but you can end up not knowing what it’s doing.
CA: I like to imagine that these onomatopoeic names for the tools like gulp are named after the noises the developers make when they’re using them. [laughter]
BH: How does Webpack differentiate itself from Grunt? Grunt tasks can do bundling, minifying etc., how is Webpack different from that?
CA: It’s just that there’s a bit of crossover between the capabilities of each tool.
DR: How is that different, to say, Bower or AMD modules?
DC: Bower and AMD are like NPM, package managers.
DC: There’s some history in that, in NPM 2 (the previous version of NPM), all of your dependencies were installed in a tree-like structure. What you’d end up getting was duplicate dependencies, different modules requiring different things, and you’d just end up with this massive tree, but that was all server-side.
NPM 3 came along and was able to do the same kind of things, so took over and Bower was discontinued because of that.
DR: So AMD is just a specification for packaging stuff up is it?
DC: Yeah – AMD, Common.js, Systems.js do that, while package.js is a file for defining your required modules.
DC: When you do React apps, the server-side code effectively becomes a REST API. Where you’re just sending data, your single-page app (SPA) is handling all the view stuff. When you bundle it with your webpack etc., you’ve essentially got an index.html, and an app.js. It can be dangerous, because the app.js file can get quite big, like megabytes in size.
AH: So do you think all of these server-side frameworks are no longer required? We just need to produce JSON for consumption by React apps?
Is it leaning edge, or is it bleeding edge?
AH: I think most people who are starting a new web app today are making the decision between Angular or React. I don’t think many people are wondering which server-side framework they’re going to use anymore. The server-side way still works, rendering some HTML out to a form and then receiving a form post. It’s pretty simple, but it’s got some downsides, page transitions cause flicker, it’s not perfect. You end up writing a lot of mapping code of form posts to DTOs and database objects – a lot of monotonous code.
How much transpiling is too much?
BB: What you’re writing is source code, what gets executed on the computer is irrelevant. It’s the same as a compilation, [in any high-level language] there’s always going to be some difference between what you write and what gets executed.
CA: It’s less a case of the computer, but it’s the load of having multiple toolsets to stitch it all together. Each layer could fail, and someone has to pick through that when it does.
CA: The trend is that more tooling is improved tooling. You get to keep the old tools. [laughter]
DC: I can explain it. There’s a key difference, compilers are going from high level to low level, transpilers are going from one high level language to another with a view to supporting a wider range of browsers.
??: Minification is a step you can accept, because it’s giving you benefit, even though it’s going from more human-readable to less human-readable. Every layer up you go should be more human readable, you should be able to deal with it easier, and simpler.
DC: When you minify, you can still read it, it’s just a bit of a mess.
DR: We’re basically treating the browser as a commodity compute engine. You wouldn’t look at machine code and complain about it being unreadable.
How does this affect the cost of running an application in production?
AH: When you execute more of the logic in the browser, the CPU requirements of the server-side reduces. You can serve your React application out of a static S3 bucket at very low cost, you don’t even need a server behind it.
We’ve just said that all we need to do is to make REST calls, well, I can run up an API Gateway to create microservices driven by AWS Lambda and I’ve got completely serverless infrastructure to host my React app and provide backend services.
TW: It helps you to focus on what’s important. You might be able to get rid of a lot of complexity and not take on as many people to run the IT part of the service, allowing you to concentrate on providing features for your customers.
AH: It’s kind of amazing that right now, every page hit, every flicker of the screen costs us milliseconds of CPU time. We end up paying to run a full operating system for these machines.
CA: We had a customer struggling to carry out performance analysis on one of our React applications because the page transitions were instant and didn’t show up on server logs. They were monitoring the server logs to try and do a like-for-like comparison against the existing server-side rendered web application. There’s nothing in the logs, because the system wasn’t hitting the server at all.
AH: A React application feels faster than an ASP.Net application or similar, because the browser is downlading and re-rendering the whole page on page refresh. A React application only has to call a REST API, render components and swap out some DOM, at the cost of a higher cost of initial page load when the React app is loaded.
DR: The React applications I’ve used seem really snappy when you’re using them, but you have this up-front cost. You might think, well that’s only once when you first hit the application, but that’s the most important time. The first time someone gets to your website, if they’re waiting, they’re going to get bored and go somewhere else.
CA: The way that Facebook does it is to pre-render the page, and then take bits of the page over as and when those bits of the application load. To start with, it’s static.
Every page you go to now, has like a 1MB of graphics, moving videos, maybe it’s not that big a deal.
Is it a fast way to write applications?
CA: When teams are used to it, it’s fast, but to start with you’re going to be copying and pasting from StackOverflow a lot. [laughter]
- DC: Denis Craig
- CA: Craig Andrews
- AH: Adrian Hesketh
- ND: Neil Dunlop
- BB: Ben Brunton
- DR: Dan Rathbone
- BH: Ben Houghton
- TW: Tom Walton
Adopting React can provide many benefits, from reduced infrastructure costs for high scale deployments, perceptible improvements in user experience and a structured approach to UI construction, but comes to many at a retraining cost, and a cost of tooling complexity which can take the shine off the new technology.
Accordingly, finding people who know React and its tooling well is not easy, but for many organisations, the risks of being left behind in what’s essentially a step-change in technology are too great to hold back adoption, despite questions about whether Angular 2 will win out in the developer mindshare over React.