How to prepend a base path to all relative images with Node.js
Posted on October 23, 2021
To add further optimizations to my blog, I decided to use a CDN to serve optimized images and assets.
This blog uses Nuxt and the generate
capability to dump all the HTML as static pre-compiled files.
All the assets were served by the Netlify CDN which doesn't allow dynamic resizes and on-the-fly compression. Using something like CloudImage CDN, I potentially can get some benefits from performance perspective.
The scenario and results
For instance, the full list of images (that are loaded in lazy mode, btw) in the blog index page, without optimization, weights 22Mb of data. After the CDN swap, the optimized version of the same list weights 8Mb! Not bad at all, nearly 70% of reduction of original weight!
The Plan
Instead of digging with the Nuxt internals and plugin system, I've opted with a little Node.js script that, after the generation process, reads all the source files and prepend the CDN base path to my img
tags with a tiny RegEx.
Here the script that detects the image src
and add the CDN base path:
const addCDNBaseToImages = html => {
const reg = /<img.*?src="([^"]*)"[^>]*>(?:<\/img>)?/gmi
const images = html.match(reg)
let parsed = html
if (!images) return html
images.forEach(img => {
const r = /<img.*?src="([^"]*)"[^>]*>(?:<\/img>)?/gmi
const res = r.exec(img)
const src = res[1]
if (src.indexOf('data:image') === -1 || src.indexOf('https') === -1) {
const newTag = res[0].replace(src, BASE_CDN_PATH + src)
parsed = parsed.replace(res[0], newTag)
}
})
return parsed
}
Since there're some base64
encoded images and absolute URL from other sources, I need to skip them during the process.
I love when a small action produces a consistent impact!