Normalize requests to increase cache efficiency

Improve cache performance by normalizing requests. Filter and reorder query params, convert to lowercase, filter headers, and more.

VCL

Use this solution in your VCL service (click RUN below to test this solution or clone it to make changes):

Compute@Edge

Use this solution in your Compute@Edge service:

  1. JavaScript
package.json
JavaScript
{"dependencies":{"@xgu/accept":"^1.0.1"}}
index.js
JavaScript
const originalReq = event.request;
let url = new URL(event.request.url);
// Filter the query string to only include query
// parameters that are valid for your site
let searchEntries = url.searchParams.entries();
let filteredEntries = searchEntries.filter(entry => ["query", "page", "foo"].includes(entry[0]));
let filteredParams = new URLSearchParams(filteredEntries);
// Lowercase specific query param values
let pageValue = filteredParams.get("page");
if (pageValue) {
filteredParams.set("page", pageValue.toLocaleLowerCase());
}
// Sort the querystring params in alphabetical order
filteredParams.sort();
// Create a new Request object with a sorted URL.
url.search = filteredParams;
const newReq = new Request(
url,
originalReq,
);
// Remove headers that you want to avoid using to vary responses
newReq.headers.delete("user-agent");
newReq.headers.delete("cookie");
// Normalise headers that you may vary on.
let acceptValue = newReq.headers.get("accept-language");
if (acceptValue) {
const preference = ["en", "de", "fr", "nl"];
// Find the best match between preference and accept-language header
let selection = accept.language(acceptValue, preference);
// Fallback if no preference match was found.
if (selection === "") {
selection = "de";
}
newReq.headers.set("accept-language", selection);
}
acceptValue = newReq.headers.get("accept-encoding");
if (acceptValue) {
const preference = ["br", "compress", "deflate", "gzip", "identity"];
// Find the best match between preference and accept-encoding header
let selection = accept.encoding(acceptValue, preference);
// Fallback if no matching preference is expressed for accept-encoding.
if (selection === "") {
selection = "identity";
}
newReq.headers.set("accept-encoding", selection);
}
acceptValue = newReq.headers.get("accept-charset");
if (acceptValue) {
const preference = ["iso-8859-5", "iso-8859-2", "utf-8"];
// Find the best match between preference and accept-charset header
let selection = accept.charset(acceptValue, preference);
// Fallback if no preference is expressed for accept-charset.
if (selection === "") {
selection = "utf-8";
}
newReq.headers.set("accept-charset", selection);
}
// Print out the request url and headers for debugging. Disable for production use to avoid overhead.
console.log(newReq.url);
newReq.headers.forEach((value, name) => console.log(name + ': ' + value));
// Send the modified request to the origin and return the response back to the client.
return fetch(newReq, {
backend: "httpbin",
});