Scalability vs Responsive Sites
A major part of performance with sites on any platform is ensuring that your website is highly cacheable. By caching pages to serve as static files to repeat users, this offloads a lot of server processing power. Without cache, your web server would have to re-process the code to generate your page. Not only does this make more work for your server, it could slow down the response time for your site.
A challenge developers face is how to cache their sites heavily, while still adapting to mobile devices. With Google PageSpeed’s score hinging on mobile compatibility, many themes in WordPress are adapting to offer responsive options. Chances are you’re wanting a different, mobile-friendly version of your site to show to your smartphone users. With page cache, your user sees whatever version was requested the last time the page was stored in cache. This equates to a poor experience for your users.
X-Device Cache Groups
So how do you handle this scenario? Difference circumstances require two different versions of the site. You can do this by adding an “X-Device Group” header based on the HTTP User Agent the request came from. This allows you to detect devices in Varnish. This way, any device you designate as “mobile” gets cached in a mobile group. At the same time, desktop users are cached in a separate cache group. So this solves our problem! A mobile user receives the mobile site. A desktop user receives the desktop site.
Example Config
So how do you detect devices in Varnish? Here’s an example setup:
# Cache different devices in different cache groups so they're served the right version
if ( req.http.User-Agent ~ "(?i)(tablet|ipad|playbook|silk)|(android(?!.*mobile))" ) {
# Cache tablet devices in the same group - it's possible this is different than smartphones for some sites
set req.http.X-Device = "tablet";
}
elsif ( req.http.User-Agent ~ "(?i)
Mobile|iP(hone|od)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune" ) {
# Cache smartphones together. The mobile user-agents receive a mobile version with a responsive theme
set req.http.X-Device = "smartphone";
}
else {
# Cache everything else together. We assume anything that doesn't fit into the above regex is a regular desktop user.
set req.http.X-Device = "regular";
}
This snippet says to add a X-Device header to each of these device groups. It allows Varnish to cache the devices separately. You can set the header to whatever you prefer. Some prefer something more like X-Cache-Bucket, or X-Cache-Group (which WP Engine uses). If you’re curious how I came to this setup and these particular user-agents, I grabbed these from a pretty thoughtful list. And, Varnish published a very helpful guide on device detection that I snagged to get started.
When you detect devices in Varnish caching groups like this, it allows you to take full advantage of page caching, while still maintaining responsive behavior. That’s a win you can take to the bank! Using more cached pages equates to faster website load times.
Johnny says
I’m still learning the ropes of writing to the vcl, so I hope it’s OK that I ask… where does this get placed in my vcl file? recv?
Thank you for this, btw!