📑

Nuxtにも@nuxt/imageがあったので使ってみた

2021/03/13に公開

先日、以下の記事を書かせてもらったのですが

https://zenn.dev/kote2/articles/eac7f15443265c

React(Next.js)にあってVue(Nuxt.js)ないというのがあり、Vue(Nuxt.js)にこれあったらいいのになー、というのがあったわけです。

それは画像最適化モジュールです。

画像最適化モジュールとは?

webサイトに使用される画像は、実質1枚に見えますが、通常ユーザーは同じwebサイトを、PCから、タブレットから、スマホから閲覧します。また、これら閲覧する環境により、解像度が高いものもあり、その場合、通常の2倍サイズの画像を表示してあげないとボヤける等の仕様があります。

なので、以下のようにいろんな指定の仕方で記述しなければなりません。(ちゃんとやろうとすると)

<picture class="imgWrapper">
  <source media="(min-width:1200px)" srcset="
        /images/testxpc.jpg 1x, # PC用
        /images/testxwide.jpg 2x # Retina用
      " />
  <source media="(min-width:801px)" srcset="/images/testxtabs.jpg" /> #タブレット用
  <source media="(min-width:481px)" srcset="/images/testxsm.jpg" /> # スマホ用
  <img src="/images/testxpc.jpg" alt="" /> # どれにも属さなかった場合
</picture>

画像最適化モジュールを使用すると、ビルド時に勝手に生成してくれるので、このようにいろんなデバイス用に画像を用意する手間がなくなります。1つの高解像度画像さえあれば良いのです。

Next.jsの例をとってみるとこうです。

画像最適化モジュールの例(Next.js)

<!--通常のhtmlの画像表示タグ-->
<img src="/images/test.jpg" width="500" height="300" alt="テスト" />

<!--React(Next.js)でのnext/imageモジュールを使った場合-->
<Image
src={'/images/test.jpg'}
width={500}
height={300}
alt='テスト'
/>

<!--上記のビルド結果(多少簡略化してます。ほんとはソースがもっと複雑)-->
<img alt="テスト" src="/_next/image/test.jpg " decoding="async" style="min-width: 100%; max-width: 100%; min-height: 100%; max-height: 100%;" srcset="/_next/image/test2.jpg 1x, /_next/image/test3.jpg 2x">

実際どれほど違うかというと。この記事に貼ってる猫の画像が
https://basicnext-kote2.vercel.app/post/post-09

元画像: 1.1M
最適化後: 62KB
になってます。

本題: Nuxtにも@nuxt/imageがあった

https://image.nuxtjs.org/

※まだ日本語で解説してる人がいなかったので書きました。

使い方

ここから抜粋(Setup)

インストール

npm install -D @nuxt/image

nuxt.config.js編集

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

images(このモジュール)のオプションなどを設定

export default {
  image: {
    // Options
  }
}

でいけます。

詳しい解説は公式の方が間違いがなくて良いので、ここでは手っ取り早く試す方法を記述します。セットアップを終えたら

xxx.vue
<template>
  <nuxt-img
    src="/images/test.jpg" # 画像のパス
    quality="70" # ビルド時の画質(100が最高画質)
    sizes="md:100% lg:500px" # レスポンシブ設定
    class="inline-block"
  />
</template>

Nuxt版imageはクラスが使える

なお、next/imageではクラスが使えないようですが、nuxt/imageでは公式には記載されてなかったですがクラスが使えるので便利です。

Nuxt版imageは%やvwが使える

next/imageではfill以外の相対的な数値は指定できないですが、nuxt/imageではsizesで指定でき、しかもレスポンシブ設定もできます。書き方はなんとなくtailwindcssっぽいですね。

結果

こちらも、実際どれほど違うかというと。この記事に貼ってる猫の画像が
https://laughing-saha-766f92.netlify.app/post/post-09/

元画像: 1.1M
最適化後: 35KB
になりました。

外部の画像

外部の画像も取り込めるようで、その場合はオプションでドメインを追加する必要があります。

export default {
  image: {
    domains: ['https://nuxtjs.org']
  }
}

他にもいろんなオプションがありますのでご参照ください。
Opsions

ちなみにNuxt的にはこっちのほうが有名なんじゃないかと思います。
Nuxt Optimized Images

Nuxt Optimized Imagesを探し当てたところ、公式のツールが出てるのを発見しましたので、ここに書かせていただきました。

Discussion