Cache SVG returned from a Function

Hi there,

I’m trying to render an SVG image in a lambda function and cache it in the CDN.
I want to avoid invoking the function for each request. In my testing the function was invoked each time I requested the image even with Cache-Control set.
I understand that I should not expect the function to be called only once, because of the all the nodes Netlify CDN has.

Does Netlify CDN support caching SVG images ? Am I doing something wrong ?

Here is my code :
import React from ‘react’;
import RDS from ‘react-dom/server’;
import Avataaars from ‘avataaars’;

export function handler(event, context, callback) {  
  const appString = RDS.renderToString(React.createElement(Avataaars, event.queryStringParameters, null));
  console.log("Avatar rendered...")
  callback(null, {
    statusCode: 200,
    headers: {
      "Content-Type": "image/svg+xml",
      "Cache-Control": "public, s-max-age=31536000"
    },
    body: appString
  })
}

Any idea?

I assume you want to use the Lamdba function to render the svg on the first visit, and on the subsequent visits you want to use a cached version without invoking any lamdba functions:

The only way i know this can be implemented on Netlify is this:

On first visit, that URL doesn’t exist in Netlify CDN, so the request is routed to a Lambda Function which:

  1. generates and serves the svg.
  2. marks the url in a DB as visited (ex: FaunaDB)
  3. Triggers a static site generation

When the site is generated it checks the DB to see if new SVGs needs to be rendered it builds the site and copies over the new svgs to the URL used on the first visit.

On the subsequent visits the URL rewrite routes the request to Netlify CDN, because the url exist so redirecting to the Netlify Function URL is no longer needed.

@philhawksworth has an excellent working GH repo on how to achieve this, it’s still WIP, but you should take a look.
As far is know this is the only way to implement the caching strategy mentioned above.
In any case, keep us posted!

2 Likes

Looks interesting, but I can’t regenerate the website in my case.
Based on the following answer it seems that I should be able to cache responses in the CDN:
https://stackoverflow.com/questions/54543137/can-i-use-netlifys-cdn-to-prevent-lambda-execution-more-than-once-a-day

The question is if it works for SVG images and if I did it correctly.

Hi,

We do support caching function returns by passing a custom cache-control header, I just tested it and it works for me. Can you provide me with a URL to that function so I can test it myself and check our logs to see if it was a cache hit?

2 Likes

Hi,
Thanks for your answer.
I just found out that it works when I add an Etag to the response headers. Seems to work now. Or should it work without an etag as well?

1 Like

It was my understanding that if you use cache-control without Etag, it should still work. Cache-control will inform US how long to cache it on our CDN edge.

Be aware that this cache is PER CDN NODE and we have dozens, so even if you use a cache-control that is a day long, you may see the function loaded several dozen times as it could happen:

  • on multiple CDN nodes
  • that cache could time out (if not accessed frequently on a node, it WILL be evicted for more frequent content at some point)
  • we could drop the cache on a number of CDN nodes, as we add and remove them from rotation
1 Like