Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Attempt At Scoring 100 On Google PageSpeed

DZone's Guide to

Attempt At Scoring 100 On Google PageSpeed

Paul Underwood makes some alterations to attempt to score 100 on Google's PageSpeed tool and break the one second load time.

· Performance Zone
Free Resource

Download our Introduction to API Performance Testing and learn why testing your API is just as important as testing your website, and how to start today.

With PageSpeed being so important to Google and other search engines, Google has created a nice tool to judge the speed and optimization of your website by using Google PageSpeed.

Before PageSpeed

First I'm going to start off by running PageSpeed on paulund.co.uk. This site isn't exactly resource-heavy so I'm expecting quite a high score to start with but there will be things we can do to improve the speed of paulund.co.uk.

As you can see on the first test running through PageSpeed paulund.co.uk is getting a score of 89/100 on desktop computers, this is a good enough score and I probably wouldn't have to do much work to get this to 100. But when you check the mobile score it's set to 73/100.

pagespeed-mobile

On the PageSpeed results page, it tells you areas that your site needs to improve on. We can now run a speed test from WebPagetest and see what speeds the pages are loading on so we can try to beat this after making all the improves we need.

paulund-webpagetest

Paulund Page Test

As you can see from this image it's currently loading in 1.52 seconds with a repeat view of 1.37 seconds, now that's pretty quick for a website but it could be better.

PageSpeed Best Practices

First, we're going to look at some of the best practices Google recommends to speed up your website:

  • Avoid landing page redirects
  • Enable compression
  • Improve server response time
  • Leverage browser caching
  • Minify resources
  • Optimize images
  • Optimize CSS Delivery
  • Prioritize visible content
  • Remove render-blocking JavaScript
  • Use asynchronous scripts

Avoid Landing Page Redirects

You should avoid any unnecessary HTTP redirects when a visitor lands on your page. For example, if you navigate to a site on your mobile, some websites pick this up and will redirect you to a mobile version of the site http://example.com -> http://m.example.com. Instead of doing this you should make your website responsive so there is no need to redirect the visitor to a new website.

Paulund.co.uk does not do any redirects on HTTP redirects and has a responsive design for when viewing on mobile devices so there is no need to do any further work on this.

Enable Compression

All modern browsers support gzip compression on all HTTP requests, and when gzip is enabled it can reduce the size of files by 90%. Gzip compression alone should drastically improve the page speeds of your website.

To enable GZIP compression on NGINX all you have to do is open the file/etc/nginx/nginx.conf find the section for HTTP and use the following settings:

# enable gzip compression
        gzip on;
        gzip_min_length  256;
        gzip_buffers  4 32k;
        gzip_proxied       any;
        gzip_types
            application/atom+xml
            application/javascript
            application/json
            application/ld+json
            application/manifest+json
            application/rss+xml
            application/vnd.geo+json
            application/vnd.ms-fontobject
            application/x-font-ttf
            application/x-web-app-manifest+json
            application/xhtml+xml
            application/xml
            font/opentype
            image/bmp
            image/svg+xml
            image/x-icon
            text/cache-manifest
            text/css
            text/plain
            text/vcard
            text/vnd.rim.location.xloc
            text/vtt
            text/x-component
            text/x-cross-domain-policy;
        gzip_vary on;
        # end gzip configuration

Improve Server Response Time

It is recommended that server response time is reduced to under 200ms. Server response is the time it takes for your server to render the HTML on the page. There are many factors that can contribute to slow response time such as slow framework logic, database queries, slow routing, CPU usage, and memory usage.

The hardest step to improve your server response time is to work out where the bottleneck is and use the data provided by your server hosts to analyze the resources to work out where the problem could lie. When using a framework or CMS, always refer to the documentation for the best performance practices.

Leverage Browser Caching

When the browser loads a page it will have to gather multiple resources over the network to render the page correctly. This will include HTML, CSS, JS, image etc. Having to do this on every page load can cause a large amount of transfer data, slowing down not only the client loading time but server response time. Having the ability to locally cache files means the browser is able to reuse previously fetched resources.

Each type of resource should have a defined caching policy (for example if the resource can be cached and for how long).

To leverage browser caching in NGINX you need to setup the caching policies like the code below.

# Expire rules for static content

# cache.appcache, your document html and data
location ~* \.(?:manifest|appcache|html?|xml|json)$ {
    expires -1;
    # access_log logs/static.log; # I don't usually include a static log
}

# Feed
location ~* \.(?:rss|atom)$ {
    expires 1h;
    add_header Cache-Control "public";
}

# Media: images, icons, video, audio, HTC
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
    expires 1M;
    access_log off;
    add_header Cache-Control "public";
}

# CSS and Javascript
location ~* \.(?:css|js)$ {
    expires 1y;
    access_log off;
    add_header Cache-Control "public";
}

This is a modified version of the expires.conf file as part of the h5bp project on github.

Minify Resources

Minifying resources such as HTML, CSS and JS will reduce the size of files that need to be transferred and therefore speeding up the download of these resources from your server.

Minifying will remove things that aren't needed for your page to render correctly such as comments, whitespace, long variables and long function names etc.

Optimize Images

Images will most likely be the biggest resource used on the web page, which is why it's very important to make sure they are optimized for the web page. Make sure you have selected the right format to get the smallest size while still keeping the quality of the images. Carefully choose the dimensions used for the image, as you are wasting resources if the image is too large and the browser has to automatically resize it. You may need to investigate on whether you need images at all and if they can be replaced by CSS.

Optimize CSS Delivery

Before a browser will render the page it must download and process all styles on the page. As a result, the browser will not render the page until all external stylesheets are downloaded and processed which may result in a slower first render of the page.

To learn more about render blocking CSS view the Google guidelines.

Render Blocking CSS

The normal way you would include CSS on the page is by using external CSS stylesheets and using the link tag. You will include these in the head tag.

<html>
    <head>
        <link rel="stylesheet" href="styling.css">
    </head>
    <body>
        <h1 class="page-title">Welcome</div>
    </body>
</html>

Inside styling.css file you can have critical styling for the page such as:

.page-title
{ 
    font-size: 3.6rem; 
}

Google's recommendation is to move all critical CSS to be inline styling on the HTML document, changing the HTML to look like this

<html>
    <head>
        <style>
            .page-title{ font-size: 3.6rem; }
        </style>
    </head>
    <body>
        <h1 class="page-title">Welcome</div>
    </body>
</html>

Remove Render-blocking JavaScript

Similar to how you can speed up the rendering of CSS, you can do the same for JavaScript. Any external files that need to be rendered can be placed directly inside the HTML to reduce the amount of HTTP requests the browser needs to make.

<html>
    <head>
        <script type="text/javascript" src="page-javascript.js"></script>
    </head>
    <body>
        <h1 class="page-title">Welcome</div>
    </body>
</html>

This can be replaced with:

<html>
    <head>
        <script type="text/javascript">
            /* contents of JavaScript file */
        </script>
    </head>
    <body>
        <h1 class="page-title">Welcome</div>
    </body>
</html>

Any external JavaScript files that aren't critical for the page to be rendered can be called by adding the async flag to the script tag.

<script async src="page-javascript.js">

Load Google Fonts Async

Most websites these days are using the useful Google web font library allowing you to import a huge library of fonts straight to your web page. When you run your website through Google PageSpeed it will highlight the Google web font script as a render blocking file. Using the WebFontLoader to load the web fonts on the page with async removes the render-blocking on this file.

<script type="text/javascript">
    WebFontConfig = {
        google: { families: [ 'Roboto' ] }
    };
    (function() {
        var wf = document.createElement('script');
        wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
            '://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js';
        wf.type = 'text/javascript';
        wf.async = 'true';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(wf, s);
    })(); </script>

Leverage Browser Caching - Google Analytics

The only thing I can't fix on Google PageSpeed is the error for browser caching on Google analytics script.

https://ssl.google-analytics.com/ga.js (2 hours)

Because I download this script from Google itself there isn't much I can change about it. The only possible solution I have is to download the script, store it locally, and apply browser caching to it. But then there's the problem of when Google makes a change to analytics, my site will not receive the change and I will have to re-download the file. For this reason, I've chosen not to do this and keep it as an external JavaScript file.

Results From PageSpeed

After making the above changes to the site what are the scores with Google PageSpeed now.

paulund-after-pagespeed

It's now getting a score of 97/100 with the two main problems being the server response time being at 0.38 and the Google analytics problems described above. With the server response time, I need to monitor the resources of the server a bit more to find the bottleneck or I might need to upgrade the server to be able to handle all the requests.

WebPageTest is now saying that paulund.co.uk takes 1.07 seconds to load on first visit and 1.002 seconds on second visit; that's an improvement of 0.45 seconds. The website already loaded quite quickly so I didn't expect the changes made above to make a huge difference but they managed to reduce loading by half a second and almost breaking the 1 second load time barrier.

Seeing these results means once the problems with the server response times are fixed it will most certainly break the 1-second barrier.

Resources

Here's a list of resources you can use to test the speed of your site, these will also give you recommendations on what you can do to improve the speed of your site.

PageSpeed

WebPageTest

Pingdom Tools

GTMetrix

Find scaling and performance issues before your customers do with our Introduction to High-Capacity Load Testing guide.

Topics:
performance ,google pagespeed service

Published at DZone with permission of Paul Underwood, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}