
Here at MaxCDN 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 (
FileCachePathin 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_whitespacefilter. Similarly, HTML comments were not always removed, so we directly enabled theremove_commentsfilter. (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).

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.
Sign us up for more. We are continuing to test the module with the PageSpeed team, and our goal is to make it available across our CDN and to all of our customers – stay tuned!
In case you want to run Nginx with PageSpeed, here’s our full config:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
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:
- Ilya Grigorik (Google)
- Jeff Kaufman (Google)
- Joshua Marantz (Google)
- Vid Luther (ZippyKid)
- Ask Bjorn Hansen (MaxCDN)
- Justin Dorfman (MaxCDN)
Blog