Blog Home   Blog Home

April 22, 2015   •   Taylor Jasko

Nginx Performance Tips Using Google Pagespeed

 
 

Testing the ngx_pagespeed module

We’ve been working with Google’s Make the Web Faster team to optimize our Content Delivery Network. The simplicity of their goal is great: You know the web? Make it faster.

We’re always excited to try new technologies, like WebP. However, new developments often come with implementation caveats: we’re eager to work with Google and other partners to field-test, identify issues, and resolve them as they appear. The more we collaborate to battle-harden the technology, the faster we can deliver your content with even better performance.

Today, we’d like to share a few lessons we’ve learned while testing the ngx_pagespeed module developed by the Google’s PageSpeed team.

First up: setup was painless. We spun up a new server, compiled the latest stable Nginx with ngx_pagespeed, and we were done. The Nginx PageSpeed settings were ready to be added to the main virtual host config.

Enabling PageSpeed took a single line (pagespeed on;). But, as with any test deployment, we discovered and resolved a few issues:

  • A quick gotcha: Make sure the cache directory (FileCachePath in the Nginx config) is already created, and writeable by the Nginx daemon.
  • We noticed whitespace wasn’t being trimmed as expected, so we explicitly added the collapse_whitespace filter. Similarly, HTML comments were not always removed, so we directly enabled the remove_comments filter. (Please note: Whitespace is not part of “core” config because in some cases JS depends on whitespace )
  • Certain URLs were being rewritten and included our Varnish HTTP port (8080). The fix was to have PageSpeed rewrite the urls back to the regular domain:
    pagespeed MapRewriteDomain maxcdn.com maxcdn.com:8080;
  • Nginx was handing content directly to PageSpeed, even if it was compressed. Currently, PageSpeed can’t read zipped content, so we disabled compression in the PHP layer with a FastCGI parameter: fastcgi_param HTTP_ACCEPT_ENCODING "invalid";
    (Note: Content was compressed by Nginx after the PageSpeed step.)


So, did it work? We used a Google Analytics experiment to split traffic and measure results on our homepage. When testing content delivery, we disabled WordPress plugins that could affect our statistics (we wanted to compare a baseline Nginx with the PageSpeed module).

Nginx with the PageSpeed module

With PageSpeed enabled, we shaved 1.57 seconds from our average page load (seen above), dropped our bounce rate 1%, and our exit percentage 2.5%. In sum, we squeezed out extra performance with nothing but a few extra lines in our nginx config files.

In case you want to run Nginx with PageSpeed, here’s our full config:

server {
  #port to listen on
  listen 80;

  # server name
  server_name www.maxcdn.com;

  # root location
  root /var/www/maxcdn.com/public_html;

  # access log
  access_log /var/log/nginx/maxcdn.com.access.log main;

  # PageSpeed
  pagespeed on;

  # let's speed up PageSpeed by storing it in the super duper fast memcached
  pagespeed MemcachedThreads 1;
  pagespeed MemcachedServers "localhost:11211";

  # show half the users an optimized site, half the regular site
  pagespeed RunExperiment on;
  pagespeed AnalyticsID UA-XXXXXXXXXX-1;
  pagespeed ExperimentVariable 1;
  pagespeed ExperimentSpec "id=1;percent=50;level=CoreFilters;enabled=collapse_whitespace,remove_comments;";
  pagespeed ExperimentSpec "id=2;percent=50";

  # Filter settings
  pagespeed RewriteLevel CoreFilters;
  pagespeed EnableFilters collapse_whitespace,remove_comments;

  # needs to exist and be writable by nginx
  pagespeed FileCachePath /var/ngx_pagespeed_cache;

  # Varnish talks to us as maxcdn.com:8080 but when we rewrite
  # urls we should use maxcdn.com because that's what the
  # outside world uses for us.
  pagespeed MapRewriteDomain maxcdn.com maxcdn.com:8080;

  # This is a temporary workaround that ensures requests for pagespeed
  # optimized resources go to the pagespeed handler.
  location ~ ".pagespeed.([a-z].)?[a-z]{2}.[^.]{10}.[^.]+" { }
  location ~ "^/ngx_pagespeed_static/" { }
  location ~ "^/ngx_pagespeed_beacon$" { }

}

Enjoy!

A big thank you to the following people who helped make this happen:

Originally published on MaxCDN, a StackPath company

   
Topics

View All
Stay Informed

Receive our monthly blog newsletter.

Follow

Connect with us to stay updated.

Stay Informed

Receive our monthly blog newsletter.

Follow

Connect with us to stay updated.