3 min read

Optimize your website within two hours

I run a small tea subscription service called Tomotcha, and each month we send Japanese tea directly from Osaka.

Like most small businesses we use Google tools extensively (Analytics, AdWords, Webmaster Tools...) and we periodically receive their emails about new stuffs.

Last week's topic was Does the speed of your mobile website makes you lose some visitors? (loosely translated from French).

Interesting.

I ran it and... it was bad.

Initial test

Eleven seconds! Try by yourself on your favorite url here.

A friend of mine based in US told me lately that our website was a little bit slow (our servers are in Paris).

I already started to check CloudFront. But with eleven seconds, the problem was obviously deeper than the server location.

And so started my optimization journey on a pretty common stack (ours): Nginx & Django.

Django

I started with Django. We had dozens of CSS and JS files, it was time to consolidate them.

Django Compressor is the way to go.

Edit your settings.py file and modify it as follows after pip installing the django_compressor package:

INSTALLED_APPS = [
    # ...
    'compressor',
    # ...
]
STATICFILES_FINDERS = [
    # ...
    'compressor.finders.CompressorFinder',
]

In your templates, group a maximum of CSS links and JavaScript scripts between a minimum number of compress instructions:

{% load compress %}
<!-- ... -->
{% compress css %}
<link rel="stylesheet" href="{% static 'startup/flat-ui/bootstrap/css/bootstrap.css' %}">
<!-- ... -->
<link rel="stylesheet" href="{% static 'tomotcha/css/style.css' %}">
{% endcompress %}
<!-- ... -->
{% compress js %}
<script src="{% static 'tomotcha/js/underscore-min.js' %}"></script>
<!-- ... -->
<script src="{% static 'js/angular.min.js' %}"></script>
{% endcompress %}

This will aggregate your various files in a single one, with network gains in perspective.

The icing on the cake: set COMPRESS_OFFLINE = True in settings.py and issue a manage.py compress command to avoid on the fly cache generation and latency for your first visitor.

Nginx

You should definitively check that gzip is enabled and actually compress some stuff.

Use Chrome inspection tool and look for the Content-Encoding header in the Response Headers.

Check that Gzip is enabled

If not, you should have a look at the following settings in your Nginx configuration:

server {
    [...]
    gzip on;
    gzip_comp_level    5;
    gzip_min_length    256;
    gzip_types *;
    [...]
}

Do not forget to restart it.

Stripe

Stripe is our payment provider. Awesome service with a great APIs.

We have very basic needs, so we only use Stripe Checkout.

On Tomotcha the checkout button is on the home page and its integration was done pretty much like this:

<script src="https://checkout.stripe.com/checkout.js"></script>
<script type="text/javascript">
(function() {
    [...]
    StripeCheckout.configure({
        key: 'tomotcha',
        [...]
    });
})();
</script>

Don't. Look at the Performance tab of Chrome inspection tool. Catastrophic:

Stripe performances

Instead, call StripeCheckout.configure when your customer actually wants to subscribe.

Its a little longer but a nice wheel make them wait, time to display the form.

Resources

A vast subject:

  • Do I really need to include my theme's JS for a fancy carousel that I do not use? No: drop it!
  • Is my header image small enough? Initially at 225k, optimized for the web it's now 78k: use the dedicated feature in your favorite image editor.
  • Check that you include minified (*.min.js) JavaScript files, at least for external dependencies.
  • ...

Time to collect. Let's re-run the benchmark:

Final test

Better! And now we can start to think about advanced stuff:

  • Server location
  • Caching
  • ...

My conclusion? Coffee is deprecated, upgrade to green tea.

More seriously, it only took me a couple hours to greatly improve our website performance, and it's definitively worth a shot.