Home

Web Speed Hackathon 2025 参加記

こんにちは。Cyber Agentさんが開催しているWeb Speed Hackathon 2025に初めて参加させていただいたので、その感想とかもろもろを書き連ねます。

Web Speed Hackathonとは「予め準備してあるWebアプリケーションのパフォーマンスを改善することで競い合うハッカソン」1であり、めちゃくちゃ重たいWebアプリケーションのチューニングをし、どこまで軽くできるかを競うイベントです。スコアは各ページのLighthouseのスコアと決められたフローのスコアを合計し計算します2。今回の題材は「架空の動画配信サービス」3ということで自分にとっては比較的馴染みの深い題材でした。

参加時のリポジトリ

GitHub - kq5y/web-speed-hackathon-2025
Contribute to kq5y/web-speed-hackathon-2025 development by creating an account on GitHub.
GitHub - kq5y/web-speed-hackathon-2025 favicon github.com
Contribute to kq5y/web-speed-hackathon-2025 development by creating an account on GitHub.

初めての参加でしたが順調にスコアが上がっていき、最終的にスコア単体では1位だったもののレギュレーション違反により失格になってしまいました。というかそもそもレギュレーションチェックを受けた上位陣はほとんど失格し残った一人の方が新たな1位になるという… もう少しで1位になれた悔しさを供養するためにもなにをしたかを振り返っていきます。

最終ランキング

やったこと

時系列順でコミットログを抜粋します

1日目

webpack-bundle-analyzerを使用してファイルを見てみると、100MB以上あったのでいらないところを削っていく事から始めていきました。

  • e133138 lodashを置き換え
  • b2a6bad iconを全て読み込んでいたため、@iconify/reactに変更
  • 86438d8 画像のpreloadとHydrationDataを削除、SSRからSPAへ
  • 6743232 JPEGのサムネ画像をAVIFに置き換え
  • f71a019 p-min-delayの削除
  • 4be745d SVGのロゴもAVIFに置き換え
  • ea780db 番組表のチャンネルロゴをPNGに置き換え
    SVGにfont情報がbase64で埋め込まれていて既存ツールでの変換ができなかったため、Playwrightでスクショを撮るスクリプトを作成。
  • 445eca0 適当にimg要素にloading="lazy"を追加
  • 592b3fc 不必要なpolyfillを削除

今回の公式デプロイ環境はherokuでしたが、privateにできないなど色々問題がありそうだったので、去年と同様の Koyebで始めました。

[15:25] 計測 58.25 / 1200.00

  • 962a3d7 番組表の説明画像をpublicに移動し、AVIFに置き換え
  • 7d21b0d 404ページのGIFを圧縮
  • 1a4c4b9 ReDOSを修正
  • 47a0fb6 WebpackからViteへ移行
    Webpackでのチャンク分割がうまくできず、ビルドも遅かったためわかりやすいViteに移行。
    rollup-plugin-visualizerも導入し簡単にバンドル分析ができるように
  • 5b5b201 hls.jsvideo.jsを削除しshaka-playerに統一 全部を試してみて、一番バンドルサイズが小さくなったshaka-playerを採用。
  • fbc5816 DialogでHeadless UIの全てをimportしていたのを修正
  • 391430d シークプレビューの画像を生成済みのものに変更。ffmpegとかを削除 これでバンドルからwasmも消せてサイズ大幅削減に。

[18:20] 計測 52.95 / 1200.00

[19:24] 計測 53.50 / 1200.00

  • 8ae02d6 DB初期化時のサムネイルURLからランダムデータであるversionを削除
    ここで乱数が狂い、「表示されるコンテンツがオリジナルのものと異な」4ってしまう現象が発生
  • b9198cc createPlayerのdynamic importを修正

ここから乱数のズレによりテストの対象idが存在しなくなってしまうせいか、視聴ページなどのスコアで上振れするため嘘スコアになります。

[20:21] 計測 461.50 / 1200.00 (嘘)

本人はまさかの暫定2位に驚いていました。嘘スコアなのは気づいていません。

  • 8a37616 各要素のdescriptionが全て5000文字ほどあるが、表示するのは200文字程度なので、いらないdescriptionは消し必要なのは短縮することで、レコメンドAPIのレスポンスを小さく
  • 6128282 404ページのレコメンドAPIを更に小さく
  • 5f9dccb HoverableをCSSに置き換え
  • a0b65be シーク処理を置き換えてポインター関連を削除 <- ここで悲劇
  • a5e7214 Ellipsisline-clampに置き換え
  • 9197f7d AspectRatioをCSSに置き換え

[00:29] 計測 381.60 / 1200.00 (嘘)

ここらへんでログインモーダルがおかしくなっていてフォーカスすると全てが固まるため、hydrateRootの引数などを修正してみたりしています。

  • 3b4da63 Dialogの中身部分を別コンポネントに分離
  • 4f652ee レコメンドAPIでentrance以外はlimit:1

[01:18] 計測 25.85 / 1200.00 (嘘)

NO_FCPが大量発生し何故かスコアが一気に低迷しました。おそらくhydrateRootとか起因?

[01:38] 計測 27.05 / 1200.00 (嘘)

  • 5d9e76c playlistのX-AREMA-INTERNALを削除
  • 5b5110f bufferingGoalを50から20に変更

ここでKoyebが遅いのかと思い、Cloudflare Tunnelを用いて自身のPCから配信する形に変更

[01:56] 計測 23.55 / 1200.00 (嘘)

  • 2bbda0a hydrateRootの引数を変更
  • a3e9003 no-cacheを削除
  • 76716ed プレイヤーにpreload: "metadata"を追加

[03:10] 計測 434.00 / 1200.00 (嘘)

[04:04] 計測 451.70 / 1200.00 (嘘)

  • 4e0ac9b @sinclair/typebox, @sinclair/typemapを削除
  • 222f0ee @iconify/reactをSVGへ置き換え
    生成済みのサイトから一つ一つコピペしていきました。

[05:07] 計測 459.25 / 1200.00 (嘘)

眠くなったのでベッドイン。UnoCSSのドキュメント5を見ながら就寝。1日目の稼働時間は03/22 10:30から03/23 05:30でした。

2日目

顔を洗って、アセットを複数種類作るのとUnoCSSの調整をした後、APIの調整とフローを通すことを目標に2日目開始。

  • f365ebf サムネイル画像をsmall/bigの2種類に
  • 746f6e0 トップページにあるpreview用に小さいサイズの動画を生成 tsファイルのサイズを小さくするスクリプトを作成

[10:35] 計測 458.75 / 1200.00 (嘘)

[11:49] 計測 595.65 / 1200.00 (嘘)

フローを成功させるために、aria-labelをつけてみたり6いろいろしてみた。

  • 351e07d react-final-formを削除
  • 3814c7c 乱数のズレ問題を解決

[13:46] 計測 239.65 / 1200.00 (ここから本当)

おまけにここからフローで得点がつくようになった

[14:18] 計測 376.22 / 1200.00

[14:43] 計測 391.86 / 1200.00

何回か試しても番組表のフローでPROTOCOL_TIMEOUT7が発生。調べてみても謎だ…

  • 062deaf データベースの同期間隔を1000msから5000msに変更
  • 7ace806 データベースにインデックスを追加8

[15:11] 計測 380.08 / 1200.00

  • 6e54597 polyfillのsetimmediate削除 (悲劇の弊害)

[15:24] 計測 319.23 / 1200.00

回線速度などでランダム性が出るため9、ここからKoyebに戻る

[15:50] 計測 413.86 / 1200.00

残り2時間を切ったのでレギュレーションチェックを実施。テストケース大丈夫でなさそうなところを手元で確認する。
そこで1時間延長のお知らせ10。ラッキーと思い各ページの調整を行う。

  • 3e47488 episodeページの調整。画面下部のレコメンドAPIのリクエストをページ読み込み後にしたり、コンポネント分割、その他CSSの調整。
  • 9eab063 404ページの調整。useLoaderDataを使ったり
  • 708edc7 homeページの調整。上と同じく。
  • e2d6557 episode, programページの調整。上と同様にprefetchやコンポネントの調整
  • a3c48de seriesページの調整。上と同じく。

[17:06] 計測 460.67 / 1200.00

  • 8dc6256 次の番組を取得するAPI(/api/programs/:programId/next)を作成。programページで都度timelineを取得していたためそれを置き換え。
  • 7bc4a81 番組の詳細を取得するAPI(/api/programs/:programId/detail)を作成。番組表ページの読み込み時に呼ばれるAPIのサイズを小さくし、dialogを開く際に追加で情報を取得する。
  • 4fb56b1 その他のAPIにおいても、descriptionがとても長いため最初の300文字を抜粋する処理を適応。

[18:22] 計測 728.49 / 1200.00

最後の/retry、まさかの暫定1位に心臓バクバクです。

最後のスコア

2日目の稼働時間は03/23 08:30から03/23 18:30で、食事や休憩を含めた総稼働時間は27時間でした。

結果

結果は最初に書いた通り、レギュレーション違反で脱落になりました。違反の内容は「シークサムネイルが表示されず、ポインターに追従しない」4であり、実際に確認してみるとサムネが0sの状態のまま動かない不具合がありました。ここでClineに頼り切ってしまい眠いのもあってreviewしないまま変更を acceptしてしまったことが原因という。最後にルール一覧を見ながらレギュレーション違反を確認したときも、ここはできていたから大丈夫だろうという風に考え、その箇所の確認を飛ばしてしまいました。(意味がない)
revertすればすぐ動く内容であり、しかも逃したものが1位のため山のように押し寄せてくる悔しいの感情。

スコア推移

リーダーボード

Web Speed Hackathon 2025 リーダーボード
Web Speed Hackathon 2025 リーダーボード favicon web-speed-hackathon-scoring-board-2025.fly.dev

やりたかったこと

まだLate Submissionができないっぽいので(できるようになりました)やりたかったこともついでに書いておきます。

  • luxuonなど置き換え可能なライブラリがあったのでその削減
  • zodなどのバリデーション系はよくわかっておらず手を付けなかったが、型情報のみしか関与していない場所を削除したかった。
  • GIFファイルをWebMとかにしてみる
  • 番組表のフローを成功させたかった(未だ原因不明11
  • setIntervalとかあえて複雑な処理をしているところを修正しきれていない
  • 番組表のリサイズ処理が重いのがそのまま
  • カルーセルをCSSに置き換え(scroll-snap-type)

終了時のvisualizer

特に、main.jsの大半をzodとluxonが締めているのでここを消せれば更に良くなりそう

あと解説の放送を聞いていると、CSSで色々できるみたいで最近のCSSはすごいなと

他にも、公式でVRTが用意されていたのですが、その画像がdarwinのものだったり、WSL環境だと失敗したり、GitHub Actionにうまく搭載できなかったりで活用できなかったので次回以降は活用したいですね。

まとめ

DevToolsのPerformanceやLighthouseの使い方など、たくさんのことを学べてとても楽しく参加できました。スタッフの方には感謝いっぱいです。来年こそリベンジします。
あとClineも他の人の書いたコードなので、ちゃんとPRみたくreviewして内容を把握しましょう。

追記(2025/04/25)

Late Submissionができるようになったので、スコアを計測してきました。 なお、デプロイ環境がHeroku+Cloudflare Proxyになっています。

まずは大会本番中の最終サブミットと同一コードでスコアを確認します。なお、システムの都合で大会本番は計測できていなかった11部分を除いた点数がカッコ内です。

計測 589.71(586.71) / 1200.00

環境の変化がおそらく要因なのですが何故か結構下がりましたね。ついでにCloudflare Tunnelで試してみてもあまり変わりませんでした。ジャッジ側でなにか変化があったのか、それともKoyebがそんなに良かったのか…

次にミスを見つけていれば大会本番中に達成できた点数を確認します。

計測 580.42(572.42) / 1200.00

んーしかしそれでも1位の人は500超えてないので…
ここからは大会期間中にできなかった改善をします。

計測 583.18(579.43) / 1200.00

まだまだ改善できるところはあるので時間ができたら取り組んでみますが、今回は一旦ここまで。やっぱり悔しいですがリベンジを夢見て頑張ろうと思います。

付録

他の参加者さんの記事

Web Speed Hackathon 2025参加記
Web Speed Hackathon 2025参加記 favicon zenn.dev
【参加記】Web Speed Hackathon 2025で優勝した話
【参加記】Web Speed Hackathon 2025で優勝した話 favicon zenn.dev

今回参考にした過去イベントの参加記

Web Speed Hackathon 2025 参加記 | 2025.03 | Articles | Asa's Website
CyberAgent の Web Speed Hackathon 2025 に参加してきました!
Web Speed Hackathon 2025 参加記 | 2025.03 | Articles | Asa's Website favicon a01sa01to.com
Web Speed Hackathon 2022 の解説と振り返り - d-haru’s blog
この記事は「はてなエンジニア Advent Calendar 2022」の11日目の記事です。 10日目は@NanimonoDaemonさんの「CSSのLiveReloadする!開発環境でのCSSのビルドをViteに任せてバックエンドとViteの開発サーバーを連携させる」でした。 はじめに 先日、CyberAgent さんが主催する CyberAgentHack/web-speed-hackathon-2022 に参加しましたので、その時にやったことなどの解説と振り返り記事になります。 Web Speed Hackathon 2022 とは? "Web Speed Hackathon 2022…
Web Speed Hackathon 2022 の解説と振り返り - d-haru’s blog favicon d-haru.hatenablog.com
Web Speed Hackathon 2022 の解説と振り返り - d-haru’s blog
Web Speed Hackathon 2021 miniでほぼ満点を出しました
あけましておめでとうございます! 19の翠(sappi_red)です。 いつもはSysAd班 [https://trap.jp/sysad/]で部内サービスの開発・保守をしています。 Web Speed Hackathon 2021 miniに参加した(している)ので、今回はそれでほぼ満点を出した話を書きます。 このコンテストはWeb パフォーマンス改善を競うものです。 イベントの詳細は開催告知記事 [https://developers.cyberagent.co.jp/blog/archives/32747/] をご覧ください。 今回のminiは今年の2月に行われたWeb Speed Hackathon 2021をベースにしているようです。 そちらの方にも参加したのですが、そのときに参加記を書いていなかったので、振り返りつつ記録するのにちょうどいい機会なのといくつかできそうなことがあったので、参加してみることにしました。 年末には記事を出そうと思っていたのですが、文量が増えて結局終了1日前になってしまいました…。 前回のリポジトリ [https://github.com/sa
Web Speed Hackathon 2021 miniでほぼ満点を出しました favicon trap.jp

脚注

  1. https://cyberagent.connpass.com/event/338797/ より引用

  2. 詳しくはdocs/scoring.md

  3. 名前はArema、どこかで聞いたことあるような…

  4. イベントDiscordサーバーの違反理由より 2

  5. https://unocss.dev/integrations/vite

  6. 効果は不明 https://qiita.com/thithi7110/items/b42025e78cb64455ba9b

  7. ここで何故か発生 https://github.com/CyberAgentHack/web-speed-hackathon-2025-scoring-tool/actions/runs/14016035455/job/39241821905#step:7:78

  8. やり方があっているかわからないし、効果も軽微

  9. ここで家族がドラマを見始めたため帯域を圧迫

  10. Heroku 関係でたくさん不具合が起きていたらしく、それ以外を選択して正解だった。

  11. やっぱりスコアリングのツールが壊れていったっぽいです。 2

icon

kq5y