Load Google web fonts script link asynchronously - javascript

I'm trying to increase my website performance by doing some tweaks, and i have found the google web fonts scripts to load fonts
asynchronously, the problem is that the fonts loads
asynchronously but not the script src link so i just moved the problem with css to js.
My actual code is that:
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js"></script>
<script>
WebFont.load({
google: {
families: ['Oswald:400,300', 'Material+Icons']]
}
});
I've tried to use async and defer but on the script src but it didn't work (it eliminated the page block render but the fonts didn't loaded like the other scripts do with async).
So what's the best way to remove the script src link?

Try This.
<script>
WebFontConfig = {
google: { families: ['Oswald:400,300', 'Material+Icons'] }
};
(function(d) {
var wf = d.createElement('script'), s = d.scripts[0];
wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js';
wf.async = true;
s.parentNode.insertBefore(wf, s);
})(document);
</script>

Here ya go, include this in the body, right before </body> and not the head tag
<link href="https://fonts.googleapis.com/css?family=Noto+Serif" rel="stylesheet" lazyload>
This makes the font load after everything above it.
But instead of Noto Serif, use Oswald font in your case.
Answered originally by user "Paddy" here:
https://stackoverflow.com/a/40624546/6283055

Related

Uncaught ReferenceError: WebFont is not defined

I am testing the the pages for mobile friendly issues I am getting the page a mobile friendly but search console gives errors. I don't know why?
Uncaught ReferenceError: WebFont is not defined
I am getting this error as I test the page when I click view details as it shows some page loading issues. I am not able to figure out what it means?
You can load the web fonts asynchronously using the script below.
courtesy: https://usefulangle.com/post/259/load-google-fonts-javascript
<script>
WebFontConfig = {
google: {
families: ['Roboto:300,400,700']
}
};
(function(d) {
var wf = d.createElement('script'), s = d.scripts[0];
wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js';
wf.async = true;
s.parentNode.insertBefore(wf, s);
})(document);
</script>
I had a similar problem and I solve embedding my font using e.g.:
<link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">
Also, is important to load the CSS Asynchronously depending on your Font priority.
e.g. Webfont Lora 400
<link href="https://fonts.googleapis.com/css?family=Lora:400&display=swap" rel="stylesheet" media="print" onload="if(media!='all') media='all'">

Deferring CSS load, why is including preload <link> faster?

I'm testing out preloading and I'd like to know why including a preload link before a preload script is faster by a tenth of a second.
rel="preload" tells the browser to start downloading the stylesheet to not block loading. The script creates a stylesheet from the URL and applies it to the page. Why is the stand-alone-script not as performant?
<link rel="preload" href="https://unpkg.com/tachyons#4.8.0/css/tachyons.min.css" as="style" onload="this.rel='tachyons.min.css'">
<script type="text/javascript">
//<![CDATA[
if(document.createStyleSheet) {
document.createStyleSheet("https://unpkg.com/tachyons#4.8.0/css/tachyons.min.css");
}
else {
var styles = "#import url('https://unpkg.com/tachyons#4.8.0/css/tachyons.min.css');";
var newSS=document.createElement('link');
newSS.rel='stylesheet';
newSS.href='data:text/css,'+escape(styles);
document.getElementsByTagName("head")[0].appendChild(newSS);
}
//]]>
</script>
Preload + Script:
https://codepen.io/JulianNorton/full/GvxpVr/
Script only:
https://codepen.io/JulianNorton/pen/vJRLBK
The answer can be found in the MDN
preload has other advantages too. Using as to specify the type of content to be preloaded allows the browser to:
Prioritize resource loading more accurately.
The browser priorities this resource during pre-rendering, marking it as a "stylesheet" required for the critical rendering path, while the inline element's priority is lower.

How to defer load css files (for google speed insights)

I am trying to get a 100/100 score on Google Page Speed Insights. But it keeps telling me some css files are blocking content above the fold. How can I make sure those files are loaded after the main content is loaded? So that it doesn't show up anymore in Page Speed Insights.
I tried loading the files asynchronously using jquery, but this way the message still pops up at the page speed tool.
I tried the following:
<script>
var loadMultipleCss = function(){
//load local stylesheet
loadCss('myawesomestyle.css');
//load Bootstrap from CDN
loadCss('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css');
//load Bootstrap theme from CDN
loadCss('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css');
}
var loadCss = function(cssPath){
var cssLink = document.createElement('link');
cssLink.rel = 'stylesheet';
cssLink.href = cssPath;
var head = document.getElementsByTagName('head')[0];
head.parentNode.insertBefore(cssLink, head);
};
//call function on window load
window.addEventListener('load', loadMultipleCss);
</script>
With my own file paths ofcourse.
But for Google PageSpeed Insights this didn't work.
Can you share the link of the website you are optimizing?
Are you sure that your page is not cached somewhere?
There are two methods that worked for me:
A) You could just put the stylesheet tags after the closing </html> tag.
B) Another technique is to put following link tag into the head section:
<link rel="preload" id="stylesheet" href="/assets/css/below.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/assets/css/below.css"></noscript>
The drawback with method B is that not all browsers support rel=preload in the link tag and you will need to include the following polyfill:
<script>
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
!function(a){"use strict";var b=function(b,c,d){function e(a){return h.body?a():void setTimeout(function(){e(a)})}function f(){i.addEventListener&&i.removeEventListener("load",f),i.media=d||"all"}var g,h=a.document,i=h.createElement("link");if(c)g=c;else{var j=(h.body||h.getElementsByTagName("head")[0]).childNodes;g=j[j.length-1]}var k=h.styleSheets;i.rel="stylesheet",i.href=b,i.media="only x",e(function(){g.parentNode.insertBefore(i,c?g:g.nextSibling)});var l=function(a){for(var b=i.href,c=k.length;c--;)if(k[c].href===b)return a();setTimeout(function(){l(a)})};return i.addEventListener&&i.addEventListener("load",f),i.onloadcssdefined=l,l(f),i};"undefined"!=typeof exports?exports.loadCSS=b:a.loadCSS=b}("undefined"!=typeof global?global:this);
/*! loadCSS rel=preload polyfill. [c]2017 Filament Group, Inc. MIT License */
!function(a){if(a.loadCSS){var b=loadCSS.relpreload={};if(b.support=function(){try{return a.document.createElement("link").relList.supports("preload")}catch(b){return!1}},b.poly=function(){for(var b=a.document.getElementsByTagName("link"),c=0;c<b.length;c++){var d=b[c];"preload"===d.rel&&"style"===d.getAttribute("as")&&(a.loadCSS(d.href,d,d.getAttribute("media")),d.rel=null)}},!b.support()){b.poly();var c=a.setInterval(b.poly,300);a.addEventListener&&a.addEventListener("load",function(){b.poly(),a.clearInterval(c)}),a.attachEvent&&a.attachEvent("onload",function(){a.clearInterval(c)})}}}(this);
</script>
I wrote an article about optimizing a page from pagespeed 59 to 100 and you can see the before and after on following branches:
Before: https://github.com/storyblok/storyblok-express-boilerplate/blob/unoptimized/views/layouts/main.hbs
After: https://github.com/storyblok/storyblok-express-boilerplate/blob/master/views/layouts/main.hbs

Load css file before js

I had a internal style followed by a external style. I noticed the page was blank till the external css didn't load. So i changed it to the below code. Now the external css request is made after the js.
Why for both above and how do i make css request before js. Are there any advantages to it(css before js in below code).
<body>
<style>
body {
background: #333;
}
</style>
<script>
var headHTML = document.getElementsByTagName('head')[0].innerHTML;
headHTML += '<link type="text/css" rel="stylesheet" href="build/main.css">';
document.getElementsByTagName('head')[0].innerHTML = headHTML;
</script>
<!-- The polyfills js is generated during the build process -->
<script src="build/polyfills.js"></script>
Use setTimeout in a function which is called when the body loads.
<body onload="loadPage()">
JS
function loadPage() {
//code to load css
setTimeout(function() {
//code to load js
}, 1);
}
I think that would work. Hope it helps.
This happends because a page is rendered from top to bottom. So I suppose that browser renders you inline styles and goes executing inlines script which uppends link to a style. Then it goes further and executes external script. And after that it loads your newly appended stylesheet.
So, I'd be too naive to ask but why don't you just put your stylesheet link into the head?
Of course you should just put your css files like normal people do :). but if you really want to make it happen, it's gonna get as ugly as this code gets:
<script>
var head = document.getElementsByTagName('head')[0],
link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('href', 'style.css');
var sheet = "sheet", cssRules = "cssRules";
if (!('sheet' in link)) {
sheet = "styleSheet";
cssRules = "rules";
}
var waitForCSS = setInterval(function() {
if (link[sheet]) {
// now you can load your javascript files here like I did with CSS
// or just use any js code you want.
clearInterval(waitForCSS);
}
}, 10);
head.appendChild(link);
</script>
The way to do this is
<head>
<link type="text/css" rel="stylesheet" href="build/main.css">
<style>
body {
background: #333;
}
</style>
</head>
<body>
<!--
Rest of your code in body
//-->
<!--Body is going to end after the below //-->
<script>
window.addEventListener("DOMContentLoaded",function(){
var sc=document.createElement('script');
sc.src="build/polyfills.js";
document.head.appendChild(sc);
});
</script>
</body>
A webpage is parsed from top to bottom.
So, try put the style in your head tag and place the scripts in just before end of body tag
In the script,
add an eventlistener to window when the Dom content Loaded, make a script tag, append src and append it to Head.
It's important to load the style before anything because it's the visual of your page. It's the first thing the user see.
You change css too along with DOM using javascript. So it is preferred to load css first.
Adding a preload mostly did the trick
<link rel="preload" href="build/main.css" as="style">
The browser now made the request for css. Then it makes a call for js. Then it adds CSS tag to the head. Finally, tries to remakes the call to get CSS but since the call is in progress or done it just loads it. There is an issue of FOUC though if CSS takes times.

CSS delivery optimization: How to defer css loading?

I am trying to optimize the CSS delivery following the google documentation for developers https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery#example
As you can see in the example of inlining a small CSS file the critical CSS in inlined in the head and the original small.css is loaded after onload of the page.
<html>
<head>
<style>
.blue{color:blue;}
</style>
</head>
<body>
<div class="blue">
Hello, world!
</div>
</body>
</html>
<noscript><link rel="stylesheet" href="small.css"></noscript>
My question regarding this example:
How to load a large css file after onload of the page?
If you don't mind using jQuery, here is a simple code snippet to help you out. (Otherwise comment and I'll write a pure-js example
function loadStyleSheet(src) {
if (document.createStyleSheet){
document.createStyleSheet(src);
}
else {
$("head").append($("<link rel='stylesheet' href='"+src+" />"));
}
};
Just call this in your $(document).ready() or window.onload function and you're good to go.
For #2, why don't you try it out? Disable Javascript in your browser and see!
By the way, it's amazing how far a simple google search can get you; for the query "post load css", this was the fourth hit...
http://www.vidalquevedo.com/how-to-load-css-stylesheets-dynamically-with-jquery
A little modification to the function provided by Fred to make it more efficient and free of jQuery. I am using this function in production for my websites
// to defer the loading of stylesheets
// just add it right before the </body> tag
// and before any javaScript file inclusion (for performance)
function loadStyleSheet(src){
if (document.createStyleSheet) document.createStyleSheet(src);
else {
var stylesheet = document.createElement('link');
stylesheet.href = src;
stylesheet.rel = 'stylesheet';
stylesheet.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(stylesheet);
}
}
This is how you do it using the new way, without using any 3rd party library or extra JS:
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
link rel="preload" as="style" requests the stylesheet asynchronously.
The onload attribute in the link allows the CSS to be processed when it finishes loading.
"nulling" the onload handler once it is used helps some browsers avoid re-calling the handler upon switching the rel attribute.
The reference to the stylesheet inside of a noscript element works as a fallback for browsers that don't execute JavaScript.
In addition to Fred's answer:
Solution using jQuery & Noscript
<html>
<head>
<style>
.blue{color:blue;}
</style>
<script type="text/javascript" src="../jquery-1.4.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
if($("body").size()>0){
if (document.createStyleSheet){
document.createStyleSheet('style.css');
}
else {
$("head").append($("<link rel='stylesheet'
href='style.css'
type='text/css' media='screen' />"));
}
}
});
</script>
</head>
<body>
<div class="blue">
Hello, world!
</div>
</body>
</html>
<noscript><link rel="stylesheet" href="small.css"></noscript>
from http://www.vidalquevedo.com/how-to-load-css-stylesheets-dynamically-with-jquery
Using pure Javascript & Noscript
<html>
<head>
<style>
.blue{color:blue;}
</style>
<script type="text/javascript">
var stylesheet = document.createElement('link');
stylesheet.href = 'style.css';
stylesheet.rel = 'stylesheet';
stylesheet.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(stylesheet);
</script>
</head>
<body>
<div class="blue">
Hello, world!
</div>
</body>
</html>
<noscript><link rel="stylesheet" href="small.css"></noscript>
Try this snippet
The author claims it was published by Google's PageSpeed Team
<script>
var cb = function() {
var l = document.createElement('link'); l.rel = 'stylesheet';
l.href = 'yourCSSfile.css';
var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h); };
var raf = requestAnimationFrame || mozRequestAnimationFrame ||
webkitRequestAnimationFrame || msRequestAnimationFrame;
if (raf) raf(cb);
else window.addEventListener('load', cb);
</script>
There is a simple way to load CSS asynchronously with only link tag
<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">
media="print" tell browser to load CSS asynchronously that intended for print.
Onload set the link's media to all when it loaded.
Comapared to mahmoud answer, this approach doesn't prioritize fetching the css, which maybe not needed
More details are explained here
WARNING: body{background-image: url("http://example.com/image.jpg");} in css files will make your css files still render-blocking.
If you tried all the solutions above and you still get the render-blocking warning from PageSpeed insights then you probably have this style rule in your css files. After hours of tests it turns out that this rule is what making ALL of my css to be flagged as render-blocking resources at PageSpeed insights. I found the same issue has been discussed before.
I don't know why body{background-image: url(...) do this for all the css files!, although I have different images resources in the file for the buttons, icons, ...etc .
I fixed this by moving this rule from the .css file and put it in the inline styles. Unfortunately, you will have to break your css plan and put the rule in all of your layouts HTML files instead of being in 1 css file that is imported in all of your HTML layouts, but the 90s and green color in PageSpeed insights deserve it.
Fixed mine by introducing placing all css files at the bottom of the page, after the body tag. but this introduces a new problem, the page loads un-styled html for noticeable mili seconds before applying the style. For this I fixed by introducing a splash screen all styled on the page.

Categories