mini-css-extract-plugin
mini-css-extract-plugin copied to clipboard
Add an `asyncMedia` option to prevent parser-blocking async css
- Operating System: All
- Node Version: v12
- NPM Version: v7
- webpack Version: 4 / 5
- mini-css-extract-plugin Version: Suggested to be 1.5.0
Feature Proposal
I would suggest adding an asyncMedia
option to the plugin that would allow loading of async css bundles with the media
attribute set to print
(or something else), which is then switched out to all
on load.
Eg.
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css',
chunkFilename: '[id].[contenthash:8].css',
asyncMedia: 'print',
}),
would add a link attribute with:
<link rel="stylesheet" type="text/css" href="..." crossorigin="anonymous" media="print">
and an onload
handler which would replace this with:
<link rel="stylesheet" type="text/css" href="..." crossorigin="anonymous" media="all">
when the stylesheet has been downloaded.
I would suggest the default for this option is print
but that it is customizable
Feature Use Case
This is the best practice way of loading async css – without it, the page pauses while downloading the async css as it's appended to the head.
This use case was previously mentioned in https://github.com/webpack-contrib/mini-css-extract-plugin/issues/721 , but it cannot be easily implemented due to the fact that the onload
attribute is in use by the plugin logic itself. For that reason I think it makes sense to implement this as an option in this plugin.
(I'd be happy to implement this myself if you think it makes sense)
https://github.com/webpack-contrib/mini-css-extract-plugin#attributes, you can do it using this, changing print
to all
is unsafe, because user can be in print
mode
Thanks for the suggestion – my understanding from https://github.com/webpack-contrib/mini-css-extract-plugin/issues/721 was that this specific use case wasn't supported with the attributes
option, due to the need to change the attribute in the onload handler, which is in use by the plugin. I agree that this is a tradeoff though as media="print"
might be a use case for some people (faux media attributes are another way of achieving this but that has its own drawbacks)
Why do you need this? I recommend to use rel="preload"
, it is widely supported right now, no need to support old browsers using unsafe hacks, also async loading will do FOUC, it is not good
I'm looking for a way to download CSS files without blocking javascript parsing. By inserting a <link>
tag into the document head, additional javascript parsing is paused until that CSS file download is complete.
If we were to add a rel="preload"
in the server response, there's a good chance that the file would already be downloaded by the time the <link>
tag is inserted, so that would partly solve the problem, yes. If that preload didn't complete (maybe it was too slow, or the preload request failed) I think this would still be needed.
An alternative is to instead of doing the <link media="print" ...>
to insert <link rel="preload" ...>
, but swapping that back to media="all"
or rel="stylesheet"
would still require some API to make that useful I think. An API suggestion for that would be:
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css',
chunkFilename: '[id].[contenthash:8].css',
asyncPreload: true,
}),
would add a link attribute with:
<link rel="preload" as="stylesheet" type="text/css" href="..." crossorigin="anonymous">
and an onload handler which would replace this with:
<link rel="stylesheet" type="text/css" href="..." crossorigin="anonymous">
One difference doing this would be that the CSS gets downloaded with the highest priority, but probably that'd be what you'd want in this case anyway.
By "async" what I mean is really what the plugin does already, here: https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/src/index.js#L783 . My understanding was that this type of insertion would be safe against FOUC because it doesn't call resolve() until the onload
handler is complete
It still have FOUC
when we change media
Close in favor https://github.com/webpack-contrib/mini-css-extract-plugin/issues/949