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

I don’t understand why the async stylesheet thing works:

  <link rel="stylesheet"
        href="$CSS&display=swap"
        media="print" onload="this.media='all'" />
The media query doesn’t match. Why does the browser even load the stylesheet? Shouldn’t it only load it if it starts to match? Especially for things like print stylesheets, where the media query will only become true by deliberate user action (unlike viewport size media queries where actions like rotating a device could cause them to start matching). Print stylesheets will be used by <0.0001% of users on almost all pages, and could easily be loaded only when the user tries to print the document.

The whole thing is a dubious technique anyway because it depends on JavaScript—if JavaScript is disabled, the stylesheet will now not load ever. You’re probably OK with that in a case like this (the fonts are deliberately optional), but inevitably with such techniques people start using them on stylesheets that actually are important, because “it makes the page load faster” or something.

P.S. Why the trailing slash on the tag? It’s completely useless, by definition, and trailing slashes can mislead people into thinking that you can close tags that way, which you can’t.




It is explained in the article how it works:

"This will implicitly tell the browser to load the CSS file in a non-blocking fashion, applying the styles only to the print context. However, the moment the file arrives, we tell the browser to apply it to all contexts, thus styling the rest of the page."

The browser ignores the file because it's just for print and can be loaded later on. But when the page is fully loaded (onload="..."), the media property is set to "all" and does not stay at "print". When this happens, the browser now knows it should load it as soon as possible and does so.

As you mentioned: if JS is disabled, the file will never load. The author states that his solution is not 100% perfect: "[Async webfonts] should always be considered an enhancement anyway, so we need to be able to cope without them; we can and should design decent fallbacks for use during their absence, and;"


You missed my point, or I didn’t explain it well enough. I’m saying: why is the browser even starting to load the stylesheet? It should see media=print and decide that it doesn’t need it at all, and only fetch and load it when the media query starts to match, or perhaps by heuristics when there’s a reasonable chance that it will soon match.

As it stands, browsers are fetching print stylesheets all the time (sure, at idle priority, but they’re still fetching them) even though they’re used less than once per million page loads. This seems silly.


This reminds me of the SEO industry, where people apply cheap tricks for years telling themselves they can outsmart Google, then suddenly there's a core update and all those sites get heavily penalized.

This will probably backfire on frontend devs the same way. A browser prefetching files that aren't needed in 99.999% cases (probably higher, who prints a random webpage in 2020?) sure seems like a bug, so that will probably get fixed someday, and people who applied this trick will wonder why their websites are all breaking down at once.

In general, do things that sound intuitive and coherent to you rather than things that are unintuitive and go against the platforms you are developing on. If someone advises you to go against the value proposition of Google Search (find interesting content) or against the value proposition of Google Chrome ("browse the web in a simple, secure, and faster way"), you might want to take a big step back and rethink this.


OP here: Simply because the only mechanism a browser needs is ‘a currently-matching media type’ or ‘not a currently-matching media type’. There is no need to add further checks for a specific media type; that would lead to added and potentially infinite complexity as new media types are added.


“Does the media query match” is certainly the simplest way to defer loading, but I think some leeway could be useful; the user agent may have ways of predicting when there’s a reasonable probability that the media query will match soon. Kinda like how <img loading=lazy> doesn’t load once the image is needed, but a short time before it’s probably needed.

Hmm, thinking about <img loading=lazy>, I’ve thought of a reason they might not load such stylesheets lazily: privacy leak, you’re notifying the server that the document may have been printed. Lazy image loading has been careful to address this situation so that it’s no new surface (e.g. browsers shouldn’t lazy load if JS is disabled, but if it’s enabled you’re not leaking anything new). But printing specifically? I guess there hasn’t been any way of detecting that the document has been printed, so doing lazy loading on stylesheets for different media types would reveal something new.


You can detect print very, very easily. I helped the NHS track print-users using this: https://csswizardry.com/2018/03/measuring-the-hard-to-measur...

Note that we can’t use `background-image: url();` here as browsers will not print background styles by default, so we’d likely miss the majority of cases.


Good point, I completely forgot about that vector. Then there’s no privacy leak, and I go back to not being able to see why they do it the way they do! :)


Stylesheets are different story to images. Stylesheets (that match a media type) are render-blocking whereas images are not. Lowering the priority of a non-matching stylesheet but still downloading it is a better option than JIT loading one.


I don’t believe it’s technically correct to characterise stylesheets as render-blocking; if they take too long to load, user agents may start rendering without them. (This used to happen regularly. Not sure if browsers do it less than they used to or if the conditions where it happens just occur less often these days.)

If you control your layout with JavaScript, things like orientation changes can take a short time to update after the viewport has altered. It’s not ideal, but it’s not awful either.

I disagree with your second claim. I assert (without statistics) that the chance that a print stylesheet will be needed are more than a million to one against (possibly closer to a billion to one). If that is so, I would much rather have printing a document take the extra second to fetch the print stylesheet, rather than needlessly fetching a lot of print stylesheets that I literally never use.


> I don’t believe it’s technically correct to characterise stylesheets as render-blocking…

But they are. There’s absolutely no question about that. A browser will only render in the absence of a stylesheet if a) there’s programmatic intervention from the developers (e.g. timeouts) or b) if the server ultimately responded with a TCP timeout because of an outage. In the latter case, rendering is blocked for 20s on Win and 80s on *nix. CSS is render-blocking. There are no two ways about it. You can verify either slowdowns or outages by using https://slowfil.es or a blackhole server respectively.

> If you control your layout with JavaScript, things like orientation changes can take a short time to update after the viewport has altered. It’s not ideal, but it’s not awful either.

In this scenario you’re CPU-bound and not network-bound. Dispatching render-blocking requests on a high-latency connection JIT is far worse than front-loading your CSS asynchronously with minimal priority.

> I disagree with your second claim. I assert (without statistics) that the chance that a print stylesheet will be needed are more than a million to one against

I agree that print stylesheets are very very very rarely needed. My point—which I stated already—is that to accommodate individual media types increases complexity in the browser for zero gains.


OP here: Important point is that it’s the file’s onload event and not the window’s onload event that we’re listening for.


> P.S. Why the trailing slash on the tag? It’s completely useless, by definition, and trailing slashes can mislead people into thinking that you can close tags that way, which you can’t.

Simple: so that XML parsers can load the HTML, as they are not aware of the HTML context which allows "unclosed" tags.


You wouldn’t parse an HTML document with regular expressions.

So why would you parse one with an XML parser? It’s just wrong. (And an effort doomed to failure if you ever have to deal with documents other people wrote, because very few will parse.)


I deal with boatloads of manually written XML and HTML (templates) at my job. It's simpler in mindset to always write something that can be parsed as XML and is not much overhead (a single byte ffs).


There are a lot of more XML parser than HTML5 parser in the world. That's an argument for polyglot markup, if you like the open web and HTML as an API.


> The whole thing is a dubious technique anyway because it depends on JavaScript—if JavaScript is disabled…

I address this twice in the article, which presumably you didn’t read.

> P.S. Why the trailing slash on the tag? It’s completely useless…

Are you just looking for things to be unhappy about?


As I said, in this case it’s deliberate and acceptable, but techniques like this have a pernicious way of being used in other more important places where they’re emphatically bad.

Concerning the trailing slash: it’s something I’ve long been puzzled about because it seems to me to be not merely pointless but slightly counterproductive. Here you’ve evidently deliberately inserted it, and I can’t for the life of me understand why people are doing this, so I’m asking.


It actually wasn’t a deliberate inclusion—I didn’t give it any thought, largely because it makes no difference and isn’t relevant to the topic of the article. Hopefully readers feel empowered enough to delete their own forward-slashes.




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

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

Search: