rycus86/demo-site

View on GitHub
src/res/specs/pagespeed.md

Summary

Maintainability
Test Coverage
Once you have some metrics about browser timings from your site's visitors,
you might find that the experience is not that great when you're not connecting
to the site on *localhost* on your laptop.

A great tool that can help you identify some of the problems is *Google's*
[PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/)
that processes a page on your website and analyzes its performance from both
mobile and desktop perspective.
It also gives you helpful hints on how to resolve those problems.

![PageSpeed Insights]({{ image: pagespeed.png }})

You only need to enter the *URL* of the page you're looking to get more
information about and hit the *Analyze* button.
On my demo site I've got a few helpful tips on how to make it faster.

##### Browser caching

The static resources like images, *JavaScript* and *CSS* files where
served without or not long-enough cache expiration headers.
I have changed this easily to *1 month* in *Flask* using a simple configuration.

```python
app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 30 * 24 * 60 * 60  # 1 month
```

##### Optimize images

Optimizing images was an easy win since most of my images were screenshots
saved as is so there was definitely room for improvement.
*PageSpeed Insight* lets you download the optimized version of your images
or you can use any tools you like.

##### Eliminate render-blocking resources

The browser will not be able to render the page if it has resources to download
before the content, usually in the `<head>` section of the *HTML*.
For *JavaScript* you can try the `async` attribute on the `<script>` tag though
be aware that the scripts will be downloaded *and executed* in random order so,
if you have dependencies between your scripts, this might be tricky.
I opted for using the `defer` attribute which delays loading the *JavaScript* files
until after the page has finished parsing.

*CSS* was a bit trickier since you would normally want the content on the page
to appear looking nice so these usually live in the `<head>` section.
Still, you might have styles that *can* be loaded later, for content not visible
at first glance or elements that are lazy loaded.
I have changed my `<link>` tags loading non-critical *CSS* to:

```html
<meta name="custom-fetch-css" content="/asset/non-critical.css"/>
```

These are then turned into regular `<link>` tags with *JavaScript* once those are
loaded:

```javascript
lazyLoadCSS: function () {
    $('meta[name=custom-fetch-css]').each(function () {
        var placeholder = $(this);
        var href = placeholder.attr('content');
        
        placeholder.replaceWith(
            $('<link>').attr('rel', 'stylesheet')
                       .attr('href', href)
                       .attr('type', 'text/css'));
    });
}
```

##### Enable compression

I could easily enable this in *Nginx* as described already with a little
bit of configuration.

```
http {
  ...
  gzip on;
  ..
}

server {
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/svg+xml;
    ...
}
```

##### Other hints

My site's results were getting better in *PageSpeed Insights* but there were
still some more things to improve:

- Reduce server response time
- Minify HTML
- Minify CSS
- Minify JavaScript

One could use the [PageSpeed Module](https://developers.google.com/speed/pagespeed/module/)
as suggested by the tool which is an add-on for *Apache* or *Nginx* webservers.
I did not want to install additional modules on mine though so I have opted for
a different approach.