Twitter Lite and High Performance React Progressive Web Apps at Scale

Before Reading On:

Optimizing for the Browser

Use Route-Based Code Splitting

Timelines from before (left) and after (right) code splitting. Click or tap to zoom.
We also ran the site before (left) and after (right) through Google’s “Lighthouse” web application auditing tool.

Avoid Functions that Cause Jank

Most devices today refresh their screens 60 times a second. If there’s an animation or transition running, or the user is scrolling the pages, the browser needs to match the device’s refresh rate and put up 1 new picture, or frame, for each of those screen refreshes.

Each of those frames has a budget of just over 16ms (1 second / 60 = 16.66ms). In reality, however, the browser has housekeeping work to do, so all of your work needs to be completed inside 10ms. When you fail to meet this budget the frame rate drops, and the content judders on screen. This is often referred to as jank, and it negatively impacts the user’s experience. — Paul Lewis on Rendering Performance

It may not look like much, but before (left) while scrolling, we would cause render jank by trying to calculate the height of various elements. After (right) we cause no jank and reduce the stuttering while scrolling timelines at fast speeds. Click or tap to zoom.

Use Smaller Images

Large images (left) can block the main thread from continuing for 18 frames. Small images (right) take only about 1 frame. Click or tap to zoom.

Optimizing React

Make use of the shouldComponentUpdate method

Liking the first Tweet caused both it and the entire Conversation below it to re-render!
Before (left), when liking an unrelated Tweet, entire Conversations would update and re-render. After adding shouldComponentUpdate logic (right), you can see that the component and its children are prevented from wasting CPU cycles. Click or tap to zoom.

Defer Unnecessary Work until componentDidMount

By deferring non-essential code paths from `componentWillMount` to `componentDidMount`, we saved a lot of time to render Tweets to the screen. Click or tap to zoom.

Avoid dangerouslySetInnerHTML

Before (left), you’ll see it takes roughly 20ms to mount 4 SVG icons, while after (right) it takes around 8. Click or tap to zoom.

Defer Rendering When Mounting & Unmounting Many Components

Without deferring rendering, the navigation bar takes time to respond.
Our HigherOrderComponent, as written by Katie Sievert.
const DeferredTimeline = deferComponentRender(HomeTimeline);
render(<DeferredTimeline />);
After deferring rendering, the navigation bar responds instantly.

Optimizing Redux

Avoid Storing State Too Often

Comparisons of the amount of time it takes to update after each keypress while dispatching the change to Redux and when not. Click or tap to zoom.

Batch Actions into a Single Dispatch

A comparison using the React Perf extension for Chrome without batch-dispatch in Redux (left) vs with batch-dispatch (right). Click or tap to zoom.

Service Workers

Pre-Cache Assets

Network asset load times without ServiceWorker pre-caching (left) vs with pre-caching (right). Click or tap to zoom.

Delay ServiceWorker Registration

<script>
window.navigator.serviceWorker.register('/sw.js');
</script>
Notice how when registering your service worker immediately, it can block all other network requests (left). Deferring the service worker (right) allows your initial page load to make required network requests without getting blocked by the concurrent connection limit of the browser. Click or tap to zoom.

--

--

--

Writing React.js on @Twitter Lite.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Lazy Load YouTube Videos Using <iFrame/>

Building a Chat App on React and AWS Amplify (Part 3)

How loading JavaScript can slow websites down (even if it’s asynchronous)

Make Smooth Page Transitions with React Router

My Journey to Using Async / Await

React Native Structure Folder — For Simplicity

Methods as props + conditional rendering in React.

Gatsby.js — SASS, Plugins, Themes, and Data Sources

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Paul Armstrong

Paul Armstrong

Writing React.js on @Twitter Lite.

More from Medium

Concatenated strings vs ES6 template literals in React

Let’s Get a Handle on Event Handlers

UseState and UseEffect with React

Its a Match!