食べログ スマートフォンページのCSSを最適化してLCP改善にトライ！

この記事は食べログアドベントカレンダー2021の2日目の記事です:santa::evergreen_tree:

12/2(木) 担当、食べログWEBデザイナーの @mamiyan です。
食べログに入社してあっという間に4年目になり、頑張って先輩らしく振る舞っています...！



この記事では、今年の6月頃に取り組んだ、食べログのスマートフォンサイト（以下、SPと略します）のうち、[店舗詳細TOPページ](https://s.tabelog.com/tokyo/A1303/A130301/13238724/)のCSSファイル最適化についてLCPに触れながらまとめていきます。

▼食べログの店舗詳細TOPページ（例：プレミアムプラン）
<img width="375" alt="食べログの店舗詳細TOP" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/b08a6ed2-4962-1061-b6dd-97241bba3775.png">



#  **1.なぜCSSファイルを最適化する必要があったのか** 
- CSSファイルの肥大化
- 一部のCSSファイルの二重読み込み問題
- PageSpeed Insightsでパフォーマンスの悪さが目立っていた


長期運用されている大規模サービスならではの悩みかもしれませんが、多くの方が同一ファイルを修正しているので、一定ルールのもと適切にメンテナンスを行っていても歴史とともに肥大化していきます。

肥大化したCSSはブラウザのレンダリングパフォーマンスに悪影響を与えます。またコアウェブバイタル（Core Web Vitals）がGoogle検索のランキング要因に組み込まれると囁かれたタイミングで見過ごせませんでした。

さらにはGoogleのパフォーマンス計測サイトである[PageSpeed Insights](https://pagespeed.web.dev/?hl=ja)でパフォーマンスが悪目立ちしていたので、重い腰を上げて取り組みました。

なお、コアウェブバイタルやLCPについての詳しい説明は以下の引用にて省略とさせてください。

##  **コアウェブバイタルとは？** 

> Core Web Vitals は、Web 上で実際にユーザーが体験するユーザー エクスペリエンスに関する重要な観点の測定を目的とした一連のフィールド指標です。Core Web Vitals には指標と各指標のターゲットとなるしきい値が含まれており、これらを参考にすることで、運営するサイトでのユーザー体験が "良い"、"改善が必要"、"悪い" のいずれの状態にあるかを開発者が定性的に理解できるようになります。
引用：web.dev

> 2020 年時点で Core Web Vitals は、Largest Contentful Paint (最大視覚コンテンツの表示時間、LCP)、First Input Delay (初回入力までの遅延時間、FID)、Cumulative Layout Shift (累積レイアウト シフト数、CLS) という 3 つの指標により構成されています。それぞれの指標は、ユーザー エクスペリエンスに関する様々な観点を測定します。
引用：web.dev
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/a77d19b2-3128-0e20-67af-7e546b399381.png)

##  **LCPとは** 

> Largest Contentful Paint (LCP) 指標は、ビューポート内に表示される最も大きい画像またはテキスト ブロックのレンダリング時間を、ページの初期読み込み開始タイミングと比較してレポートします。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/abfb50ad-f234-a9db-5cbc-81a5e39351dc.png)

引用：web.dev



#  **2. 効果は？** 
取り組み内容を紹介する前に、効果について触れておきます。

CSSやdocumentのファイルサイズを537KBと大幅に削減しました！
ここまで大きなダイエットが見込めると思っていなかったので嬉しかったです。

対象ページ：https://s.tabelog.com/tokyo/A1303/A130301/13238724/

| Type | ファイル名 |  Before |    After    |
|:--------:|:-------:|:-----:|:--------:|
| CSS | application_inline.css  | 13.1KB  |    0    |
| CSS | rstdtl_common.css  | 27.2KB  |    0    |
| CSS | rstdtl_top.css| 19.3KB |   0      |
| CSS | rstdtl_async.css| 50.5KB |   0      |
| CSS | rstdtl_common_async.css| 52.5KB |   0      |
| CSS | rstdtl_top_async.css| 0 | 56KB        |
| document | 13238724/ (rstdtl_top_inline.css含む)| 519KB |   88.3KB      |
| 合計 || 681.6KB | 144.3KB     |

##  **2-1. Lighthouseで効果を確認する** 
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/77a626a0-90a2-3de0-1181-64cbc4078643.png)
ChromeのデベロッパーツールにあるLighthouseではLCPが0.6s改善されているように見えます。
ただ計測タイミング（時間帯？）によって大きくぶれる傾向があるのでなんとも言えません。



##  **2-2. [ PageSpeed Insights ](https://developers.google.com/speed/pagespeed/insights/?hl=ja&url=https%3A%2F%2Fs.tabelog.com%2Ftokyo%2FA1303%2FA130301%2F13238724%2F)で効果を確認する** 
リリースして3週間後にPageSpeed Insightsで比較しましたが、LCPの数値に改善は見られませんでした。
Origin Summaryは28日間の収集期間なので1週間弱足りていないのですが、残りの数日でも変化は見られませんでした。
あまり効果はなかった、、、？

**Before（2021/6/30 11時ごろ）** 

> ![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/084e322b-0dc1-bcd9-769c-d0a245474b32.png)


**After（2021/7/19 16時ごろ）** 
> ![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/dbc6244f-cef6-42a4-7eee-ea0bc70dddaa.png)




###  **2-2-1. 「使用していないCSSの削減」項目に効果あり** 
とはいえ、PageSpeed Insightsの「改善できる項目」で指摘内容に変化が見られました。
以下、LCPの変化をご覧ください。

**LCPの変化** 
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/4f267401-545d-3c11-0c88-00255745a786.png)
狙い通り、CSSの最適化を行ったので `使用していないCSSの削減` という指摘項目で0.6sほど改善できました。

###  **2-2-2. 「レンダリングを妨げるリソースの除外」項目に効果あり** 
ちなみに、レンダリングを妨げるリソースの除外では3つのCSSファイルが指摘されていました（下記画像の青の下線3つ）。

この対処方法として、「インラインCSS」と「遅延読み込みCSS」に区分けしてレンダリングのブロッキングを回避する手法を取りました。狙い通り、指摘項目からCSSファイルがなくなっていることを確認できました。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/d6efb18f-6633-8f42-8aed-b1f6133bb937.png)
※指摘されていたCSSファイルがない

紛らわしいのですが、application_inline.cssはインラインという名前がついていますが実際にはインライン読み込みされておりませんでした。そのためレンダリングの妨げとなっていたようです。


#  **3.やったこと** 
上記の2で対応についても軽く触れていますが、まとめると以下です。

- 使用していないルールセットの削除
- 重複しているルールセットの削除
- ファーストビューで使用しているルールセットの抽出
- ファーストビューのCSSはインライン読み込み
- ファーストビュー以外のCSSは非同期読み込み（遅延）

店舗詳細TOPに関しては分岐条件が多くデザイナーだけで全容を把握するのは困難だった為、エンジニアさんとフロントエンドエンジニアさんに協力を仰ぎ汎用モジュールの使用可否を調査しました。
リストアップした汎用モジュールを三者で睨めっこして、1.5hほどチャットツールで通話しながら調査しました。

最終的には、呼び出していた5つのCSSファイルを2つに集約。
ファーストビューで使用するCSSは `rstdtl_top_inline`にまとめ、それ以外を `rstdtl_top_async`と区分けしました。
この対応により、レンダリングのブロッキング回避に貢献しています。

> ![9.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/d3da66ca-1094-ea99-2c24-4f65a6c3d5f5.jpeg)



#  **4.PageSpeed Insightsを見れば、コアウェブバイタルの各種数値を改善できる項目が分かる** 

短縮できるおおよその時間がご丁寧にも[PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fs.tabelog.com%2Ftokyo%2FA1303%2FA130301%2F13238724)で "改善ポイント"と "短縮できる推定時間" のセットで提示してくれています。なので、LCPの数値が遅い！何をやればいいんだ？となったとき、真っ先にここを見れば疑問が解決できます。


例：[SP店舗詳細トップ](https://s.tabelog.com/tokyo/A1303/A130301/13238724)のURLでチェックした改善ポイント
> ![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/b5996d4a-b7c9-3171-2669-735bbabb7e5f.png)

このうちデザイナーができるCSS周りの対処方法は青の下線の2つです

- レンダリングを妨げるリソースの除外
  - 詳細：ページの First Paint をリソースがブロックしています。重要な JavaScript や CSS はインラインで配信し、それ以外の JavaScript やスタイルはすべて遅らせることをご検討ください。
- 使用していないCSSの削減
  - 詳細：スタイルシートから使用していないルールを削除して、スクロールせずに見える範囲のコンテンツで使用されていない CSS の読み込みを遅らせると、ネットワークの通信量を減らすことができます。

要約すると、「不要なCSSを削除して、ファーストビューのCSSはインラインで配信してください」と解釈できます。
この改善ポイントですが、実はFCPも同じような提案がされています。
> ![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/d6bab0a9-de42-dd9f-316e-a16cae6b3788.png)

つまり、この2つの改善ポイントの対策を行ったらLCPとFCPの両方を改善できるということになります。
これらのCSSの対策を行うとLCP/FCPの両方の対策ができるので、一石二鳥ですね。

#  **5. まとめ** 
指摘されていたCSSの改善ポイントに対して、概ね解消できることはやり切りました。
しかし目に見えるほどの大きなリターンが得られるわけでもありませんでした。
労力に見合わない作業であっても、結果的にユーザビリティに寄与できるのであれば、積極的に取り入れていきたいと思っています。

そのほかLCPの指摘項目に目をやると使用していないJavascriptの削減が目立っており、短縮できる推定時間は4.92sとなっております。
> ![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225425/4060e85f-4e9a-f896-25b9-c1f8f7ea3db0.png)


一番効果の見込めそうなところから着手するのがセオリーですが、フロントエンドエンジニアさんに伺ったところcommon.jsに関してはリプレイスのタイミングで対処予定とのことでした。
※新しい実装方法は [Atomic Design+styled-components](https://note.com/tabelog_frontend/n/n4b8bcb44294c)を採用

あとは広告のJSも積み重なって影響しているのでそちらも監視しておくと良さそうです。

以上、「食べログ スマートフォンページのCSSを最適化してLCP改善にトライ！」でした

明日はエンジニア @sudomeg さんの「作る人にも使う人にも嬉しいMVPをやってみた 〜実用最小限の見つけ方〜」です。お楽しみに！