Skip to content

[Bug]: next/image static images are not cached #1491

@jzxhuang

Description

@jzxhuang

Summary

When using next/image with Netlify edge functions, statically imported images are never cached. This results in the browser always making a request, which results in a 304 status code (asset unchanged). This is effectively making next/image unusable, lack of caching is a severe degradation to app performance

See here:

  • Open https://rainbow-haupia-6bb9be.netlify.app/ with devtools network tab open, filter for images
  • on first load, the "react image" should have 200 status code. And be loaded in webp assuming your browser supports that format :D
  • On subsequent loads, the request is 304. I would expect 200 here with a browser cache hit. If you have multiple images on a page or hit a cold funciton boot, this request can take over 2s.
  • Root cause appears to be that the response applies cache-control: public, max-age=0, must-revalidate header

image

Compare this to the same application deployed on Vercel: https://netlify-next-image-caching.vercel.app/

image

You can configure the Time to Live (TTL) in seconds for cached optimized images. In many cases, it's better to use a Static Image Import which will automatically hash the file contents and cache the image forever with a Cache-Control header of immutable

I also tried specifying minimumCacheTTL, didn't appear to do anything. https://deploy-preview-1--rainbow-haupia-6bb9be.netlify.app/

Steps to reproduce

  1. create a new next app with yarn create next-app --typescript
  2. render a statically imported image using next/image
  3. Deploy on Netlify
  4. observe that the image is not cached

A link to a reproduction repository

https://github.com/jzxhuang/netlify-next-image-caching

Plugin version

4.13.1

More information about your build

  • I am building using the CLI
  • I am building using file-based configuration (netlify.toml)

What OS are you using?

Mac OS

Your netlify.toml file

`netlify.toml`
# Paste content of your `netlify.toml` file here
[[plugins]]
package = "@netlify/plugin-nextjs"

Your public/_redirects file

`_redirects`
# Paste content of your `_redirects` file here

Your next.config.js file

`next.config.js`
# Paste content of your `next.config.js` file here. Check there is no private info in there.
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
}

module.exports = nextConfig

Builds logs (or link to your logs)

Build logs
# Paste logs here
https://app.netlify.com/sites/rainbow-haupia-6bb9be/deploys/62e26aa8c3966d7a427076d1

Function logs

Function logs
# Paste logs here

.next JSON files

generated .next JSON files
# Paste file contents here. Please check there isn't any private info in them
# You can either build locally, or download the deploy from Netlify by clicking the arrow next to the deploy time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions