AJAX requests are typically used to provide dynamic content on WordPress sites and bypass cache. I have already shown how to Cache AJAX requests with Varnish to bypass PHP and MySQL for AJAX processing by storing the cache in Varnish. In my quest for maximum performance I also experimented with Cloudflare page caching for WordPress. This guide combines the power of these two guides, we are going to cache AJAX GET requests from WordPress on Cloudflare for the fastest load times.
This guide assumes you are using Varnish 4 and have a free Cloudflare account.
Before and After Benchmarks
The before result shows a 307 ms load time to California from the Netherlands (proof).
The after result shows a 3 ms load time to California from the Netherlands after using Cloudflare page caching (proof).
This is a huge improvement of 3 ms down from 307 ms. That is roughly 1% of the original load time for the WordPress popular posts widget.
Cache AJAX GET Requests with Cloudflare and Varnish
Let’s look at the headers of the AJAX request to see why Cloudflare isn’t caching them using cURL.
curl -I "https://guides.wp-bullet.com/wp-admin/admin-ajax.php?action=wpp_get_popular&id=3"
The Expires
and Cache-Control
headers tell Cloudflare to not cache this URL. You can see this in the CF-Cache-Status: MISS
header.
root@htpcguides:~# HTTP/1.1 200 OK
Date: Fri, 13 Jan 2017 18:59:53 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Set-Cookie: __cfduid=d6303005caebe1f2b9037a66ba01d211b1484333992; expires=Sat, 13-Jan-18 18:59:52 GMT; path=/; domain=.htpcguides.com; HttpOnly
Pragma: no-cache
X-Robots-Tag: noindex
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Vary: Accept-Encoding
X-Varnish: 1087020866
Via: 1.1 varnish-v4
Access-Control-Allow-Origin: https://guides.wp-bullet.com
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Cache: HIT
CF-Cache-Status: MISS
Server: cloudflare-nginx
CF-RAY: 320b167eaaee0c5f-AMS
We can manipulate these headers with Varnish 4 by modifying the vcl file.
sudo nano /etc/varnish/default.vcl
Add this snippet in vcl_deliver
to remove the offending headers and add the right Cache-Control
header so Cloudflare will cache this request.
sub vcl_deliver {
if ( req.url ~ "\?action=wpp_get_popular" && !req.http.cookie ~ "wordpress_logged_in" ) {
# Remove headers preventing Cloudflare cache
unset resp.http.Cache-Control;
unset resp.http.Expires;
unset resp.http.Pragma;
unset resp.http.ETag;
# Cache request in browser for 1 day (in seconds)
set resp.http.Cache-Control = "max-age=259200";
}
}
Check your Varnish vcl syntax is OK
varnishd -C -f /etc/varnish/default.vcl
If there were no errors you can reload Varnish
sudo service varnish reload
Time to verify the header manipulation is working.
Test AJAX Request is Cached
Using the same cURL command we can query the same AJAX GET request
curl -I "https://guides.wp-bullet.com/wp-admin/admin-ajax.php?action=wpp_get_popular&id=3"
You can see the headers are gone and have been replaced with the correct Cache-Control
header.
Notice there is now a CF-Cache-Status: HIT
.
HTTP/1.1 200 OK
Date: Sat, 14 Jan 2017 10:34:52 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Set-Cookie: __cfduid=d315ec598c4f6ca083628abcc3bef0cdf1484390092; expires=Sun, 14-Jan-18 10:34:52 GMT; path=/; domain=.wp-bullet.com; HttpOnly
X-Robots-Tag: noindex
Vary: Accept-Encoding
X-Varnish: 135206
Via: 1.1 varnish-v4
Cache-Control: public, max-age=2678400
Access-Control-Allow-Origin: http://guides.wp-bullet.com
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Cache: MISS
CF-Cache-Status: HIT
Expires: Tue, 14 Feb 2017 10:34:52 GMT
Server: cloudflare-nginx
CF-RAY: 3210701dead83ce9-CPH
It will not get much faster than caching your dynamic requests on a CDN like Cloudflare :).
Would this bypass capability checks?