Next.jsでoptimizeした画像を自動的に適用する方法


Lighthouseなどで画像がデカイとか言われる

個々の画像の処理は面倒

なので、自動化する

  1. まずはnext-optimized-imagesをいれる
  2. さらに必要なライブラリを追加で入れる
    • JPEGならimagemin-mozjpeg
    • PNGならimagemin-optipng
    • WEBPならwebp-loader
    • Responsiveな画像を用意したいならresponsive-loadersharp ...など
  3. 併せてnext-compose-pluginsも入れる(入れなくても良いが、next.config.jsを書く時に綺麗に纏められる)
  4. 下のようにnext.config.jsを設定する(コメント部分はnext-optimized-imagesのデフォルト
  5. 画像をリンクする際には/publicからの絶対パスではなく、相対パスでrequire(...)する(例:<img src={require("...")} />
  6. devではoptimizeされないので注意(optimizeImagesInDev: trueでdevでも動くとあるが、next.jsがハングアップする模様...)
  7. 念のために再起動する
  8. yarn buildで画像のパスが変わっているか確認
next.config.js
const withPlugins = require("next-compose-plugins")
const optimizedImages = require("next-optimized-images")

const nextConfig = {
  // あれば
}

module.exports = withPlugins(
  [
    [
      optimizedImages,
      {
        // these are the default values so you don't have to provide them if they are good enough for your use-case.
        // but you can overwrite them here with any valid value you want.
        // inlineImageLimit: 8192,
        // imagesFolder: 'images',
        // imagesName: '[name]-[hash].[ext]',
        // handleImages: ['jpeg', 'png', 'svg', 'webp', 'gif'],
        // optimizeImages: true,
        // optimizeImagesInDev: false,
        // mozjpeg: {
        //   quality: 80,
        // },
        // optipng: {
        //   optimizationLevel: 3,
        // },
        // pngquant: false,
        // gifsicle: {
        //   interlaced: true,
        //   optimizationLevel: 3,
        // },
        // svgo: {
        //   // enable/disable svgo plugins here
        // },
        // webp: {
        //   preset: 'default',
        //   quality: 75,
        // },
      },
    ],
  ],
  nextConfig
)

require(...)する時に相対パスではなく、絶対パスでやりたい場合

next.config.js
const { resolve } = require("path")
const nextConfig = {
  webpack: (config) => {
    // next-optimized-images
    // 名前は何でも良い(@p、~images、@publicImages ...)
    config.resolve.alias["@public"] = resolve(__dirname, "public")

    return config
  },
}

こうしておいて、/publicからいつものように参照するように@publicから始める(名前は何でも良い)

  ...
  ...
  return(<img src={require("@public/../../")} />)
  ...
  ...