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