Home > Mobile >  How to load CSS Asynchronously without Inline Scripts (comply with CSP)
How to load CSS Asynchronously without Inline Scripts (comply with CSP)

Time:09-22

I want to implement Asynchronously loading CSS files for faster performance. However I want security too, so I want my site to have CSP.

<link rel="stylesheet" media="print" class="AOcssLoad" .... onl oad="this.onload=null;this.media='all';" />

Without going into details it wants me to avoid things like onload and many other JS that are part of elements.

I want it to look like this

<link rel="stylesheet" media="print" class="AOcssLoad" href="" />

Please suggest a way to achieve Asynchronous CSS files without inline JS as used above.

We can use inline <script> tags or seperate JS files.

I tried the below code as an inline JS.. Below is the HTML for the JS,

<script  nonce="" type="text/javascript" data-exclude="true">

var Script = document.getElementsByClassName("AOcssLoad");
for (var i = 0 ; i < Script.length; i  ) {
    this.className  = " Loading";
    Script[i].addEventListener("load", function({
        this.onload=null;this.media="all";
        this.className  = " onl oad";
    });
}
</script>

While it works, it's highly unreliable.

I cannot comprehend the problem, but I shall say it works only 50% of the times, sometimes just reloading the page can solve/break the problem, with no apparent change to css/html/cache as such.

Please help me improve on this, or build a better approach for it.

Edit:

As Suggested in Comments I tried different methods, including the links to other resources from GitHub.

Those methods are unreliable I would say they work less than 50% of times. However I tried to use jQuery(document).ready() and add media="all" to all the css files, but that increases TBT (Total Blocking Time) thus impacting my site performance

CodePudding user response:

You could use a vanilla JS function based on jQuery .ready():

document.addEventListener("DOMContentLoaded", () => {
  document.querySelectorAll(".AOcssLoad").forEach(el => {
    el.media = "all"
    console.log(`Loaded: ${el.href}`)
  })
});
<link rel="stylesheet" media="print" class="AOcssLoad" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" />
<link rel="stylesheet" media="print" class="AOcssLoad" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap-utilities.min.css" />
<link rel="stylesheet" media="print" class="AOcssLoad" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap-reboot.min.css" />
<link rel="stylesheet" media="print" class="AOcssLoad" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap-grid.min.css" />
<h1>Hello world!</h1>

However, no matter which solution you choose, be aware you will have to deal with Flash of Unstyled Content (FOUC). Consider other approachs for managing your stylesheet files.

CodePudding user response:

why not inject it with

<script>
document.write("<link rel=\"stylesheet\" media=\"print\" class=\"AOcssLoad" href=\"\" />
");
</script>

and place the <script> tags right above the place where you want the <link> tag to be.

or just

<link rel="stylesheet" media="print" class="AOcssLoad" href="" />

nothing happens all except for the css will load asynchronously and you can have csp

  • Related