cache asset images more aggressively (#23553)
* cache asset images more aggressively * more careful about which gets the manual surrogate key * fix rendered-content-link-checker script too * feedbacked
This commit is contained in:
52
lib/render-content/plugins/rewrite-asset-urls.js
Normal file
52
lib/render-content/plugins/rewrite-asset-urls.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import fs from 'fs'
|
||||
|
||||
import { visit } from 'unist-util-visit'
|
||||
|
||||
// Matches any <img> tags with an href that starts with `/assets/` or '/public/'
|
||||
const matcher = (node) =>
|
||||
node.type === 'element' &&
|
||||
node.tagName === 'img' &&
|
||||
node.properties &&
|
||||
node.properties.src &&
|
||||
(node.properties.src.startsWith('/assets/') || node.properties.src.startsWith('/public/'))
|
||||
|
||||
// Content authors write images like ` {
|
||||
return (tree) => {
|
||||
visit(tree, matcher, (node) => {
|
||||
const newSrc = getNewSrc(node)
|
||||
if (newSrc) {
|
||||
node.properties.src = newSrc
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getNewSrc(node) {
|
||||
const { src } = node.properties
|
||||
if (!src.startsWith('/')) return
|
||||
|
||||
try {
|
||||
const filePath = src.slice(1)
|
||||
const stats = fs.statSync(filePath)
|
||||
// The size is not perfect but it's good enough. The size is
|
||||
// very fast to pick up without needing to do a deep hashing of the
|
||||
// image's content. It's perfectly possible that someone edits an
|
||||
// image and it's size doesn't change. Although very unlikely.
|
||||
// The slightest change to the image is more likely to either increase
|
||||
// or decrease the image size by at least 1 byte.
|
||||
// Also, because of this limitation, we're not confident to cache the
|
||||
// image more than say 24h. But in the unlikely event that someone does
|
||||
// edit an image and the size doesn't change, there's always the
|
||||
// escape hatch that you can soft-purge all manual CDN surrogate keys.
|
||||
if (!stats.size) return
|
||||
const hash = `${stats.size}`
|
||||
const split = src.split('/')
|
||||
split.splice(2, 0, `cb-${hash}`)
|
||||
return split.join('/')
|
||||
} catch (err) {
|
||||
console.warn(`Error trying to get a hash for ${src}`, err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user