Lighthouseのスコアを爆上げした昔話（Lighthouse ver5時代）

# はじめに
2020年1月頃にとあるサイトのパフォーマンスチューニングを施したときの記録です。
本番リリースしてから、と寝かせてたらLighthouseが6に上がったことにより陳腐化しましたが、
何かの役に立つこともあるかもしれないので公開します。
特定を避けるために一部情報が抜けていることをお許しください。

# 環境
php(Symfony) + javascript(jQuery)のクラシックなMPA（MultiplePageApplication）。
外部ドメインのコンテンツ(広告、アクセス解析など)を含みます。

# 実施した内容
Lighthouseのレポートの主にOpportunityから簡単に着手できるものを実施しました。
修正余地や成果を分かりやすくしたかったため、外部ドメインのコンテンツは遮断し、
また修正を簡単にするためにローカル環境で行っています。
**Oppotunity**
![opportunity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244191/395150ba-87d1-ae9b-d71c-091df85a5043.png)
**Diagnostics**
![diagnostics.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244191/d3db0a1f-00fb-b172-1359-5a715e9a53d7.png)

# 成果
MobileのPerfomanceが10から93へと改善（Lighthouse ver5での結果です）
PCも同程度まで向上しました。
元々が低かったせいもありますが、閑散期に短期で終わらせたにしては悪くない結果でした。

**Before**
![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244191/7bbbcfc3-7c55-e2e6-73eb-01c7b17a7fea.png)
**After**
![after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244191/25fd7aac-1067-30c4-7cdd-c20dd6834bc8.png)
**その時の心象風景**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244191/5e93c0a6-93a6-4f1b-1d29-fb2d539fb217.png)

# 大きな効果があった修正
**Eliminate render-blocking resources: 10→19 point**
javascriptの読み込みでasync/deferの指定をしておらず、
jsファイルの読み込み完了までレンダリングが止まっていました。
読み込み箇所が多かったため、大変乱暴ですが全部のJavascriptに一括でdeferを入れ、
その後問題が見つかった箇所を個別で対応していきました。

```html
<script src=”foo.js” defer />
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244191/510acbe4-23c3-6fa8-76e6-f6c3592d28fd.png)
画像はGrowing with the webより


**Ensure text remains visible during webfont load: 19→46 point**
font-displayが未定義で、fontの読み込み完了までテキストが表示されていなかったため、
css内の全ての@font-faceにfont-display: swapを追加しました。

```css
@font-face {
  …
  font-display: swap;
}
```

![font-display.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244191/48946e88-b95d-4f30-c473-029e058b08b6.png)


**Enable text compression: 46→84 point**
gzip圧縮転送されていないテキストコンテンツがあったので圧縮するように.htaccessを編集しました。

```
<IfModule mod_deflate.c>
    <IfModule mod_filter.c>
        FilterDeclare COMPRESS
        FilterProvider COMPRESS DEFLATE "%{CONTENT_TYPE} =~ m#^text/#i"
        FilterProvider COMPRESS DEFLATE "%{CONTENT_TYPE} =~ 
m#^application/(atom\+xml|javascript|json|rss\+xml|xml|xhtml\+xml)#i"
        FilterProvider COMPRESS DEFLATE "%{CONTENT_TYPE} =~ m#^image/(svg\+xml|x\-icon)#i"
        FilterChain COMPRESS
        FilterProtocol COMPRESS DEFLATE change=yes;byteranges=no
    </IfModule>
</IfModule>
```

**Does not use HTTP/2 for all of its resources: 84→93 point**
HTTP/2が有効になっていたため、サーバ側にnghttp2をインストールし、.htaccessに以下を編集しました。

```
Protocols h2 http/1.1
```

# 大きな効果が確認できなかった修正
**Minify CSS / Minify Javascript**
一部のファイルで設定漏れがあったため修正しましたが、目立った効果はありませんでした。

**Serve images in next-gen formats**
jpgフォーマットの大きな画像があったため、webp変換した画像を用意し、
.htaccessでwebpを有効化し、
ブラウザがサポートしており、かつjpg画像の呼び出し時にwebp画像が存在する場合はそちらを返すようにしました。


**Properly size images**
一般的なディスプレイサイズより大きな画像を使用していたため、
一回り小さい画像を用意してmediaqueryで使い分けするようにしました。

```
<picture>
    <source media="(min-width: 1281px)" srcset="top_large.jpg">
    <source srcset="top.jpg" />
    <img src="top.jpg" />
</picture>
```

**Serve static assets with an efficient cache policy**
静的コンテンツでキャッシュ設定が無いものがあったため、
.htaccessで設定を行いました。

```
<IfModule mod_expires.c>
    ExpiresActive on
    ExpiresDefault                          "access plus 1 month"
    ExpiresByType application/json          "access plus 0 seconds"
    ExpiresByType image/gif                 "access plus 1 year"
    …
</IfModule>
```

# Lighthouse ver6での変化
観点ごとの重み付けが変化し、またOpportunityの項目がスコアには直接は反映されないことが明示されました。
`Opportunities - These suggestions can help your page load faster. They don't directly affect the Performance score.`
その結果、現時点での上記の施策はそこまでの効果は出なくなっています。
代わりに[スコア計算機](https://googlechrome.github.io/lighthouse/scorecalc/)が公開されたりと、スコアへの影響はわかりやすくなっているので、
今後はより効果的にスコアを伸ばすアプローチが取りやすくなったと思います。

# まとめ
記事は寝かせると腐ることが多いので早めに書きあげましょう。

# 参考
https://web.dev/lighthouse-whats-new-6.0/
https://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html
https://qiita.com/phanect/items/82c85ea4b8f9c373d684
https://qiita.com/oreo/items/2e82bfeb42e351557c3c
https://qiita.com/nuko-suke/items/fb5b335551065875de4e