Skip to main content

Command Palette

Search for a command to run...

How to Lazy Load Images with an Edge Worker

Updated
2 min read

Lazy loading your images is a great way to increase performance and other Google Lighthouse metrics. Fortunately, there's now a simple native attribute you can add your your <img> tags that will lazy load them without any extra code.

<img loading="lazy" src="https://www.fillmurray.com/640/360" />

Of course, this is easier said than done if you're using a WYSIWYG editor or legacy platform that doesn't support this attribute. Fortunately, edge functions can help us here. Only a few CDN providers are offering edge functions. For this example we'll use Cloudflare Workers.

If you're not familiar with them, edge functions are basically a bit of code that runs right before the content gets sent back to the user. So after your server is done doing whatever it's doing, the edge function can intercept the result and do whatever you want to it. You can use it to alter the code sent back, proxy another site entirely, and many other things.

Cloudflare Workers have a feature that allow you to transform HTML. With this we can make small tweaks on the edge that might be harder to do, or sometimes impossible, on the server.

Here's the code to add the native lazy loading feature to all images:

// Image rewriter that adds loading="lazy" to <img> tags that don't already have it
class ImageRewriter {
  element(element) {
    const attribute = element.getAttribute(`loading`)
    if (!attribute) {
      element.setAttribute(`loading`, `lazy`)
    }
  }
}

// Listens for incoming page requests
addEventListener(`fetch`, (event) => {
  event.respondWith(handleRequest(event.request))
})

// An HTML rewriter that intercepts and rewrites <img> tags
const rewriter = new HTMLRewriter().on(`img`, new ImageRewriter())

// Fetches content from origin and pass through transformer
async function handleRequest(req) {
  const res = await fetch(req)
  return rewriter.transform(res)
}

It's simple, but can have a major performance impact across your entire website. You can take this much further if you wanted and add custom attributes to ignore lazy loading on some images, or have a fallback for browsers that don't support the native lazy loading attribute. But this is good enough for most use cases.

A
Adi4y ago

Hello, I want to change the blogger permalink /p/test.html to /test-page/ and also canonical link and other links. but still can't rewrite the canonical and other links.

first code, with route settings like this: www.domain.com/test-page*

addEventListener("fetch", event => {
    return event.respondWith(fetch("https://www.domain.com/p/test.html"))
})

the second code, and the route settings are like this *.domain.com/test-page*

const OLD_URL = "https://www.domain.com/p/test.html";
const NEW_URL = "https://www.domain.com/test-page";
async function handleRequest(req) {
  const res = await fetch(req)
  return rewriter.transform(res)
}
class AttributeRewriter {
  constructor(attributeName) {
    this.attributeName = attributeName
  }
  element(element) {
    const attribute = element.getAttribute(this.attributeName)
    if (attribute) {
      element.setAttribute(
        this.attributeName,
        attribute.replace(OLD_URL, NEW_URL)
      )
    }
  }
}
const rewriter = new HTMLRewriter()
  .on("link", new AttributeRewriter("href"))
  .on("meta", new AttributeRewriter("content"))
addEventListener("fetch", event => {
    let url = event.request.url
  event.respondWith(handleRequest(url)
  .catch(err => new Response(err.toString(),{status:500})))
})
K

I'm not entirely sure. I don't think I've ever tried to change canonical links with Cloudflare workers. They have lots of examples in their docs though. You should be able to modify one of those examples to suit your needs.

A
Adi4y ago

when I just run the code rewrite it works rewrite the canonical link with route www.domain.com/p/test.html. I can't seem to run concurrently, is there maybe something wrong with my route settings? I've also changed my codes and still the same still can't rewrite the canonical link.

More from this blog

K

Kennedy Rose

20 posts