Closed y4shiro closed 1 year ago
思い当たる節が 2 点ほどある
前者から調査する
next/image の blur エフェクトが重いので、これ切るだけでかなり改善する
一旦 blur を削除した状態でコミット後、スマホでの挙動見てみると、 スマホでの挙動が大分改善され、モーダルを開いた時やフィルタの切替時もかなり軽快になった
next/image はデフォルトで lazyload が有効になっており、viewport 外の要素は画像読み込みが行われない様になっている
https://nextjs.org/docs/api-reference/next/image#loading
The loading behavior of the image. Defaults to lazy.
現在の Modal コンポーネントを調査してみると、Card コンポーネントの殆ど全ての読み込み / レンダリングが行われている この現象は、next/image が生成する要素の高さ (height) がレンダリング開始直後に 0 となっているのが原因 これにより、map で展開している Card コンポーネントの 9 割程が viewport 内に収まってしまい、lazyload が意味を成さなくなっている
これを解決するため、レンダリング開始時に viewport 外にある Card コンポーネントに関しては代替コンポーネントを表示し、viewport に近づいた場合に本物の Card コンポーネントに差し替えて表示する方法を取ることにした
これは next/image の blur 要素を削除するだけ
今回のロジックとしては、SelectableCard コンポーネントが viewport 外の場合はダミーや placeholder に該当する代替コンポーネントを表示し、viewport に近づいた場合は本物の SelectableCard コンポーネントに差し替えるというものにした
また、今回は Intersection Observer で SelectableCard コンポーネントが viewport に近づいたかを判定することにした
React で Intersection Observer を扱うライブラリを採用した
最終的に次のようなコードを書いた
MultipleObserver コンポーネントの実装により、Modal コンポーネントを開いた場合にレンダリングされる Card コンポーネント (next/image) の数が 200 個から 30 個程に抑制され、モーダル開閉やフィルタ絞り込みの処理時間も短縮された
Chrome Devtools のパフォーマンス機能で、モーダル開閉やフィルタ絞り込み時の所要時間を計測した
改善前 500 ~ 800 ms 改善後 300 ~ 400 ms
ALL -> SSR 改善前 200 ~ 238 ms 改善後 100 ms
SSR -> ALL 改善前 380 ~ 438 ms 改善後 248 ms
merge したので close します
カードスロットをクリックしてモーダルを開く際、クリックしてモーダルを開くまでに結構な時間が掛かっている(500 ~ 800ms) モーダル自体のアニメーションに 200 ms ほど掛かっているものの、それを差し引いても長いので改善したい また、モーダル開閉以外にカード表示のフィルタ切替時も時間が掛かっているので、こちらも併せて改善したい
計測した値
改善前の値を記載する
モーダル開閉
500 ~ 800 ms
レアリティ切り替え
ALL -> SSR : 200 ~ 238 ms SSR -> ALL : 380 ~ 438 ms
Todo