Web Speed Hackathon 2025 参加記
Web Speed Hackathon 2025 に出ました(オンライン参加)。
いろいろやったので、一応記録を残しておきます
1日目 12:00
1日目は学校の終業式と被ってたので遅めから参加。まず Heroku にデプロイして触ってみると、嘘みたいに遅くてウケた。
スコア計測: 67.00
初期状態のスコアは 67 。
1日目 13:00
ChatGPT にコードベース全体食わせて、明らかに遅そうな点をいくつか修正:
- fetch の1秒待機を消す
- 動的 import の p-min-delay を消す
- マウス位置の常時取得を削除
1日目 16:00
画像関係の読み込みが死ぬほど重かったので、このサイズを最適化:
- SVG の最適化
- もともとの SVG はフォント全体が base64 で埋め込まれててクソでかい
- Inkscape の CLI から操作指示する、みたいな機能で SVG を全部開いてアウトライン化し、単純な SVG にするシェルスクリプトを書いた
- Inkscape は base64 の埋め込みフォントを扱えないようだったので、使われてるフォントを全部インストールした
- jpeg の最適化
- squoosh で雑に小さくする
- squoosh の CLI はサポートが終了していて動かなかったが、 @frostoven/squoosh-cli で行けた
- animation の最適化
- 404 時のループアニメーションの gif がバカ重かったので、 ffmpeg で WebM にしてサイズも最適化
- デカ目の動画においては、 gif はそもそもコーデックとしてめちゃくちゃ不利
1日目 16:30
シークバーのサムネイルを計算するために、毎回 WASM の ffmpeg をブラウザ上で動かすという凄い実装になっていたのでこれを剥がす。
単純に事前計算しておき、静的な画像として配信するだけ。
1日目 17:30
main.js
が 60MB とかでクソでかいので小さくする。
まず、 webpack のビルド設定が全然駄目なのでこれをしっかりサイズ最適化するものに変更。
また、アイコンライブラリを何種類か全部まるごと読み込む、ということになってたので必要なものだけ読み込む設定に。
これで 60MB -> 5MB ぐらいに。まだまだデカいけど一旦 OK とする。
1日目 19:00
サイトを開いたときに読み込まれるレコメンドの情報が毎回 60MB とかになっててヤバかったので、情報の持ち方を工夫する。
といっても、毎回全部の参照データを馬鹿正直に再帰的に展開するようになっていたのを、 id->data のマップで持つようにするだけ。
加えて、大多数のエピソードに対しては description を提供する必要がなく、 description がデータ容量のほとんどを占めているので、いらない部分を消した。
これで 60MB -> 400KB ぐらいに。
スコア計測: 8.75
ここらへんまでで、体感ではかなり速くなったので、スコアの計測をしてみる。
すると、全くスコアが出ず(最初よりもずっと悪化)、どこかがバグってそうということで、色々と問題点を探すフェーズに。
結論から言うと、これは恐らく一部が高速になったことにより lighthouse の計測の何かが掛け違い、スコアが一時的に下がっただけだった。それをバグと思い込み、5,6時間を費やしたのが今回の敗因。
2日目 11:00
1日目夜から2日目朝にかけて色々検証するも、問題が全く意味不明なので、 WSH のスコア計測ではなく lighthouse の生のスコアを信用して改善していくことに。
とりあえず lighthouse のデータを ChatGPT に丸投げすると、 SSR ができてなくね?とのこと。
SSR とかを触ったことがなくよくわからないが修正すると、 lighthouse スコアは改善。この方向性で良さそうなので進めていく。
2日目 15:00
もともとは UnoCSS によって、実行時に(ブラウザで) CSS を動的生成していた。
これはどう考えても重いし良くないので、事前生成するように。
これがマジで難しくて、いろんなエラーを踏みながら4時間とかかけてしまった。ふだん Vite を使っていて、 webpack に詳しくなかったのも一因だが、それにしても苦戦した。
2日目 17:00
ChatGPT の指摘によると、 Heroku は HTTP1.1 を使っていて、これも遅くなる原因らしい。更に、 API レスポンスなどが圧縮されておらず、それも良くないとこのと。
ここらへんを一気に解決する方法として、 Cloudflare に載せることにした。
自分のドメインを持っていなかったので(というか更新をサボっていたらいつのまにか解約されていたので)、新しく nahco314.dev を取り直す。 DNS 周りの設定を頑張ると、このドメインからアプリを開けるようになって、キャッシュ、プロトコル、CDN などの問題が解決。
2日目 18:30
main.js がまだデカいので、チャンク化しようと頑張っていたが、なぜかうまく動かず競技終了。
スコア計測: 254.75
最終順位は 21 位。レギュレーションチェックに通ったかは不明だが、あまり細かい詰めをせずに高速化をしてた(というか時間と余裕がなくてチェックまで手が回らなかった)ので通ってないような気もする。
良かった点
- AI うまく使いながらいいペースで実装できた
- 想定されている改善のうち基本的な部分はほぼ全てできた
反省点
- Web の細かい知識や知見がまだ全然足りない
- 非本質な問題にハマって時間掛けすぎた、最初から lighthouse だけ見てれば...
Discussion