This is probably not a very good general recommendation, but inline CSS actually makes quite a bit of sense to me when using React/Redux.<p>Style is generally heavily interconnected with app state in modern web apps, so why not take advantage of a sophisticated state management system like Redux to declaratively manage your styles along with your state rather than adding/removing class names at runtime imperatively? With React's implementation of inline-styles, you can treat your styles as just another piece of JS data in your state tree, and have the entire power of the JS language at your fingertips to compose/extend/manage them, including powerful functional transformations, a flexible and statically analyzable module system, and prototypical inheritance, if you're into that kind of thing.<p>With this approach, you completely remove any need for preprocessors, get rid of a whole class of CSS limitations like the lack of a proper module system, and global scoping and the associated specificity issues, and your components become truly self-contained by default.<p>That said, I don't have a lot of actual experience with this approach in practice, so I definitely could be missing some nuances and practical limitations. I'd love to hear some opinions/experiences regarding using inline styles in React/Redux.
This is the part that surprised me,<p>> Further, inline CSS on HTML elements is blocked by default with Content Security Policy (CSP).<p>I'm probably not up to date on this stuff, since I am not a web dev, but does this mean it's actually not <i>possible</i> to use `style=""` in your HTML elements any more? I thought it was not recommended, but more for organizational reasons, not security reasons. What is the reason?
I do not understand this particular example. They replace 4 lines of external CSS + 1 line of loading by 1 line of internal CSS + 2 lines of tags + 11 lines of JavaScript which then asynchronously loads 3 lines of CSS.<p>So we went from a blocking call and 5 lines of code to 17 lines and an async call. How is this in any way better than simply cramming the 4 lines of CSS internally? Maintenance will not be simpler because you will still probably have several rules to maintain over several files (and the inlining can be automated).<p>This seems like horrible over-engineered advice _especially_ for small CSS files.
Interesting. The sample code includes this bit:<p><pre><code> var raf = requestAnimationFrame || mozRequestAnimationFrame ||
webkitRequestAnimationFrame || msRequestAnimationFrame;
if (raf) raf(cb);
else window.addEventListener('load', cb);
</code></pre>
I've never thought to use requestAnimationFrame like that. When exactly does it fire? Is that the preferred callback these days for loading code after the page is "done" in some fashion? I've gotten used to using jQuery's `$(document).ready(..)` which as far as I know uses DOMContentLoaded or window.onload behind the scenes. When does the first animation frame happen in relation to those callbacks?
The problem i've always had with this, and the "above the fold" rule as it appears in the pagespeed insights tool, is the definition of "fold" varies wildly.<p>So I see CSS optimisation as a multi-step process.<p>* Switch to a component-based rendering architecture (I favour React)<p>* Map CSS rules directly to components (I use CSS Modules)<p>* Have a JavaScript entry-point per route. The entry-point should only contain what's needed for that route, common bundles can be used too (I use webpack for this).<p>* Have equivalent CSS entry points per route (again, Webpack).<p>* On initial (ie server) render, render a style tag into the document that contains the content of the relevant entry CSS. By definition this is very close to being only the CSS required for that page (if your components have various different classes depending on config, there may be some bloat here, not sure if there's a workaround).<p>* On that same render, don't include an external reference to the actual stylesheets. (At this point we're mimicking Google's advice)<p>* On first client-side navigation (yeah, i'm assuming you're using client-side routing), load the required stylesheets for the destination URL, remove the style tag, then continue the navigation.<p>I'm actually excited, because in the React ecosystem, we're not too far removed from this entire process being relatively trivial to implement. I'm assuming other ecosystems are similar.
> If the external CSS resources are small<p>It's not a general rule, it's just suggesting that your 50 character block of CSS (that might be dynamic or conditional) would be better off as part of the main markup than a separate request and all the overhead associated with that.<p>If your static CSS exists in lots of small files, you would strongly benefit from rolling them together.<p>Both these recommendations may change with new delivery models (ie HTTP2).
Offered example is missing this in the "you can inline" snippet:<p><pre><code> <head>
<noscript>
<link rel="stylesheet" href="small.css">
</noscript>
</head>
</code></pre>
..least whole point of this excercise is to make life a little bit more miserable for those pesky users who dare to disable js.
I agree that Google's recommendation here is a poor one in most cases.<p>It would be better to do the following:<p>1. Have only one or two external CSS files per page.<p>2. Serve CSS compressed when possible.<p>3. Ensure that CSS does not require any server-side processing or compression, that the server just spits out a .css or .css.gz file when the CSS is requested.<p>4. Ensure that the CSS files are relatively small.<p>5. Serve the CSS files with a very long cache time and with a version/hash string in the object name.<p>6. If feasible, make CSS changes relatively relatively rare.<p>If you do all of these things, adding the style into the web page will clutter your HTML and slow things down for frequent visitors. Yes, it might also increase perceived performance for some users who have not visited the site since the last change to the CSS.
You can automate this with the prioritize_critical_css filter in the PageSpeed module: <a href="https://developers.google.com/speed/pagespeed/module/filter-prioritize-critical-css" rel="nofollow">https://developers.google.com/speed/pagespeed/module/filter-...</a><p>(Disclaimer: this is what I work on.)
Over time I've developed some opinions not shared by most. I only use a framework when under extreme duress. I use static pages wherever possible. I measure payload size.<p>I'm also beginning to re-think CSS. I love CSS, but just like with OO, I'm thinking it may tempt us to think of structural considerations when we may just be wasting our time. I think the next app I write, I'm going to evolve my CSS, starting with inline styling, moving out to an inline style node in HEAD, then dynamically loading it from JS as in the Google example, and then finally using a class/series of classes.<p>In much the same way, in FP you can just make it work, then generalize, then group, then eventually create modules/classes full of generalized functions. This way of thinking seems to result in far quicker execution and far less complexity. Not sure if it translates to CSS, though. It'll be interesting to try it out.
This makes perfect sense for classes like ".article51_footer_wrapper_margin50", look up the rule, and sure enough it looks like `.article51_footer_wrapper_margin50 { margin-bottom: 50px; }`<p>Seriously, just inline rules like that. If it is only applied in one specific place across the entire site either because it cannot or does not need to be made more general, then inlining it is easier to maintain and understand.
Are there any findings about whether such godawful class names affect rendering performance? I mean just matching strings such as this one:<p>com-google-api-explorer-client-history-EmbeddedHistoryItemView_HistoryItemUiBinderImpl_GenCss_style-showHideHeaders<p>It's generally really hard for me to take HTML advice from google seriously, their page sources at best look mediocre, and at worst they make my eyes bleed. How can code so complicated lead to such bland looking pages? I know I'm kind of being snarky, but I can't help it. Just look at the source of that page and the linked stylesheets, look at google.com, heck, if you can find me just one elegant page I'll be grateful, because to this day I haven't seen a single one.
I remember a CSS class in some enterprise software I was working on several years ago:<p><pre><code> /* bold */
.bold {
font-weight: bold !important;
}
</code></pre>
It has became my favourite real-world example of CSS misusage :)
Note they mean inlining the css rules in a <style> block.<p>Not inlining the css as the style attribute of a tag.<p>The goal is not to have to fetch a second css page.
<p><pre><code> <script>
var cb = function() {
var l = document.createElement('link'); l.rel = 'stylesheet';
l.href = 'small.css';
var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
};
var raf = requestAnimationFrame || mozRequestAnimationFrame ||
webkitRequestAnimationFrame || msRequestAnimationFrame;
if (raf) raf(cb);
else window.addEventListener('load', cb);
</script>
</code></pre>
Seems like it's time for a <i>defer</i> attribute on <link>.
if you use the google pagespeed apache/nginx module it has an inline_css filter which does this for you, no need to cause yourself a maintenance problem.
Whatever happened to the programming rule of don't micro-optimize until you've measured the performance? There seems to be a lot of recommendations to do ugly things to websites in the name of optimization, but they still add complications that are hard to understand. Pictures used to by supposed to be optimized by pre-scaling them to the size they'd be displayed at. Now we have retina displays and that doesn't work anymore. You have to do more complicated things instead. HTML and co has become very low level-like and almost complex enough that perhaps humans shouldn't be doing it. It reminds me of the days of assembly language and all the ugly little tricks to squeeze out more clock cycles that are now handled by compilers.
Which mandates 'unsafe-inline' if you're using a content security policy (CSP).<p>>Banning inline script is the biggest security win CSP provides, and banning inline style likewise hardens your application.[1]<p>So which is it? Should we be moving away from inline scripts and CSS, and tightening it up with CSP, or is performance/fewer requests more desirable? Also, with HTTP2, the performance issue seems moot.<p>[1]<a href="http://www.html5rocks.com/en/tutorials/security/content-security-policy/" rel="nofollow">http://www.html5rocks.com/en/tutorials/security/content-secu...</a>
I'd also like to throw this into the conversation:<p>Inline styles also prevent the user from overriding styles with a custom style sheet (think color blind people). This isn't necessarily against ADA/508 compliance, but it should be taken into consideration.
I think that this is the wrong way for most websites to do CSS, as it contradicts both minimization+concatenation and HTTP2 best practices. If you have just one CSS file that's heavily cached and 100 KB (because you base64ed your webfonts to reduce request count), you should be fine.<p>Just last night, I tested trying to separate out my fonts from my CSS. Google Pagespeed Insights still threw a fit over no async CSS, even though the CSS was 5 KB. FFS, Goog! I decided against that madness.
OK, so this part is new to me:<p><i>Don't inline CSS attributes</i><p><i>Inlining CSS attributes on HTML elements (e.g., <p style=...>) should be avoided where possible, as this often leads to unnecessary code duplication. Further, inline CSS on HTML elements is blocked by default with Content Security Policy (CSP).</i><p>How effective is this, really? If I can inline a CSS class, then I can inject any style on any HTML element even if I can't inline an attribute. Am I missing something here?
I think this Google rule is too specific and in the same time too general for being alive.<p>The whole idea :<p>> Inline small CSS.<p>is too specific. I think when you work on a huge web-application you don't want to create such a bloat in your <i>layouts</i> and personally I don't think that this approach scales. On the other hand if you go with a simple web page, like a landing page with a couple of elements ... go for it.<p>> If the external CSS resources are small<p>What is "too small" anyway ? ( too general )
(Disclaimer: I'm not a coder, so I easily get overwhelmed by what others might see as very simple)<p>It may be better for delivery, but the second example is unreadable compared to the clean one. I can see why it's much better to add 15KB to your HTML file than having to request those 15KB from a separate file (one or two full round-trips of added latency :)).
I think this has been for a long time now and I expect to see everyone speak about how this is a bad recommendation. If the above-the-fold content can extracted with a gulp/grunt plugin and injected it gets even better. These are extreme measures needed for performance profits and anyone can choose to take them or simply ignore
Google's point here is to load a header really fast, the user will get this feeling that some progress happened, JavaScript will load the rest of the CSS after, while the rest of the page is getting loaded/rendered...<p>Still, I won't use their method.
We inline the front page CSS on <a href="https://pdftables.com/" rel="nofollow">https://pdftables.com/</a>, both for user experience and for SEO reasons.<p>The Node module UnCSS (<a href="https://github.com/giakki/uncss" rel="nofollow">https://github.com/giakki/uncss</a>) is working reliably for us, using PhantomJS to automatically extract the CSS rules we need for our front page.<p>The full CSS rules are then loaded at the end of the page - just in case UnCSS missed a browser specific or Javascript triggered rule, and to get the files into the cache.