Rel=Preload for Stylesheet Isn't Applying The Styles Once Downloaded

rel=preload for stylesheet isn't applying the styles once downloaded

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

How to use both rel=preload and rel=stylesheet for the same tag?

For loading CSS styles asynchronously, you should indicate it, as a preload stylesheet. Whenever you use rel="preload" alone, it won't transform to stylesheet on page load and it will remain as preload, so to indicate it as stylesheet you should use another attribute such as as which indicate the type of element and in your case, it should be style. Then you need to tell the browser whenever the loading process got finished you need to consider this as a stylesheet, so you have to define another attribute like onload and then define its real relation.

so you have to import it like this:

<link rel="preload" as="style" onload="this.rel='stylesheet'" href="http://www.example.com/style.css">

NOTE: You can read more about it here in google developers.

UPDATE

Since preload is not supported in firefox until now (according to this), the only way to do it, is to declare it twice in the one rel tag or two separate tags.

<link rel="preload" as="style" href="http://www.example.com/style.css">
<link rel="stylesheet" href="http://www.example.com/style.css">

Or

<link rel="stylesheet" rel="preload" as="style" href="http://www.example.com/style.css">

NOTE: As @JohnyFree tested the second one (one with a line through) in the Google page speed, it won't be recognized as valid preload style, whilst the format is valid according to W3.org.

Why does CSS preload doesn't work or apply styles at all?

Basically, preload means that the browser has to download a resource before it's gonna use by the browser for some purpose. When you preload CSS, it means that the browser will start downloading your resource ASAP and apply it when it found a suitable command for that for example when it finds <link> tag for the stylesheet it will apply it instantly and hence first contentful paint will be improved.

There is also a concept here. If you download your CSS as a non-critical resource then you don't need to include <link> tag.

Syntax:-

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

But this thing is suitable only for deferring non-critical CSS. But for critical CSS you can include an internal stylesheet i.e. in <style>...</style> tags.

Read more about it here - https://web.dev/defer-non-critical-css/

When to use rel=preload? Why is preloading fonts/FontAwesome a good idea?

You will often see this recommendation if you use @font-face to load fonts in.

To understand why you get this recommendation you have to consider how the browser receives and parses information.

  1. HTML is downloaded, browser looks at all the assets to download it found in the HTML and starts downloading them and parsing them.
  2. The browser discovers a CSS file and downloads it. When that CSS file has downloaded and been parsed your browser finds a reference to your 'font-awesome' font and then adds that to the list of things to download.
  3. The browser downloads that font, but a lot later than it is needed.

By adding preload to the item your order changes to HTML first, then CSS and the font-awesome font at the same time, meaning a key asset is loaded earlier.

Why is this important?

To understand why this is important you need to understand 'critical requests' - those are all the assets required in order to render the 'above the fold' content.

Above the fold content is content you can see without scrolling the page.

Now if you have any icon showing in this 'above the fold' content then your font-awesome font becomes part of your 'critical request chain' - i.e. content that is essential to paint everything above the fold.

By using preload you get the font delivered sooner (2 steps not 3 as illustrated earlier), so your above the fold content can be rendered sooner and so your site appears to load faster - this is a major factor in PSI scoring and real-world conversion rate improvements.

Should I use rel="preload" then?

In most circumstances yes you should if it is recommended, it reduces your critical request chain depth and normally results in faster loading times. However you do need to check your critical request chain to ensure it isn't a false positive (PSI isn't perfect).

The easiest way to check is to open developer tools, enable 3G throttling on the network tab and then see if the page displays faster with or without preload.

Is it my best option for the scenario given in the question?

In this example, no, but only because font-awesome is not a good idea in general.

What you really want to do is get rid of font-awesome entirely. Icon Fonts are an out-dated and terrible practice us web developers have adopted that just won't go away.

Instead of loading a 50kb+ file (for each 'weight' of font-awesome you use) plus 30kb of CSS why not use inline SVGs instead.

Inline SVGs have several advantages, but the key ones are:-

  1. As they are inlined in the HTML you remove at least one network request (normally 2-3) - great for speed.
  2. They are tiny - a typical icon is less than 1kb unzipped - with 10 icons you said you use that is 10kb total before zipping. Compare that to 180kb zipped for font-awesome fonts, CSS etc. and you can see the performance improvement.
  3. As you have inlined your icons within your HTML you reduce your 'critical request chain' length, so you can get to sub 1 second initial page renders (obviously you need to inline all of your critical CSS required for the above the fold as well.)
  4. The most important reason - people use custom stylesheets on your websites. For example people with dyslexia may prefer a certain font as it is easier to read, so they may force a site to use that font. Your beautiful 'font icons' become the dreaded 'missing character square box of doom' - which makes it really difficult to know what they are clicking. Accessibility is becoming more and more important!

Note on point 2 - the reason icon fonts are so large is they contain hundreds of icons. It is possible to reduce them to be slightly smaller that inline SVGs but that kind of optimisation often gets over-looked and is actually more time consuming than simply inlining and referencing SVGs. I just thought I would add this for completeness.

How exactly does link rel=preload work?

In it's most basic form it sets the link that has rel="preload" to a high priority, Unlike prefetching, which the browser can decide whether it's a good idea or not, preload will force the browser to do so.

===A more in-depth look:===

Here's a snippet from W3c

Many applications require fine-grained control over when resources are
fetched, processed, and applied to the document. For example, the
loading and processing of some resources may be deferred by the
application to reduce resource contention and improve performance of
the initial load. This behavior is typically achieved by moving
resource fetching into custom resource loading logic defined by the
application - i.e. resource fetches are initiated via injected
elements, or via XMLHttpRequest, when particular application
conditions are met.

However, there are also cases where some resources need to be fetched
as early as possible, but their processing and execution logic is
subject to application-specific requirements - e.g. dependency
management, conditional loading, ordering guarantees, and so on.
Currently, it is not possible to deliver this behavior without a
performance penalty.

Declaring a resource via one of the existing elements (e.g. img,
script, link) couples resource fetching and execution. Whereas, an
application may want to fetch, but delay execution of the resource
until some condition is met. Fetching resources with XMLHttpRequest to
avoid above behavior incurs a serious performance penalty by hiding
resource declarations from the user agent's DOM and preload parsers.
The resource fetches are only dispatched when the relevant JavaScript
is executed, which due to abundance of blocking scripts on most pages
introduces significant delays and affects application performance. The
preload keyword on link elements provides a declarative fetch
primitive that addresses the above use case of initiating an early
fetch and separating fetching from resource execution. As such,
preload keyword serves as a low-level primitive that enables
applications to build custom resource loading and execution behaviors
without hiding resources from the user agent and incurring delayed
resource fetching penalties.

For example, the application can use the preload keyword to initiate
early, high-priority, and non-render-blocking fetch of a CSS resource
that can then be applied by the application at appropriate time:

<!-- preload stylesheet resource via declarative markup -->
<link rel="preload" href="/styles/other.css" as="style">
<!-- or, preload stylesheet resource via JavaScript -->
<script>
var res = document.createElement("link");
res.rel = "preload";
res.as = "style";
res.href = "styles/other.css";
document.head.appendChild(res);
</script>

Here's a really in-depth description from the W3C spec.

Global support is good across modern browsers, at ~93% (as of June 2022).

link preload doesn't seem to change the download priority level

<link rel="preload"> does not change Chrome's internal "priority" for downloading an asset, it simply instructs Chrome when to start the download.

The resource is loaded with the same priority as it would otherwise, but now the browser knows about it ahead of time, allowing for the download to start earlier.

A stylesheet or font will still be considered Highest priority, and a video will still be considered low priority. But Chrome will start downloading an asset immediately when it encounters the <link rel="preload"> tag.

Note that <link rel="preload"> is a compulsory instruction to the
browser; unlike the other resource hints we’ll be talking about, it’s
something the browser must do, rather than merely an optional hint.

Source: https://developers.google.com/web/fundamentals/performance/resource-prioritization

Is there any benefit in using link rel=preload or link rel=preconnect for resources on the same domain as the original page?

preconnect will have no effect (you are already connected to the domain).

preload will have an effect (causing resource to be fetched immediately, without waiting to discover where in the page is it used).



Related Topics



Leave a reply



Submit