こんにちは、エンジニアのオオバです。
はてなブログからNext.jsで構築した本ブログ。
画像のレンダリングは旧来の<img />
。
Next.js v10で登場したImageコンポーネントに
置き換えていませんでした。
MarkDownの画像にサイズ指定ができない。
↑これが解決できませんでした。
今回少し工夫してImage置き換えに成功しました。
そのノウハウを共有をしたいと思います。
→11万文字で徹底解説した「DOTweenの教科書」Unityアニメーションの超効率化ツールはこちら
LightHouse 7ポイント上昇
まずは結果からお伝えします。
Imageに置き換えたことで、
パフォーマンススコアは7ポイント上昇しました。
ページの読み込み速度が上がるというのは
単純にうれしいです。
画像URLにサイズ取得用のハッシュを仕込む
ここから実装についてのお話です。
![【Next.js】next/imageをMDXに適用してパフォーマンス大幅アップ_1](https://sample.com/img.png#300_200)
mdxファイル内の画像URLに
「#幅_高さ」 というキーワードを埋め込み、
Next.jsでレンダリング時に参照します。
具体的にどう実装していくのか解説していきます。
画像サイズをMarkDownは未サポート
通常MarkDownで執筆する時、
画像サイズは指定しません。
というかできません。
![【Next.js】next/imageをMDXに適用してパフォーマンス大幅アップ_2](https://sample.com/img.png)
MarkDownの仕様に画像サイズが
サポートされていないからです。
画像サイズを無理やり埋め込む
前述したとおり、
幅と高さをURLにハッシュで埋め込むことで
サイズ取得を実現しました。
![【Next.js】next/imageをMDXに適用してパフォーマンス大幅アップ_3](https://sample.com/img.png#幅_高さ)
大量の画像のサイズを埋め込む方法
Pythonでスクリプトを書いて、
- キー : 画像URL
- バリュー : 幅_高さ
という構成のキャッシュファイルを作りました。
https://sample.com/img1.png, 910_978
https://sample.com/img2.png, 930_509
https://sample.com/img3.png, 32_69
https://sample.com/img4.png, 120_387
https://sample.com/img5.png, 672_429
このファイルを参照して、
画像パスを変更しています。
分かりやすい図を用意しました
- ネットから画像を取得
- サイズを取得
- URL、画像の幅高さをセットにしたcsvを作成
- MarkDownからMDXへ変換
- 変換時に先のCSVを参照
- 画像のURLに画像サイズ情報を埋め込む
- MDXProviderを使ってimgタグを置き換える
- 最適された画像がレンダリングされる
といった流れです。
正規表現とMDXProviderで画像URLからサイズを取得
_app.jsxに記述しているMDXProviderで
MDXの整形処理をしています。
MDXProviderに渡している
ルールスクリプトは以下です。
const mdComponents = {
img: (props) => {
// 正規表現で画像URLから「#幅_高さ」を検索
const match = props.src.match(/#([0-9]*)_([0-9]*)/);
// サイズ情報が見つかったらImageを適用する
return (
<Image src={props.src}
width={match[1]}
height={match[2]}
/>
)
}
}
imgタグの時に正規表現を使って
画像URLからサイズを拾います。
その値をwidth
、height
に
それぞれ値をセットします。
MDXProviderでMDXを整形する方法は
こちらの記事で詳しく解説しています。
もしやり方がわからない方はぜひ読んでみてください。
外部サイトの画像はnext.config.jsに登録
💻ソースコード : next.config.js抜粋
images: {
domains: [
"sample.com"
]
},
外部サイトに配置した画像を表示するときには
next.config.js
にドメイン登録が必要です。
設定し忘れると以下のエラーが出力されます。
Unhandled Runtime Error
Error: Invalid src prop (【img url】) on `next/image`,
hostname "【ドメイン名】" is not configured under images in your `next.config.js`
パフォーマンス大幅アップ
Imageコンポーネントへの置き換えは、
パフォーマンスアップのためと
言っても過言ではありません。
震える手でドキドキしながら
計測ボタンを押しました。
以下LightHouseでの計測です。
Imageコンポーネント適用前後で
パフォーマンスが7ポイントも上昇!!
素晴らしい!!
結果
- Imageコンポーネント適用前後 : 7%アップ
- はてなブログ時代と比較 : 28%アップ
素晴らしいです。
苦労して実装した甲斐がありました。
まとめ
imgからImageに置き換えました。
結果的にパフォーマンスが大幅アップ!
まだImageを使っていない方、オススメですよ。
実装方針として、
MarkDownに画像サイズを仕込むのが味噌でした。
最後に、ブログをNext.js化して、
全ての機能を自分で
作らなければならないのは非常に面白いです。
まだまだ改善したい機能がたくさんあるので、
実装でき次第ブログで報告させていただきます。
この記事が気に入ったらフォローしよう
「Unity初心者大学」というUnity初心者向けのYouTube始めました!!
ぜひチャンネル登録をお願いします!
最後まで読んでいただきありがとうございました!
すばらしいNext.jsブログライフをお過ごしください。
- Next.js v11.1.2