UNPKG

coach-core

Version:
66 lines (59 loc) 2 kB
import * as util from '../util.js'; const SKIPPABLE_DOMAINS = new Set([ 'www.google-analytics.com', 'ssl.google-analytics.com', 'analytics.twitter.com' ]); // One year in seconds — the cache lifetime modern best practice (and the // HTTP/1.1 spec) recommends as the upper bound. For content-hashed URLs // (e.g. /static/app.4af2.css) this is what `Cache-Control: // max-age=31536000, immutable` is designed for. const ONE_YEAR = 31_536_000; function processAsset(asset) { if (SKIPPABLE_DOMAINS.has(util.getHostname(asset.url))) { return 0; } else if (asset.expires >= ONE_YEAR) { return 0; } else if (asset.expires <= 0) { // this is caught in cacheHeaders so let's skip giving advice // about them return 0; } else { return 1; } } export default { id: 'cacheHeadersLong', title: 'Long cache headers is good', description: 'Setting a cache header is good. Setting a long cache header (a year) is even better because the asset will stay in the browser cache across visits. For content-hashed URLs (e.g. app.4af2.css) you can safely use Cache-Control: max-age=31536000, immutable. For unversioned URLs that may change, use a revalidating strategy instead.', weight: 3, severity: 'info', tags: ['performance', 'server'], processPage: function (page) { let score = 100; let offending = []; for (const asset of page.assets) { // Don't check the main page/document since it is common to not // cache that if (asset.url === page.finalUrl) { continue; } let myScore = processAsset(asset); if (myScore > 0) { score -= myScore; offending.push(asset.url); } } return { score: Math.max(0, score), offending: offending, advice: score < 100 ? 'The page has ' + util.plural(offending.length, 'request') + ' that have a shorter cache time than one year (but still a cache time).' : '' }; } };