CSSの軽量化
洗い出した問題の中で、最も大きな問題を抱えていたのはCSSでした。タウンワークのCSSは、複数のページのスタイルが全て1つのCSSファイル内に結合された形になっており、ページごとに見ると、使っていないスタイルを大量に読み込んでしまっている状態でした。そのサイズは500KBにもなります。下の画像は、Chromeの開発者ツールで改善前のCSSのカバレッジを表示したものです。赤い部分が、使われていないスタイルのサイズを表しています。
理想の形は、ページごとに必要なスタイルのみを読み込むことです。しかしこれを実現するためには、それぞれのページについて、どのような場合にどのスタイルを使っているのかを全て洗い出し、個別のCSSファイルとしてまとめ直す必要があります。ユーザーの状態や、画面上の操作によっても切り替わるスタイルまで含めると、精緻に洗い出すことは困難を極めます。まして、時間的制約の下、その作業を人力で行うことは不可能でした。
そのため、私たちは「スタイルの自動抽出+リグレッションテストの徹底」という戦略をとりました。具体的には、ページごとに取りうるパターンのHTMLをできる限り収集し、それらの中で使用されているスタイルを自動抽出、新たなCSSファイルとして書き出します。元のCSSの代わりに新たに生成したCSSを使って、リグレッションテストを行います。もしパターン漏れがある場合、デザイン崩れが発見できるので、このパターンを新たに加えもう一度CSSファイルを書き出し、リグレッションテストを行います。この手順を、デザイン崩れが発見できなくなるまで繰り返します。これによって、リリース可能と判断できる品質を担保することができました。
下の画像は、改善後のCSSのカバレッジを表示したものです。最終的に、もともと500KBあった未使用CSSのサイズを12KBまで減らすことができました。使っていないスタイルが若干残っているのは、画面上のイベントに応じて使われるものがあるためです。
結果
CSSの軽量化を中心とする今回の取り組みによって、読み込み時間を40%程度削減することができました。下の画像は、改善前後のLighthouseの実行結果(Simulated Fast 3G、4x CPU Slowdown)を横並びにしたものです(2018年7月時)。
まとめと今後
本稿では、タウンワークにおけるパフォーマンス改善の取り組みについてお話しました。この取り組みの大きな成果のひとつは、開発セクション以外も含む事業組織内でパフォーマンスの重要性が以前よりも広く認知されるようになり、開発における意思決定をしやすくなったことです。
一般的に、成熟したサービスの開発現場では、リスクを回避するため意思決定に保守的なバイアスがかかりがちです。そのため、今回のようなリスクを伴う改善に踏み切れたことは、今後のパフォーマンス改善活動にとって大きな一歩であったと感じています。
私たちは、サービス開発におけるパフォーマンス改善活動を、攻めと守りの2つの観点から捉えています。攻めの活動とは、ユーザー体験に影響するパフォーマンスの課題を発見し、それを解決しにいくことです。守りの活動とは、現状のパフォーマンスを妨げる要因を、できる限り作り込まないようにすることです。これらの両輪を回すことで、継続的なパフォーマンス改善に取り組んでいきます。
いずれの活動においても、最も重要なことは、指標となる値を継続的に計測し、モニタリングすることです。ユーザー体験に直結するパフォーマンスの課題を浮き彫りにするためには、単純なコンバージョンレートだけでは不十分です。ユーザーの行動をより精緻に分析するため、サービスの性質に応じた中間メトリクスとログを設計する必要があります。パフォーマンスを妨げる要因を作り込まないようにするためには、リリース前後のパフォーマンスを比較して、悪化した場合には検知する仕組みが必要です。可能であれば、パフォーマンスに影響する項目について許容可能な「しきい値」を定め、リリースする前の段階でバリデーションをかけるのが理想的です。
今後も、少しでも使いやすいサービスをユーザーのみなさんにお届けできるよう、さまざまなトライをしながら、パフォーマンス改善活動に取り組んでいきたいと思います。
