> One might argue, that inline CSS cannot be cached by browser and are loaded with each HTTP document, thus increasing total download size. And using HTTP/2 making additional requests ain't such a big problem anymore.
I’ve spent a lot of time obsessing over this—and being perplexed by performance-focused web devs favoring inline styles generally. Here’s what I’ve found.
- External <link> stylesheets are exactly as you describe, with some important caveats depending on specifics of the actual page, site, host, resources, and other bundle characteristics.
- Perceived performance is almost universally better, for all network conditions I’ve tested, when at least a portion of a page’s styles are inlined in <head>. Yes, even with HTTP/2. Yes, even with optimal metadata hints which should degrade better on a slower network. The most reasonable conclusion I can come to is that the main document parser is so well optimized that beating it is like challenging the Harlem Globetrotters on “fundamentals”: you’re going to be right, some of the time; you’re going to lose, every time.
- The benefits of inline styles degrade pretty quickly for subsequent navigations, with appropriate cache headers. This is expected, but with perf (web or otherwise) validating assumptions isn’t something you should leave unspoken.
- Many hosts have bad cache headers, even those you’d expect to do better (glares at GitHub Pages, my host).
- While the benefits of inline styles degrade rapidly, the drawbacks rarely if ever accelerate enough to care except under the worst network circumstances. And the drawbacks of <link> stylesheets accelerate much more rapidly.
- Most of these facts are mostly unnoticeable, on most mainstream devices, for most of this audience. You have to measure to register a difference, and the measuring has a greater impact than any measurable implementation difference.
- The notable exception, one which users will notice regardless of their device capabilities or network conditions, is web fonts. If you load them, the best perceived performance strategy is to mark them optional. Even so, they have the greatest impact on perceived performance, on otherwise well optimized pages, on high perf devices with good network conditions.
- When loading fonts on a page, inline styles perform dramatically better than <link> stylesheets regardless of any other implementation detail or circumstance. They have better perceived performance if baseline styles like colors and basic typography are inlined as well. This is what is commonly glossed over (and sometimes overloaded to mean more) as “critical styles”.
- From this point on, <link> styles perform “the same or better” for a basically useless unit of “better”. Assuming a relatively flat request waterfall. HTTP/2 helps if you know your entire dependency graph upfront, which nearly no site does… and it doesn’t matter, because Push is dead or on its way out and that graph is meaningless if the client disregards it.
- Good luck knowing your dependency graph. The tools that are designed for it are concerned with JS bundles. Your best bet is the added build-time complexity of CSS-in-JS and dynamic atomic classes (which are both great, albeit an unpopular combination). If you don’t, you’re either serving redundant styles, too many (my personal preference, after critical styles), or you’ve rolled your own static analysis tool (please share!).
I’ve spent a lot of time obsessing over this—and being perplexed by performance-focused web devs favoring inline styles generally. Here’s what I’ve found.
- External <link> stylesheets are exactly as you describe, with some important caveats depending on specifics of the actual page, site, host, resources, and other bundle characteristics.
- Perceived performance is almost universally better, for all network conditions I’ve tested, when at least a portion of a page’s styles are inlined in <head>. Yes, even with HTTP/2. Yes, even with optimal metadata hints which should degrade better on a slower network. The most reasonable conclusion I can come to is that the main document parser is so well optimized that beating it is like challenging the Harlem Globetrotters on “fundamentals”: you’re going to be right, some of the time; you’re going to lose, every time.
- The benefits of inline styles degrade pretty quickly for subsequent navigations, with appropriate cache headers. This is expected, but with perf (web or otherwise) validating assumptions isn’t something you should leave unspoken.
- Many hosts have bad cache headers, even those you’d expect to do better (glares at GitHub Pages, my host).
- While the benefits of inline styles degrade rapidly, the drawbacks rarely if ever accelerate enough to care except under the worst network circumstances. And the drawbacks of <link> stylesheets accelerate much more rapidly.
- Most of these facts are mostly unnoticeable, on most mainstream devices, for most of this audience. You have to measure to register a difference, and the measuring has a greater impact than any measurable implementation difference.
- The notable exception, one which users will notice regardless of their device capabilities or network conditions, is web fonts. If you load them, the best perceived performance strategy is to mark them optional. Even so, they have the greatest impact on perceived performance, on otherwise well optimized pages, on high perf devices with good network conditions.
- When loading fonts on a page, inline styles perform dramatically better than <link> stylesheets regardless of any other implementation detail or circumstance. They have better perceived performance if baseline styles like colors and basic typography are inlined as well. This is what is commonly glossed over (and sometimes overloaded to mean more) as “critical styles”.
- From this point on, <link> styles perform “the same or better” for a basically useless unit of “better”. Assuming a relatively flat request waterfall. HTTP/2 helps if you know your entire dependency graph upfront, which nearly no site does… and it doesn’t matter, because Push is dead or on its way out and that graph is meaningless if the client disregards it.
- Good luck knowing your dependency graph. The tools that are designed for it are concerned with JS bundles. Your best bet is the added build-time complexity of CSS-in-JS and dynamic atomic classes (which are both great, albeit an unpopular combination). If you don’t, you’re either serving redundant styles, too many (my personal preference, after critical styles), or you’ve rolled your own static analysis tool (please share!).