Hacker News new | past | comments | ask | show | jobs | submit login

Inline CSS has the benefit of not making a second HTTP request, as well as (if I recall correctly) rendering the page styled from the get go, as opposed to once unstyled and once again when the CSS has finished downloading.



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.

All in all I think developers have considered all options and chose the best solution for their particular use case.


If the stylesheet is less than a few kilobytes, it will generally be faster to inline it even for subsequent page views with an immutable cache header. Caches and separation into external files still aren’t free.

One other thing that is almost always overlooked is that you don’t tend to use all styles on a given page, and you could strip out the unused styles. For example, the front page linked here has over 4KB of stylesheet, unminified and with unused styles; minified, it’s 3KB; with unused styles removed (including the wonky body:hover), it’s about 662 bytes. Something in the vicinity of 1KB is for specific pages, and 1KB for editing (form fields and such). If you try actively minimising the front page (removing unnecessary whitespace and attribute quotation marks, minifying and paring the stylesheet, and removing a few pointless elements), the whole thing ends up under 3.4KiB (down from 7.8KiB).

(Mind you, most browsers can do some degree of intra-session sharing of an in-memory representation of a stylesheet, for performance and memory usage reasons, and doing this will thwart that. But that’s only likely to make things faster over inlining if you’ve got much heavier styles, dozens or hundreds of kilobytes, the sort that you wouldn’t be so likely to inline anyway.)

As for the “making additional requests thing”: you still have to remember latency, because you’re adding another whole round trip to the waterfall. In the case of bearblog.dev which is hosted somewhere on the other side of the world from me (I’m in Australia), that will add an absolute minimum of over 260ms, more commonly half a second or more. Inlining of small resources like this when you have a very short waterfall already significantly improves load performance. The HTTP/2 and HTTP/3 improvements are about requesting more than just a couple of resources: in a case like this if you had one HTML and one CSS resource from the same host, HTTP/2 would not improve anything over HTTP/1.1.


Great points. I completely forgot about HTTP/2, thank you.


> 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!).


The browser can cache the http page too!


True, but they can’t cache a portion of the page that happens to be shared across every page on the website. If I go to a dozen different pages on the site, any in-http-page styles will be loaded a dozen times, while a separate style sheet will only be loaded once.


True but blogs are not Facebook. People generally don't visit thousands of pages. 1 visit and bounce is very common for blogs.


Visiting 1 article then bouncing is the most common pattern for blogs by a long way.

Also the amount of time taken to download a CSS file is usually much less than the round trip time for requesting the file. Especially in the p90/p99 end of the latency distribution. Here in Australia, I can download a 10kb css file in less than 1ms. But simply requesting that CSS file from America will take 200ms.

For a blog, inlining the css is absolutely the way to go. Especially if the css is small (which it should be!).


Perhaps, though I thought the net benefit of newer http protocols was to make that second request very lightweight. Then it's also cached if they visit a second page on the blog.


It’s text and is transmitted gzipped. This is as close to a non-issue as I can think of.


Normally, yes, but the sales pitch is "no stylesheets" + "fast", etc. So it becomes a topic of interest.


Separate CSS has the advantage that it can get cached, so you ideally only transfer it once.


HTML can be cached too, with the right headers.


true, but for a blog, the html would be cached per page, which means that if you look at n pages the same css is loaded n times too.

depending on _how_ you cache it, there might be a cache invalidation round trip for your css (Q: has this changed? A: no), which might or might not transfer more data than your embedded css anyway.


Most blogs consist of more than a single html page and usually reuse the same styles.


True, but most visitors to your blog won’t read more than one page.


CSS is render blocking. The browser will never paint anything on screen until it’s downloaded and parsed in to a css object model.

Unless you’re hyper tuning the page load performance in some specific way I think CSS is usually best served as a separate asset with a very generous cache time.

If the entirety of the CSS is extremely minimal it can make sense to in-line it too. Especially if you can get everything in at under 14kb. (Initial TCP window size)


The issue you're describing only happens when JavaScriptis used to render the CSS.


The fact that this needed to be said is concerning.

There's no FOUC if you add a stylesheet to <head>, and it concerns me that people seeing that flash have come to expect it as a fault of CSS, when it's really these frameworks making a decision to load the stylesheet via javascript.


I completely agree. I'm promoting a concept called TACE to get back to the principles of the web that were being promoted between 2000-2010. I've realized that a lot of web developers these days don't understand the basic principles of HTML, CSS, and JS because they initially learned web development using a Javascript framework.

https://www.agraddy.com/introducing-tace


I feel like this is an overblown reaction to a single person getting something wrong in the internet? It's not really concerning that not everyone knows everything with a 100% degree of certainty.


Why is seeing plain text before the stylesheet is loaded considered to be worse than seeing nothing at all before the stylesheet is loaded?


reflow while you're trying to read something sucks


How does that make the website better though?


I don't know. You'll have to ask the people who made it.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: