Skip to main content

Command Palette

Search for a command to run...

How to Optimize Image Rendering on Next.js Servers

Published
2 min readView as Markdown
How to Optimize Image Rendering on Next.js Servers
K

I am a developer who is highly interested in TypeScript. My tech stack has been full-stack TS such as Angular, React with TypeScript and NodeJS.

Goal: Optimize image before the first user accesses, reduce server load, reduce TTFB + increase LCP score ( better SEO ).

  1. Pre-generate image by script (sharp)

    Pre-generate image like as Vercel often do it.

    Example:

     // scripts/resize-images.ts
     import sharp from 'sharp'
     import fs from 'fs'
     import path from 'path'
    
     const inputFolder = 'public/images/original'
     const outputFolder = 'public/images/optimized'
     const sizes = [640, 768, 1024, 1280, 1920]
    
     fs.readdirSync(inputFolder).forEach(file => {
       sizes.forEach(size => {
         const inputPath = path.join(inputFolder, file)
         const outputPath = path.join(outputFolder, `${size}-${file}`)
         sharp(inputPath)
           .resize(size)
           .toFormat('webp')
           .toFile(outputPath)
       })
     })
    

    ✅Run script before build to generate images with necessaries size.

  2. ✅ Use external CDN (Cloudinary, ImageKit, imgix, etc.)

    Example by Cloudinary:

     tsxCopyEdit<Image
       src="https://res.cloudinary.com/demo/image/upload/w_768/your-image.jpg"
       alt="demo"
       width={768}
       height={400}
     />
    

    ✅ Cloudinary will process the image from the first time and cache on CDN → bro server does not need to touch the image

  3. ✅ Use next export (static export)

    If the bro site is a static site (no SSR), then:

    • Use next export to create pre-optimized HTML & images.

    • Use next export to create pre-optimized HTML & images.

    • Don’t use <Image /> if you don’t need to much responsiveness => use <img />

  1. ✅Next.js ISR + Standard Cache-control

    • ISR (Incremental Static Regeneration) still creates images, but:

      • Bro configures standard Cache-Control headers.

      • Bro uses outer layer CDN (Cloudflare, Vercel) to cache optimized images.

✅ Still has cold start but from the 2nd time onwards it is very light.

  1. Use next/image but only build 1-2 sizes

    • Limit deviceSizes, for example:

    •   // next.config.js
        images: {
          deviceSizes: [768, 1024], // giảm số lượng ảnh cần render
          imageSizes: [64, 128],
          formats: ['image/webp'],
        }
      

→ ✅ Bro reduces the number of images needed to create → the first time is less "brain-wracking"

  1. Conclusion:

    | Solution | Advantage | Defect | | --- | --- | --- | | Pre-generate image by sharp | Proactive, use local | Cost storage if more images | | Cloudinary / CDN | Optimize real-time + cache | Need register services | | Reduce deviceSizes | Reduce execute render server | Can lost flexible responsive | | Use next export | Don’t need server | No SSR | | ISR + cache headers | balance between static & dynamic | Need config better CDN |

    In short, if you want it to be smooth, bro should:

    • ✅ Optimize image before deloy

    • ✅ Use CDN to process image on edge

    • ✅ Reduce sizes necessaries (if project allow)

More from this blog

E

Essential programming concepts

54 posts

I'm a software engineer who is highly interested in TypeScript/ JavaScript. My tech stack has been full-stack TS such as React, Angular with TypeScript/JavaScript and NodeJS.