web-speed-hackathon-2022に挑戦した
2023/01/06
最終更新:2023/04/12
web-speed-hackathon-2022に年末年始に挑戦してみた。
環境構築
ローカルが立ち上がるようにするまではREADMEの手順通りにやれば簡単だった。
しかし、計測環境まで準備するのは初めてだったのもあって2時間弱かかってしまった。やることとしては以下。
- fork先のrepoのSettings>FeaturesのIssuesにチェックする(forkしたrepoはdefaultがOFFになっているため)
- fork先のrepoのSettings>Actions>GeneralのAllow all actions and reusable workflowsを選択してSaveする(forkしたrepoはactionsがdefault OFFになっている)
- 何らかのホスティングサービスにデプロイし、本番環境のURLを取得する(後述)
- Issuesにて、
registration
というラベルを作成しておく(これがないとactionsのif文に入らない)
- 後はドキュメント通りにissueを登録し、github actionsが動くか確認する
デプロイ
herokuのfree planが2022/11/29に終了していたため、どこにするか迷ったが色々調べた結果renderを選択した。
チューニング
初回スコアは19.2だった。今回は本番期間後に挑戦してるため時間の縛りなどもなかったことから特に着手事項に優先度は設けず、目についたことからどんどんやっていった。
画像の圧縮
初回アクセス時にとりあえずNetworkタブを見たところ、軒並み画像のダウンロードに時間がかかってたのでとりあえず圧縮に挑戦。
https://saruwakakun.com/tools/png-jpeg-to-webp/にて、public/assets/images/races
のものをwebpへの変換をした後デプロイ。スコアが上がったのを確認したので全てのassetsを圧縮するとスコアは19.2 → 120.45と大幅に上がった。
バンドルサイズ
webpackのログを見ると約31Mあるのでこれを小さくしてみる。
analyzer結果
zengin-codeというものがデカすぎるが、初見でこれがなんなのかわからないためまずはlodashとmomentから取り組む。
lodash
使用箇所全て書き換えた結果31MB →29.23MBになった。スコアは120.45 → 131.25になった。
moment
使用箇所全てをJSのDateオブジェクトを使うように書き換えた結果 29.23MB →26.62MBになった。スコアはなぜか128.85に下がった。
webpack
webpack.config.jsを見ていたところdevtool: "inline-source-map"
とあり、distに吐き出されるコードが大きくなっていたのでこれを消したのと、mode: "development"
となっていてwebpackの最適化を受けれなくなっていたのでproductionとしてビルドが走るようにすると大幅にサイズが小さくなった。スコアも大幅に上がり128.85→204.1に。
26.62MB → 4.29MB
bebal周り
side-effect.js
でimportしていたpolyfil周りが必要なさそうだったので一式消した。この時Uncaught ReferenceError: regeneratorRuntime is not defined
と出てasync-awaitをbabelで読めなくなってしまったのでこちらの記事を参考にplugins: ["@babel/plugin-transform-runtime"]
をwebpack.config.jsに追加した。
4.29MB → 3.26MB
204.1 → 224.55
zengin-code
ついにこれ。調べたら銀行のデータらしい。公式?を見つけポチポチしていたところjsonを取ってこれそうだったのでNPM経由ではなくfetch経由でのデータ取得としてみた。ついにKBの世界にたどり着けた。
3.26MB → 419.07KB
224.55 → 382.3
framer-motion
css animationとして、styled-componentsのkeyframesで定義したコンポーネントを使うように置き換える。
419.07KB → 290.07KB
382.3 → 389.55
バンドル分割
Reactのlazyを使ってバンドルサイズの分割を試す。結果は以下。
290.07KB → 200.11KB
389.55 → 403.95
Light house
スコアも400超えてなかなか速くなってきたのでLight houseを見てみる。結果は以下。
あとはここに書かれていることを順番にやっていった。
Minify JavaScript
Reactの拡張機能を入れていると読み込まれるinstallHook.jsとreact-devtool-backend.jsが対象になっていたため一時的に拡張機能を削除した。
Reduce unused JavaScript
上記同様。
画像系
lazy loadingにする。アスペクト比をcanvasで計算していた箇所はcssに置き換えた。Top Viewの画像はlinkタグでpreloadした。なぜかサーバー側でasset urlにハッシュ値を付与していたのでこれをやめた。
Enable text compression
サーバーからのレスポンスを圧縮したら良いらしい。response headerにcontent-encoding
が付与されればいいらしいのでサーバー側のコードを見た。調べるとfastify-compressというプラグインが公開されていたのでこれを使用した。fastifyがv3系だったのでv5.0.0以下じゃないと動かない。
fastifyを最新のv4に上げようとしたが、周辺ライブラリも上げないといけなかったのとlogger周りの破壊的変更があったためやめた。
結果
ここまでやったらPerfomanceは100になったのでスコア計測したところ464.2に上がった。
まとめ
本番期間であれば11位になるスコアまで上げることができた。
勘所は掴めたので、今年の開催では10位以内にランクインしたい。