Web Speed Hackathon 2023 21位 132点 やったこと
- 概要
- リーダーボード
- スコア遷移
- コンテスト中にやったこと
- loading=“eager”から"lazy"にする f63158b
- Imageサイズ最適化 -> WebP (50MB -> 7MB) 1cd1cfc
- NODE_ENVをproductionで提供 6bc1207
- react.helmetの依存削除 49d67e3
- svgリサイズ (10857.78k → 2.55k) 5e9dbd9
- lodashの依存削除してbundleサイズ削減 c6cef64
- product/3 の mp4のロードが長すぎるためwebmに修正 (24.5MB -> 9.6MB) 8d45c77
- bundleサイズ削減 d56ff14
- ApolloClientのfetchPolicy変更 8d45c77
- 依存関係がない非同期処理をPromise.allして並列に処理 898c084
- フォント読み込み設定 d51d934
- ヘッダーと今週のおすすめは先に画像ロードするようにする 7df56d8
- aタグ遷移してるのでSPAに治す 7df56d8
- viteのbrotli提供 a8c314c
- 静的ファイルのキャッシュ max-age=3600 a8c314c
- dynamic import f724af6
- 最終
- できなかったこと
- 感想
概要
激重サイトを見た目(画像やCSS)は変更しないで、軽くしようというやつです。
得点はlighthouseの指標を元に計算されます。
リーダーボード
レギュレーション違反を除き、全体 21 th / 58 でした
Web Speed Hackathon 2023 リーダーボード
スコア遷移
コンテスト中にやったこと
リポジトリをforkして
fly.ioにデプロイ -> https://holy-wave-858.fly.dev/
何も変えずにlighthouseで初回計測
loading=“eager”から"lazy"にする f63158b
大量に画像を読み込んでいるので遅延読み込みに変更
Imageサイズ最適化 -> WebP (50MB -> 7MB) 1cd1cfc
public/images/avatars/ 配下のpngをwebpに変換するコマンド
imagemin public/images/avatars/* --plugin.webp.quality=95 --plugin.webp.preset=icon --out-dir=public/images/avatars/
画像の参照パスをsqliteで管理していたので、sqlite3のmedia_fileの.jpgを.webpに変える
sqlite> select * from media_file; sqlite> select replace(filename,"jpg","webp") from media_file; sqlite> update media_file set filename=replace(filename,"jpg","webp"); sqlite> select * from media_file;
NODE_ENVをproductionで提供 6bc1207
NODE_ENV developmentだと無駄なものを読み込むのでproductionに変更
react.helmetの依存削除 49d67e3
Webページのタイトル変更にしか使ってなかったためdocument.titleに変更
svgリサイズ (10857.78k → 2.55k) 5e9dbd9
開発者ツールのnetworkタブを見てヘッダーロゴのsvgがやたら重いため調査・修正
lodashの依存削除してbundleサイズ削減 c6cef64
fast-deep-equalを使う
https://note.com/green_grass_grow/n/n0703595eafb9
lodash (69.9kB) -> fast-deep-equal (852B)
product/3 の mp4のロードが長すぎるためwebmに修正 (24.5MB -> 9.6MB) 8d45c77
ffmpeg -i 001.mp4 -strict -2 001.webm ffmpeg -i 002.mp4 -strict -2 002.webm ffmpeg -i 003.mp4 -strict -2 003.webm sqlite3 databases/database.seed.sqlite sqlite> select * from media_file; sqlite> select replace(filename,"mp4","webm") from media_file; sqlite> update media_file SET filename=replace(filename,"mp4","webm"); sqlite> select * from media_file;
getMediaType関数も修正
bundleサイズ削減 d56ff14
https://zenn.dev/manalink_dev/articles/vite-bundle-analyzer
date-time-format-timezoneが大きく、chromeでは標準でついているので削除
ApolloClientのfetchPolicy変更 8d45c77
https://www.apollographql.com/docs/react/data/queries/#cache-and-network
cache-firstに変更
依存関係がない非同期処理をPromise.allして並列に処理 898c084
https://zenn.dev/lollipop_onl/articles/mistake-promise-all
フォント読み込み設定 d51d934
必要なフォントだけ読み込むように変更 https://zenn.dev/neriko/articles/3b55c547a07c8d22c9f1
ヘッダーと今週のおすすめは先に画像ロードするようにする 7df56d8
aタグ遷移してるのでSPAに治す 7df56d8
viteのbrotli提供 a8c314c
https://github.com/vbenjs/vite-plugin-compression
静的ファイルのキャッシュ max-age=3600 a8c314c
dynamic import f724af6
最終
- First Contentful Paint 16.0s -> 1.9s
- Speed Index 25.9s -> 3.0s
- Largest Contentful Paint 36.5s -> 9.2s
- Time to Interactive 31.5s -> 2.7s
- Total Blocking Time 11310ms -> 310ms
- Cumulative Layout Shift 0.8 -> 1.363
Cumulative Layout Shiftだけ悪化したどうして…
できなかったこと
ログインページ周りのパフォーマンスチューニング
graphqlとwasmのパフォーマンスチューニング
本来の画像が読み込まれる前に画像のプレースホルダーを入れて画像領域確保
CloudFlareを使用してCDN配信 (DNS設定反映が間に合わなかった)
https://nobunobu1717.site/?p=3142
感想
今までISUCONでバックエンドのパフォーマンスチューニングをやったことはあったのですが、フロントエンドのパフォーマンスチューニングは初めてだったので新鮮でした。
すぐに自サイトに適用できそうな画像系のテクニックなどすごく実践的でした。
上位陣のチューニング方法を見つつ精進したいです。