skip to Main Content

I’m reading about approachs to load CSS stylesheets asynchronously. One common way is as below:

<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">

It works fine. But today I see a large website using following way to load the CSS (to what they said that is asynchronously):

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

Notice the link have both preload and stylesheet and has as="style" at the end. I’m curious to know if it works that way, or it will be a blocking request?

Notes:

  • I already know common methods to loading the CSS asynchronously, this question is not about how to do it, I’m just ask about above method, as I don’t see it is documented anywhere.

  • I see common way is split preload and stylesheet into 2 links, so I’m thinking that using both of them in the same link will not work, this question is to asking for a confirmation.

2

Answers


  1. Chosen as BEST ANSWER

    I created a demo for this situation and below is what I observered.

    Prerequisites

    Create a CSS file that take long time to load.

    In below samples, it will be /style.css and it takes 5 seconds to load.

    Notes:

    • All of the tests was executed locally so it take ~0 second to load the HTML only.

    • All of the tests was conducted on Chrome v113, Windows 10 64bit.

    Tests:

    1. Normal case:
    <html>
      <head>
        <!-- normal way -->
        <link
          rel="stylesheet"
          href="/style.css" />
      </head>
      <body>
        <h1>normal way</h1>
      </body>
    </html>
    
    1. Media print + onload:
    <html>
      <head>
        <!-- media print then onload -->
        <link
          rel="stylesheet"
          href="/style.css"
          media="print"
          onload="this.media='all'" />
      </head>
      <body>
        <h1>media print then onload</h1>
      </body>
    </html>
    
    1. Preload + onload:
    <html>
      <head>
        <!-- preload then onload -->
        <link
          href="/style.css"
          rel="preload"
          as="style"
          onload="this.rel='stylesheet'" />
      </head>
      <body>
        <h1>preload then onload</h1>
      </body>
    </html>
    
    1. Preload + stylesheet on same link:
    <html>
      <head>
        <!-- preload + stylesheet -->
        <link
          rel="preload stylesheet"
          href="/style.css"
          as="style" />
      </head>
      <body>
        <h1>preload + stylesheet</h1>
      </body>
    </html>
    

    Results

    • Test 1: Page takes 5 seconds to load, has correct style when loaded.

    • Test 2: Page load instantly, takes 5 seconds to has correct style.
      Loading icon in tab bar appears for 5 seconds.

    • Test 3: Page load instantly, takes 10 seconds to has correct style (I was expect just 5 seconds).
      No loading icon.

    • Test 4: Page takes 5 seconds to load, has correct style when loaded.
      (Behavior is the same with Test 1).


  2. Adding multiple keywords in the same rel attribute will create one (internal) link per keyword.
    This means that when you do <link rel="preload stylesheet" as="style" href="... you will have both a non blocking preload link, and a potentially blocking stylesheet one.
    So this won’t work to make the style-sheet load in a non blocking way, because the stylesheet one will block and disable any benefit you could have had from preload.

    It seems that you can get a non-render-blocking <link rel="stylesheet"> by declaring it at the end of the <body>, though I’m not sure how "bullet-proof" this is.

    /* We're in <head> here */
    :root { --red-500: green; }
    span { color: var(--red-500); }
    <span>If the rendering is not blocked I should be green then red</span>
    <link rel="stylesheet" href="https://app.requestly.io/delay/1000/https://cdn.sstatic.net/Shared/stacks.css?v=e149631cb3f3">
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search