-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inline styles.css in <head> #145
Comments
Actually... I have no idea if this is possible to do automatically. If someone knows, please do share. |
Possibly could use the val-loader. Output the styles.css file then sync load the file when generating the and inline the css if < 10 kb or just add a link to the external file. |
Actually easier than that. Just use the raw-loader to load the styles.css file. If it's over 10kb, include a link, if it's below 10kb, inline it. This could actually be turned into a react component pretty easily something like |
Loaders usually accept the |
Interestingly Google AMP's project says all css styles should be inlined in the and not be external files. Regardless of the size (though they say limit styles to 50kb)... https://www.smashingmagazine.com/2016/02/everything-about-google-accelerated-mobile-pages/ So perhaps this should be turned on by default. Webpack extracts and minifies CSS and then we inline it in the |
So played around with this a bit today. To make this work, we'll need to have a special styles build step it seems so that the extracted/minified |
Which is a bit weird perhaps + extra complexity but I think it's totally worth it. Inlining CSS in head in my testing improves time to first paint by ~300ms on even a very simple page by avoiding the extra request. |
I was able to get purifycss-webpack-plugin working with this gatsby-node.js: var ExtractTextPlugin = require("extract-text-webpack-plugin");
var Purify = require("purifycss-webpack-plugin");
exports.modifyWebpackConfig = function(config, env) {
if(env === 'production') {
config.removeLoader('css');
config.loader('css', function(cfg) {
cfg.test = /\.css$/;
cfg.loader = ExtractTextPlugin.extract(['css', 'postcss']);
return cfg
})
config.plugin('extract-css',
ExtractTextPlugin,
["styles.css", { allChunks: true }]);
config.plugin('purify-css',
Purify,
[{
basePath: __dirname,
resolveExtensions: ['.js, .html'],
paths: [
'html.js',
'components/**/*.js',
'pages/**/{*.md,*.js,*.html}',
'wrappers/*.js'
],
purifyOptions: {
info: true,
rejected: true,
whitelist: [
'*markdown*',
'*footnotes*',
'*webfonts-loaded*',
'*is-reverse*'
]
}
}]);
}
return config;
} (Explanation of Purify’s options, here.) As you can see, that implementation is quite fragile, requiring both specifically-defined file globs for the paths to scan and carefully selected whitelisted selectors (the The tool, PurifyCSS, also doesn't seem to work all that well. I have quite a few selectors in my styles (cssstats), and I expected at least of third of those to be un-used. But it only reduced the un-minified filesize by 9.5%, and here’s the full list of removed selectors:
I think this is largely due to my use of escaped characters in my classes, e.g. Worse, there are false positives in that list. My .md content uses ordered lists, but the tool doesn’t pick up on it because it scans the files before conversion to html. It’s that very last point that makes me think using a tool like PurifyCSS isn’t workable before the pages are built. And, the plugin can only output a file, so it doesn’t actually address the key aspect of this issue: inline the styles when they’re small. |
With #253 this is about ready to go once the new release is done. Checklist for finishing this up:
And some testing I just did with #253 with the blog starter. Switching to inlined css dropped the Speed Index score by 1/2(!!!) on both 3G and cable. Which is even a bigger drop than I expected. 3G: Cable: It's crazy but with inlining CSS, the site loads just as fast on 3G as not-inlined does on cable. Nuts. Also on cable the inlined css site is 89% visually complete in 0.5 secs. That's a fast website. This also scores us 100/100 on PageSpeed https://developers.google.com/speed/pagespeed/insights/?url=http%3A%2F%2F572ec371d6865d789f20e371.peddler-tapir-41575.netlify.com%2F&tab=mobile |
Tested this on my website relaterocket.co tonight for a more real-world test as this site uses https + custom fonts from Typekit. Redeploying with inlined css dropped the first-load PageSpeed from ~1600 to ~1000. Re-running the test multiple times and from multiple locations I saw significant variation from ~700-1400 but the majority at around 1000. Also re-running the same test seemed to speed up the tests. Perhaps the browser at the location does cache some things. Before: http://www.webpagetest.org/result/160511_SG_A5T/ |
So I ended up not adding the helper as well... I couldn't make it work. Webpack can still be incredibly confusing sometimes :-) I put in the helper |
But ignoring that, things are looking great! This is a fairly significant performance win. Next big win will be making it simpler to inline images in css. |
Oh and service workers of course 💥 |
Just wanted to drop a note here, just needed some quick css in the head. Used:
where inline-styles.css is in /src/ next to html.js |
Thanks.
Seems like the build process still spends a bunch of time building all that
client-side logic? I was actually more concerned with that, with
unnecessary build time, when I made those changes back then!
…On Fri, Apr 17, 2020, 7:00 AM ben-hamelin ***@***.***> wrote:
Just wanted to drop a note here, just needed some quick css in the head.
Used:
`let css = <style dangerouslySetInnerHTML={{ __html:
require('!raw-loader!./inline-styles.css') }} />
return (
<html {...props.htmlAttributes}>
{props.headComponents}
*{css}*`
where inline-styles.css is in /src/ next to html.js
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#145 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADME7L3AKIKGT5MSYALNDLRNBOIHANCNFSM4B4J4LVQ>
.
|
No description provided.
The text was updated successfully, but these errors were encountered: