Optimize your website for Google

You’ve probably heard that websites that work faster and have fewer errors are ranked higher by search engines, and that makes perfect sense.
People also say that a faster websites make somebody called “a customer” happier.

Now, there are so many different ways to make people happy that we decided we’ll start with a low hanging fruit and take care of the machines first.

The easiest way to know what the big G thinks is to use their own tool called PageSpeed:

As you can see, even google themselves don’t achieve the perfect score. But let’s go through the optimizations we can apply without even touching your application source code

Process

1. Reduce server response time

There are many approaches you can consider to improve this, but the common ones are
- Deploy your service close to your customer. Or to Google’s test service.
- Install a caching proxy. This doesn’t just reduce response time, but also makes your app server work less hard. Nginx has a lot more use cases and is free, so that’s what I typically use.
- Put statics on CDN, as you’ll never achieve the same response time. Something like AWS CloudFront is cheap and easy to use, and helps on other things, too.

2. Enable compression

Most applications servers have plugins to enable GZip compression, if you’re sure all your clients would support this technology that’s been common for around 20 years.
Still, in enterpriseland you can stumble upon some 25 years-old SDK written in Java that can’t handle GZip. For such cases, Nginx with configurable rules for compressing will help — just exclude the user agent strings that gives you trouble, or check Accept-Encoding header.
Note that AWS CloudFront would compress stuff for you nowadays, just don’t forget to ask it.

3. Minify HTML/CSS/JavaScript

This is typically done by the tools that generate such files, or plugins to them. Webpack is one of the common ones and it can do all of this for your static pages.
For dynamic consult your application server manual.

4. Leverage browser caching

Especially for your static assets, you should instruct browsers to cache your content on the client and avoid unnecessary requests for the same files. Having all content cached indefinitely provides many advantages, but one disadvantage is that whenever you release — you have to wait until cache expires before your website start working well for all the users.

For dynamic content like API calls and obviously don’t want to cache much on the client, perhaps a few seconds or minutes for something that doesn’t change very often.

For static content stored in CDNs you can trigger expiry on demand, but that’s both costly and not fast enough.

We did something very simple which is in line with AWS suggestions: for every build, we create a folder in S3 bucket and use that for all the statics of that build, e.g.

https://static.zentist.io/v1_0_0_374

This path gets configured as STATIC_URL in the frontend app on start, and whenever we refer to an image like that ${STATIC_URL}/img/logo.svg we end up getting the new one, uploaded from the same source the app was built from.

Of course, this is still imperfect, as we end up making clients re-download the same assets because of path changes, but this gives us confidence that every customer is using the right version, and you don’t have to deal with per-asset versioning of each file, which is the other possible solution. A reasonable compromise can be achieved by only creating new picture set for each major or minor application release (not a patch).

Another challenge you’re likely not going to overcome here is the 3rd party tracking widgets, as you typically don’t have access, or would rather not mess with their stuff. Google’s own Analytics has 2 hour cache expiration which is being identified as an issue by PageSpeed.

5. Optimize images

Google gives you optimized versions of pictures it finds need it, but it’s better to run all your images through this process to make sure you’ve got performance on pages search bots can’t reach.

This replaces all your JPEGs with(probably) better compressed ones that look the same:

brew install imagemagick
find . -name "*.jpg" -exec convert {} -sampling-factor 4:2:0 -strip -quality 85 -interlace JPEG {} \;

PNGs can get compressed without loss of quality by removing unused transparency and color range:

brew install optipng
find . -name "*.png" -exec optipng {} -o 3 \;

In addition, I figured it would be a good idea to convert non-transparent PNGs into JPEGs to save even more traffic. Obviously, this would require code updates to use the new images.

# requires imagemagick
find . -name "*.png" -print0 | while IFS= read -r -d $'\0' line; do
if [[ $(convert "$line" -format "%[opaque]" info:) == *"True"* ]] ;then
echo "$line"
convert "$line" -sampling-factor 4:2:0 -strip -quality 85 -interlace JPEG "${line/png/jpg}"
fi
done

6. Prioritize visible content

I couldn’t find a website that wouldn’t pass this check. This would be triggered if you’re embedding tracking code incorrectly (so just don’t do that).

7. Avoid landing page redirects

If you want users to do something to your website — you probably want them to do that via TLS. So a redirect from http:// to https:// is quite common.
Make sure you have https:// as your default property in Google search so that all their referrals go directly to the secure site.

8. Eliminate blocking CSS

So, historically all CSS blocks rendering, which means your page is not going to be shown until every single referenced CSS file had been downloaded. There are no easy solutions to this one just yet.

What you can do, though:

Results

“By following these 8 easy steps..” we managed to improve PageSpeed Rank from 20–40 points to 70–90 points in just a couple of days:

Note that even 100% compliance to all the checks won’t get you a 100, as there are factors like, well, actual speed of your website, that are counted in.

This makes it even more important not to lose what you get, and I highly recommend to add a step in your release pipeline to check the scores on a public-facing Staging environment to make sure it doesn’t go back down.

The one-minute experience is indeed 1 minute (guaranteed, or your money back. Well, because it’s free, dah): https://developers.google.com/speed/docs/insights/v2/getting-started

Have you reached a 100/100 score with any of your projects? Let me know!