くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

nuxt/imageで画像を最適化を試してみる

Nuxtの公式ツイッターをみてたら良さそうなライブラリが。
画像最適化ライブラリNuxt Imageを試してみたときの備忘録(´ω`)

まとめ

  • 用意されてるコンポーネントを使うと、サイズや形式の変更を自動でしてくれる
  • sizesにも対応していて、画面サイズによって適した画像を設定できる
  • SSR/SSGなら問題なく使える
  • SPA(ssr: false)だと、デフォルトのproviderじゃダメっぽい。。

使い方

インストール

まずはインストール

$ npm install -D @nuxt/image

nuxt.configの設定

nuxt.configでの設定は、targetによって異なる。
buildModulesに設定するかmodulesに設定するか。

target: 'static'

export default {
  target: 'static',
  buildModules: [
    '@nuxt/image',
  ]
}

target: 'server'

export default {
  target: 'server',
  modules: [
    '@nuxt/image',
  ]
}

Providerについて

Nuxt Imageでは、Providerという概念がある。

Providers

Providerはサードパーティの画像変換サービスとNuxtImageをつなぐ部分で、
Cloudinary, Fastly, Vercelなどを使うことができる。

デフォルトだとipxstaticが利用される。

いくつかのProviderが用意されていて、使いたい画像変換サービスのProviderを選ぶ感じ。

以降は、ipxとstaticを利用した場合の話。

コンポーネントを使う

コンポーネント<nuxt-img><nuxt-picture>の2つ。
それぞれ、<img><picture>に変換される

  • <nuxt-img> ... <img>タグ
  • <nuxt-picture> ... <picture>タグ

基本的な使い方

基本的な使い方はこんな感じ。

<nuxt-img
  src="/sample.png"
  width="450"
  height="230"
  format="webp"
  quality="80"
  fit="contain"
  background="#FFFFFF00"
/>
  • width/height: 横幅/高さ
  • format: 変換する形式(webp/jpeg/jpg/png/gif/svg)
  • quality: 画像生成時の品質
  • fit: 画像サイズの指定(cover/contain/fill/inside/outside)
  • background: fitを指定したとき余白の背景色

もちろん、srcだけでも動く。

レスポンシブ対応(sizes)

sizesを使うと、画面幅によってサイズの異なる画像を設定できる。

<nuxt-img
  src="/sample.png"
  sizes="sm:100vw md:50vw lg:400px"
/>

smmdなどはnuxt.configで設定でき、
デフォルトはこんな感じ。

export default {
  image: {
    // The screen sizes predefined by `@nuxt/image`:
    screens: {
      xs: 320,
      sm: 640,
      md: 768,
      lg: 1024,
      xl: 1280,
      xxl: 1536,
      '2xl': 1536
    },
  }
}

設定値をまとめておくpreset

各サイズとかをあらかじめまとめておいて名前をつけることができる。
presetの設定自体はnuxt.configに書く。

export default {
  image: {
    presets: {
      avatar: {
        modifiers: {
          format: 'jpg',
          width: 50,
          height: 50
        }
      }
    }
  }
}

presetを用意しておけばpreset="avatar"とするだけで、
width/height/formatの設定値が利用される。

<nuxt-img preset="avatar" src="/sample.png" />

はまったところ

背景色の設定

最初は背景色が設定できず、かなりはまってた。。

中を見てみると、各ProviderでURLを生成している感じ。
IPXを使ってて、modifiers: { background: "#FFFFFF"}としていても、
黒い背景になってしまう。。

ソースを見てみると、modifiersがなくてもいけるようだったので、
そっちをつかったらうまくいった(´ω`)

IPXのProvider(ipx.ts)だと、こんな感じでマッピングされるらしい。

image/ipx.ts at d9aeae2144ac815f45081d06f1b6b60e62e2ec14 · nuxt/image

  keyMap: {
    format: 'f',
    fit: 'fit',
    width: 'w',
    height: 'h',
    resize: 's',
    quality: 'q',
    background: 'b'
  },

modifiersを使った場合でも、URLのパラメタにbが含まれてたけど、
末尾に設定されていたのでうまく動かないようだった。。

ipx/handlers.ts at main · unjs/ipx

export const crop = extract
export const q = quality
export const b = background
export const w = width
export const h = height
export const s = resize

先頭にbが来ている場合はOK。そうでないと、Sharpのデフォルト背景色になっていたよう。

Resizing images - sharp - High performance Node.js image processing

SPAだとうまくいかない。。

SPAというか、ssr: falseだとうまくいかないっぽい。。

  • SSR ... ipxのserverMiddlewareが追加されるのでOK
  • SSG ... generate時にstaticな画像が生成されるのでOK
  • SPA ... staticな画像が生成されず、URLが/_ipx/...に。。

target: 'server'なSPAならいいけど使わないので、
SPAだと厳しい感じ(´・ω・`)

ipxが問題なので、別のプロバイダーならよさそう(´ω`)

以上!!

参考にしたサイト様