Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait for CSS to load before JS in React [FOUC]

We are building our new website entirely in React and utilizing code-splitting & scss. Whenever a new page is requested it loads the raw HTML in the browser first and then a split second or so later the css styling comes in, seems to be a FOUC issue. This makes for a terrible experience and we need to figure out how to ensure the CSS is loaded before rendering the component(s). Does anyone have any experience with this? There seems to be a lack of information online currently with this issue. We currently have 10 js chunks but only one main.XXXXXXX.css.

like image 678
Gregg Avatar asked Mar 26 '18 16:03

Gregg


People also ask

Should I master CSS before React?

Every front-end developer starts their journey with HTML and CSS. So before you start learning to react you should have a good command of writing HTML and CSS.

Does React Native use CSS?

When working with React Native, by default it does not use HTML and CSS as a web application. In fact, right out of the box, everything is automatically styled based on Flexbox. In this article, you will be introduced to how to apply styling to React Native applications.

Is React faster than CSS?

using react may not be mandatory but it will help you have well organized and faster website th... Definitely more organized, but not faster. Nothing is faster than pure HTML, CSS, and vanilla JavaScript.


2 Answers

If you only ever have a single main.XXXXXXX.css file, then you should manually inject it into the <head> section of the initial html view and have the entry to your app (aka the initial JS file or some webpack manifest JS file) loaded at the bottom of the same html view.

For example

<html>
   <head>
      ...some header stuff
      <link type="text/css" rel="stylesheet" href="/path/to/main.XXXXXXX.css">
   </head>
   <body>
      <div id="react-app"></div>
      <script src="/path/to/vendor.js"></script>
      <script src="/path/to/app_entry_or_webpack_manifest.js"></script>
   <body>
</html>

I am assuming you have a server that is serving up at least a page that looks similar to the above. In this case (above), your CSS will load before your JS and you should avoid the FOUC issue.

This problem becomes much more difficult if you have many css files, dynamically generated (via code splitting) as you break your app apart, but it doesn't sound like you have that problem yet.

Edit: Just realized that you may not know how to inject a dynamically created css sheet into your entry html file. If you use mini-css-extract-plugin then you can specify the filename it produces. In this example, you can see you can optionally include a [hash] or not. You prolly don't want the hash.

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== 'production'

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: devMode ? '[name].css' : '[name].[hash].css',
      chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
    })
  ],
  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader',
        ],
      }
    ]
  }
}
like image 185
Timothy Beamish Avatar answered Oct 26 '22 03:10

Timothy Beamish


I can think of two options:

  1. Call the css inside the index.js of your react app.
  2. Render the react app after the DOM is loaded. Try adding something like this in your index.js react file:
    document.addEventListener("DOMContentLoaded", function(event) {
      ReactDOM.render(
        <App />,
        document.getElementById('root')
      );
    });

I consider that the best practice is that the HTML styles rendered by a ReactJS component should be called in that component. So I prefer option 1. Note: if the css file is a global file, you can consider a refactor to have only the styles of the component inside the component.

like image 30
Nico Diz Avatar answered Oct 26 '22 03:10

Nico Diz