Reputation: 10620
I'm developing a project in React with Webpack in ES2015.
I am importing the styles as
import '../assets/main.scss'
it works fine, but seems to take longer than the rest of the page, so for a second, everything looks very ugly.
is there a way I can check if the style has been loaded before start rendering the page?
Upvotes: 2
Views: 3543
Reputation: 15642
"for a second, everything looks very ugly."
This phenomenon is called FOUC (Flash of unstyled content).
Since you are using webpack, you'd be using webpack loaders too. So the first level of optimization can be done in your webpack.config.js
.
Use webpack's ExtractTextWebpackPlugin.
It moves every
require("style.css")
in entry chunks into a separate css output file. So your styles are no longer inlined into the javascript, but separate in a css bundle file (styles.css
). If your total stylesheet volume is big, it will be faster because the stylesheet bundle is loaded in parallel to the javascript bundle.
The text in bold is our first key to kill FOUC.
example:
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
module: {
loaders: [
// Extract CSS during build
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style', 'css')
}
]
},
plugins: [
// Output extracted CSS to a file
new ExtractTextPlugin('[name].[chunkhash].css')
]
}
You can tweak this further to use different loaders for .scss
or .less
.
The
ExtractTextPlugin
generates an output file per entry, so you must use[name]
,[id]
or[contenthash]
when using multiple entries.
Create multiple instances of ExtractTextWebpackPlugin
if your want different bundles for your different loader patterns (as described in the last section of the API doc).
So what we achieve ?
devtool: "source-map"
and css-loader?sourceMap
)Nota Bene: There are some caveats for using ExtractTextWebpackPlugin
which are also described in the original documentation page.
Separate CSS bundle and Webpack's Code Splitting [official doc]
With Code Splitting we can use two different modes:
- Create one css file per initial chunk (see Code Splitting) and embed stylesheets into additional chunks. (recommended)
- Create one css file per initial chunk which also contains styles from additional chunks.
For big web apps it’s not efficient to put all code into a single file, especially if some blocks of code are only required under some circumstances. Webpack has a feature to split your codebase into “chunks” which are loaded on demand.
Code splitting can be done Using webpack's require.ensure
by defining multiple split. This is pretty easy to configure see official doc, or my own SO answer for a React.js-React-Router-Webpack application ;)
There was an an issue reported when async-injection of css splits ExtractTextWebpackPlugin
and require.ensure
are used together, and here is the unofficial solution for that (use file-loader and extract-loader combined):
{
test: /\.css$/,
loaders: ["style-loader/url","file?name=app/[name].[hash].css!extract","css-loader","postcss-loader"]
}
Needs more improvement?
Once we have configured ExtractTextWebpackPlugin
, further optimization of CSS can be done using PurifyCSS WebPack Plugin.
This is a plugin for WebPack that utilizes PurifyCSS to clean your CSS and removes unused code.
"Is there a way I can check if the style has been loaded before start rendering the page?"
Here is a list of reference links explaining some general techniques to minimize FOUC:
Upvotes: 8