Vince
Vince

Reputation: 970

Loading CDN files via Javascript

I've been working hard to achieve 100/100 on Google Pagespeed (https://developers.google.com/speed/pagespeed/insights/) but I keep getting hungup when trying to use Javascript to download CDN based files. I get 'CAUTION: Provisional headers are shown.' and I assume it's blocking this kind of call for security reasons but I'm stuck.

I can call script files asycn like this, which Google likes:

<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js" async></script>

But what am I to do about the CSS files? If I call it the normal way:

<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">

Google complains and says I have a 'blocking CSS resources'.

Here's a copy of the code I've been trying to use so far:

var headID = document.getElementsByTagName("head")[0];
var cssNode = document.createElement('link');
cssNode.type = 'text/css';
cssNode.rel = 'stylesheet';
cssNode.href = '//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css';
headID.appendChild(cssNode);

Anyone have any suggestions?

Upvotes: 4

Views: 8429

Answers (3)

Vince
Vince

Reputation: 970

Here is the code I ended up creating to handle loading both css and js files async at the same time. Just put this at the bottom of your HTML before you closing tag and edit the loadjscssfile() calls as necessary.

<script>
    /* Beginning of async download code. */
    window.onload = function(){
        function loadjscssfile(filename, filetype) {
            if(filetype == "js") {
                var cssNode = document.createElement('script');
                cssNode.setAttribute("type", "text/javascript");
                cssNode.setAttribute("src", filename);
            } else if(filetype == "css") {
                var cssNode = document.createElement("link");
                cssNode.setAttribute("rel", "stylesheet");
                cssNode.setAttribute("type", "text/css");
                cssNode.setAttribute("href", filename);
            }
            if(typeof cssNode != "undefined")
                document.getElementsByTagName("head")[0].appendChild(cssNode);
        }
        loadjscssfile("//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css", "css");
        loadjscssfile("//fonts.googleapis.com/css?family=Open+Sans:300&amp;subset=latin,cyrillic-ext,latin-ext,cyrillic,greek-ext,greek,vietnamese", "css");
        loadjscssfile("/css/style.css", "css");
        loadjscssfile("//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js", "js");
        loadjscssfile("//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js", "js");
    };
    /* End of async download code. */
</script>

Upvotes: 2

mtt
mtt

Reputation: 1717

I'd suggest you to inline the styles for the critical path (above the fold): https://github.com/addyosmani/above-the-fold-css-tools
https://github.com/addyosmani/critical

Then load the other css async:
https://github.com/filamentgroup/loadCSS/

Upvotes: 0

Jimmie Tyrrell
Jimmie Tyrrell

Reputation: 1658

Google provides a good explanation of this here: https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery

It seems like they want you to inline CSS that is crucial to the page's initial display. Then load secondary CSS after. Since the bootstrap CSS is one large mix, I think it'll be non-trivial to separate crucial/non-crucial for your page.

Perhaps you can inline some duplicate CSS that exists in bootstrap.css

Upvotes: 0

Related Questions