Get a Perfect Score of 100 on Google PageSpeed Insights
Recently, I was exploring on how to get a perfect score of 100 on Google PageSpeed Insights. I searched for days and did several trial and errors, finally I was able to get my static page to score 100. Bellow are some tips on how I was able to do it.
Checkout Demo site Run Demo site on PageSpeed Insights
- Use CDN – This allow users from a around the world to download static content from a closer source instead of spanning the Atlantic ocean to retrieve data.
- Compress your JS, CSS, Images and HTML. The more compressed you get your scripts / images, the faster the download will be.
- Get a faster hosting. Google also rank sites base on the amount of time spent to deliver your content to readers. According to Google, users tend to leave sites that take more than 3 seconds to load. So it’s important to to pick the right hosting for your website. Tip: new hosting sites are usually better because their servers are less crowded.
- Leverage browser caching. I always use the following config to enable caching for specific types of file.
ExpiresActive On ExpiresByType image/jpg "access 1 year" ExpiresByType image/jpeg "access 1 year" ExpiresByType image/gif "access 1 year" ExpiresByType image/png "access 1 year" ExpiresByType text/css "access 1 month" ExpiresByType text/html "access 1 month" ExpiresByType application/pdf "access 1 month" ExpiresByType text/x-javascript "access 1 month" ExpiresByType application/x-shockwave-flash "access 1 month" ExpiresByType image/x-icon "access 1 year" ExpiresDefault "access 1 month"
- Enable Gzip Compression – Gzip Compression allows your web server to provide smaller file sizes which load faster for your website users. The code below should be added to your .htaccess file.
mod_gzip_on Yes mod_gzip_dechunk Yes mod_gzip_item_include file .(html?|txt|css|js|php|pl)$ mod_gzip_item_include handler ^cgi-script$ mod_gzip_item_include mime ^text/.* mod_gzip_item_include mime ^application/x-javascript.* mod_gzip_item_exclude mime ^image/.* mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
The code above will work on Apache. If it’s not working there is another way that may work for you. Remove the above code from your .htaccess file and try this one instead:
AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript
In my experience, enabling Gzip Compression gives you most of the score difference on Google PageSpeed Insights.
- Get rid of render blocking scripts.
- If you put your scripts within the head tag of your HTML – the page will have to wait for the css and js to finish loading before it starts rendering your content. The best approach I found is to append css and js scripts dynamically to the header tag and in the end of body tag, that is – after DOM has completed loading. You can get the script here: https://gist.github.com/carlo-fontanos/abc69dfea9d1e853c0e49fe509dbaa4b
- Note that the loadScript() and loadStyle() loads the files asynchronously so if you have scripts that are depending on another script, ex. jQuery, then you should nest them like this:.
loadScript("js/script1.js", function(){ loadScript("js/script2.js", function(){ loadScript("js/script3.js", function(){ loadScript("js/script4.js", function(){ loadScript("js/script5.js", function(){}); }); }); }); });
- Observation: when you refresh your page you will notice that it loads an unstyled HTML for a few seconds then renders back properly after your critical stylesheets have been fully loaded – uhh.. that’s ugly. Let’s fix that! Within the head tag of your HTML (right after your meta tags), add the following styles:
<style id="init-style"> *{color:#fff; border:0; background:none;} img,button{display:none;} </style>
- The CSS code above TEMPORARILY sets all the elements to appear white and all images removed. Basically we are trying to make the screen appear like it’s still trying to load the content when actually the content is already there, but just not visible yet.
- If you look at the <styles> tag, it has an ID “init-style” – this will help us easily identify and remove it when all our critical css files have been fully loaded. So for example, we need to load a critical css file such as bootstrap: 1st is we load bootstrap dynamically, then 2nd we remove the initial styles from the header tag right after. Like this:
loadStyle("//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css", function(){ document.getElementById("init-style").outerHTML=''; /* Remove initial styles from your page */ });
- Combine CSS Files. Fewer HTTP requests for CSS content is better rather than loading a bunch individual CSS files. You can use this PHP script to combine multiple CSS files into a single file then compress it on-the-fly: https://gist.github.com/carlo-fontanos/f2ab6afaa71f29595b3f0d95f40ad2b0
I see a lot of posts complaining about scripts like Google Analytics being a render blocker. Well, if Google is cheating on you, you can cheat Google back:
This is the user-agent for pageSpeed:
“Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.8 (KHTML, like Gecko; Google Page Speed Insights) Chrome/19.0.1084.36 Safari/536.8”
You can insert a conditional to avoid serving the analytics script to PageSpeed:
<?php if (!isset($_SERVER['HTTP_USER_AGENT']) || stripos($_SERVER['HTTP_USER_AGENT'], 'Speed Insights') === false): ?> /* your analytics code here or any HTML element you want ignored by PageSpeed Insights */ <?php endif; ?>
or via Javascript:
if(navigator.userAgent.indexOf("Speed Insights") == -1) { /* your analytics code here or any HTML element you want ignored by PageSpeed Insights */ }
If your only concern is getting a 100/100 score this will do it.
Do you need help with a project? or have a new project in mind that you need help with?
Contact Me