The goal of this repository is to demonstrate CSS split with Webpack 4, mini-css-extract-plugin and dynamic imports.
The idea is to discriminate the critical CSS by creating SASS files nameds *.critical.scss
.
Critical CSS is typically used to support Server Side Rendering (SSR) version of the DOM generated by React.
Both critical and on-demand CSS are extracted using one instance of mini-css-extract-plugin
npm install
npm run build
The modules are loaded like this (see webpack.config.babel.js
);
{
test: /\.s?css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader'],
},
Then the assets are generated by one instance of the plugins:
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[name].css',
}),
The distinction for critical and non-critical is done in splitChunks
.
// Extract the critical CSS into a dedicated file
styles: {
name: 'critical',
test: /(\.critical)\.s?css$/,
chunks: 'all',
minChunks: 1,
reuseExistingChunk: true,
enforce: true,
},
This outputs the following assets:
Asset Size Chunks Chunk Names
critical.css 68 bytes 0 [emitted] critical
critical.js 101 bytes 0 [emitted] critical
MyComponent.css 50 bytes 1 [emitted] MyComponent
MyComponent.js 436 bytes 1 [emitted] MyComponent
vendors.js 96.8 KiB 2 [emitted] vendors
main.css 31 bytes 3 [emitted] main
main.js 3.74 KiB 3 [emitted] main
index.html 399 bytes [emitted]
Entrypoint main = vendors.js critical.css critical.js main.css main.js
Both main.css
and critical.css
should be loaded as link
in the page. main.css
could
however be deferred, as illustrated below.
<link href="critical.css" rel="stylesheet">
<link
rel="stylesheet"
href="main.css"
media="none"
onload="if(media!='screen')media='screen'">
<noscript>
<link rel="stylesheet" href="main.css">
</noscript>