Here's a comparison of the same application with and without pre-rendering loaded on a simulated 3G connection and mobile device:
react-snap is not the only library that can pre-render static HTML content
for your React application.
is another alternative.
Why is this useful?
To solve this, many developers take the approach of rendering the application on the server instead of only booting it up on the browser. With each page/route transition, the complete HTML is generated on the server and sent to the browser, which reduces First Paint times but comes at the cost of a slower Time to First Byte.
react-snap uses Puppeteer to
create pre-rendered HTML files of different routes in your application. To
begin, install it as a development dependency:
npm install --save-dev react-snap
Then add a
postbuild script in your
This would automatically run the
react-snap command everytime a new build of
the applications made (
npm supports pre and post commands for main and arbitrary scripts which
will always run directly before or after the original script respectively. You
can learn more in the
The last thing you will need to do is change how the application is booted.
src/index.js file to the following:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
Instead of only using
ReactDOM.render to render the root React element
directly into the DOM, this checks to see if any child nodes are already present
to determine whether HTML contents were pre-rendered (or rendered on the
server). If that's the case,
ReactDOM.hydrate is used instead to attach event
listeners to the already created HTML instead of creating it anew.
Building the application will now generate static HTML files as payloads for each route that is crawled. You can take a look at what the HTML payload looks like by clicking the URL of the HTML request and then clicking the Previews tab within Chrome DevTools.
react-snap can be used for other frameworks than React! This includes Vue
and Preact. More instructions about this can be found in the
Flash of unstyled content
To help prevent this, the critical CSS, or the minimum amount of CSS that is
needed for the initial page to render, can be inlined directly to the
of the HTML document.
react-snap uses another third-party library under the
minimalcss, to extract any
critical CSS for different routes. You can enable this by specifying the
following in your
Taking a look at the response preview in Chrome DevTools will now show the styled page with critical CSS inlined.
inlineCSS option is still experimental. It is worth double-checking to
make sure styles are being applied correctly for your routes.
If you are not server-side rendering routes in your application, use
react-snap to pre-render static HTML to your users.
- Install it as a development dependency and begin with just the default settings.
- Use the experimental
inlineCssoption to inline critical CSS if it works for your site.
- If you are using code splitting on a component level within any routes, be
careful not to pre-render a loading state to your users. The
react-snapREADME covers this in more detail.