49

I'm trying out rel=preload for the first time, using it for a couple of stylesheets. Here is the code in question:

<link rel="preload" href="css/styles.css" as="style">
<link rel="preload" href="//allyoucan.cloud/cdn/icofont/1.0.0beta/css/icofont.css" crossorigin="anonymous" as="style">

I'm testing in Chrome 61, and I can see that the stylesheets are downloaded as expected, however they're never actually applied, and I get the message on the console saying that a preloaded resource isn't being used.

If I remove the rel=preload in favour of just rel=stylesheet, then it works perfectly fine.

Is there something I'm missing?

Hack it
  • 359
  • 1
  • 10
Denno
  • 1,790
  • 3
  • 17
  • 26
  • 3
    Did you include `` for each of them as well? Preloading isn’t really useful on stylesheets like that because they’re already in the `` anyway. – Ry- Oct 17 '17 at 10:37
  • Oh right, I somehow missed that in the online examples.. Thanks – Denno Oct 17 '17 at 10:39

4 Answers4

49

What do you think about this approach:

<link rel="preload" href="style.css" as="style" onload="this.rel='stylesheet'">

Resource: https://www.filamentgroup.com/lab/async-css.html

M. Paulikas
  • 730
  • 9
  • 14
  • 3
    Despite its inline js nature, I find this to be most in line with DRY and therefore I consider it a more elegant solution than the accepted answer. Cheers! – Chad Jan 23 '19 at 22:10
  • Amazing. Thank you so much for this. It's beautiful. – Alex Morris Oct 01 '20 at 20:40
  • Only issue I see is that it jumps a bit on load. Might be that I need to inline my header style – Alex Morris Oct 01 '20 at 21:30
  • 1
    This won't work in Firefox, like @John says, you need both rel="preload" and rel="stylesheet" – Mario Nezmah Jan 19 '21 at 10:00
  • 1
    Also won't work in IE11 or pre-chrome Edge, in case you need to support those https://caniuse.com/link-rel-preload – ptim Feb 02 '21 at 06:50
37

You need to have 2 lines for each one with rel=stylesheet and one with rel=preload. As preload is just fetching it and not applying.

However you will probably not notice much performance improvement as it hits one line just before the other.

The better option is to inline the css (see here) that is seen above the fold then use javascript to add in the in the css file on page load (see here).

John
  • 28,415
  • 18
  • 87
  • 126
  • Same answer here that I replied to Ryan in the comment. I've only got a small application so there probably isn't much point trying to use preload at all.. Thanks for the in depth answer – Denno Oct 17 '17 at 10:40
  • I agree all depends on the application, I have seen significant savings doing this on large applications but it is quite a bit of work to keep it manageable. – John Oct 17 '17 at 10:43
12

Technically, you can specify multiple values for rel attribute. Something like this should do the job, without writing 2 lines per stylesheet:

<link rel="preload stylesheet" href="/css/styles.css" as="style" type="text/css" crossorigin="anonymous">

You can verify this using Lighthouse. This was result on my browser (there was no chained request as stylesheet was preloaded, and was properly applied):

lighthouse audit

brc-dd
  • 6,933
  • 3
  • 26
  • 51
  • Very nice solution, thanks a lot for sharing! Like it much more than inline applying JS :) – dave0688 Jun 08 '21 at 17:32
  • Works in the browsers I care about. Thanks! – Cliff Helsel Jul 01 '21 at 18:19
  • 1
    is `crossorigin` required for stylesheets? – Crashalot Aug 12 '21 at 23:34
  • Thanks a ton.. let me give a try.. – Developer Jan 18 '22 at 20:49
  • According to [this question/answer](https://stackoverflow.com/a/61889123/1191147) this solution doesn't work, and it's not that old either. Are you sure you're reading Lighthouse correctly? – Hashim Aziz Mar 02 '22 at 01:04
  • 2
    @HashimAziz that answer looks like it has outdated information, it seems to contradict [MDN's "rel" docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel). In my case, this does fix the Lighthouse warning about critical request chaining. – Chris Hayes Apr 13 '22 at 18:53
4

The accepted answer is correct but not very clear. For one file, you need 2 lines, and not one:

<link rel="preload" href="css/styles.css" as="style"> 
<link rel="stylesheet" href="css/styles.css">

I used this approach mostly because of css background images. Apparently this will speed up the loading.


You can see this approach in a similar fashion for google fonts links:

<link rel='preconnect' href='https://fonts.googleapis.com'> 

<link href='https://fonts.googleapis.com/css2?family=Source+Serif+Pro:wght@300&family=Source+Sans+Pro:wght@300;400;600&display=swap' rel='stylesheet'>  

It's also useful for fonts. See Mozilla Docs

André Chalella
  • 13,084
  • 9
  • 51
  • 61
Minsky
  • 1,991
  • 5
  • 16