今年はWeb Speed Hackathonにオンライン参加できた。
最近の私の属性はPHPサーバーサイドエンジニアなので、普段は全然フロントエンドっぽいことをやらない。 それで、最新の開発現場っぽい最適化を体験したかった。
成績は最初の方のチューニングで手間取って思ったようにスコアが上がらなかった。残念。出直します。
まず初期状態のアプリにChromeでアクセスしたら、全然画面が描画されなくて困った。 重すぎてタブのプロセスが応答なしになってしまった。
仕方なくCURLとW3m(!)でアクセスすることにした。 SSRの初期データに大量のオブジェクトを注入しているのを、生HTMLを開いたら発見した。 コメントアウトすると速くなったので、ここがボトルネックと判断した。
内部APIをCURLで叩くと、数十MBのレスポンスを10秒ぐらいかけて処理していた。 APIの該当箇所をチラ見するとDrizzleのクエリが書いてあったのでDBだろうなと思ってSQLiteファイルを確認して、とりあえずインデックスを追加した。 これには罠があってSQLiteファイルがGitHubのファイルサイズ上限100MBに引っかかってPushできなくなった。Git LFS導入や外部Gitリポジトリに移行などチャレンジしたが最終的にはVACUUM発行したらギリギリサイズに収まった。
次にN+1クエリがあれば修正しようとレスポンスを読むとテーブルの全カラムをダンプしてたので、必要なカラムのみに減らすことにした。
この段階でChromeで開けるようになったが、Lighthouseのフル分析が成功しなかった。 ついでにChrome拡張も巻き込まれて死んでた。
定石どおりwebpack bundle analyzerを導入した。 発見された巨大バンドルの除去に取り掛かることにした。
FFMPEGをクライアントサイドで動かし、サムネイルを動的に生成してて面白かった。
あとはSVGの中にフォントが埋め込んであった。
Web Speed Hackathonはこのように普通に開発していたら「そうはならんやろ」というデチューニングを発見して、地雷を除去した後に普通のチューニングに取り掛かるという工程になることが多い。
それに加えてチューニング過程で機能落ち(デグレ)を作ると、レギュレーション違反で失格する。 後半に進むにつれて、自然と保守的にならざるをえないマインドセットが要求される。 リーダーボードの順位更新で承認されて報酬が得られるのは、射倖心との戦いだ。
参加したことないけど、ISUCONも似たようなものかもしれない。
LLMに丸投げして「自動で高速化して」と頼むのは無理そうだと判断し、早々に諦めた。 「自分で読めばわかるが?」というレベルの項目だった。
ただ、高速化過程の画像一括変換スクリプト生成とかには、LLM氏も活躍できそうだった。
そのあとは画像をWebPにしたりした。 CSSランタイムや巨大ライブラリの依存を排除したりもした。 というリソース効率の良さそうなポイントだけ優先してやろうとしてたけど、やり切れるところまで行かなかった。
他にはJSの実装をCSSで置き換えたりすると良かったらしい。
高スコアを出してた人の中には、独自にCDNを通したりする例もあったそうだ。 すごい。
今回は公式リポジトリにHerokuの企業アカウントが紐づいていて、参加者がプルリクエストを立てると自動でReviewAppsとしてデプロイされるというすごい仕組みが導入されていた。
ただ、このデプロイはうまく動作しないこともあり、個人Herokuアカウントセルフデプロイすることにした。 競技後の解説によると、当初は課題アプリを重くデチューニングしすぎてHerokuにデプロイできなくなったそう。 なので逆に運営の人たちがセルフでチューニングする必要があったらしい(面白い)。
運営側としては、参加者にフロントエンド属性の人が多いし、インフラ負担を巻き取って減らしたいのもありそうだ。 並行して最大限に重くしたアプリが次々に並列にデプロイされることを考えると、この競技の運用には高いスキルが求められる。 苦労がうかがえる。
あと競技後の目視チェックが大変そうだった。対策として今後は機能落ちアプリをGitHub Actionsのスコアリング過程で落とすのが考えられる。 次回からはさらに事前のVRTの重要性が増しそう。
私はVRTのことをすっかり忘れていた(というか余裕がなかった)。 終了後におさらいでやってみたけど、何故か差分が出てしまい、解決できなかった。 しかしレポジトリを初期状態に戻しても差分が出てた。 最初に自分の環境で比較画像のスナップショットを上書きしておくのが賢明だった。
スコア算出の仕組みについて。GitHub Actionsから非公開リポジトリにある計測スクリプトを読んで実行する仕組みだった。 このため参加者からはスコア計算過程のみブラックボックスになっているのが上手い仕組みだ。 昨年のリポジトリを読んだことあるけど、Playwrightで描画したLighthouseのレポートをPuppeteerでスクレイピングするという凝った仕組みだった(逆だったかもしれない)。
楽しかったのでまた来年も参加したい。