リクルートスピードハッカソンに参加したのでその感想や勉強したことまとめ

# リクルートFrontend スピードハッカソン
https://engineers.recruit-jinji.jp/event/20_speedhackathon/
# やったこと
参加者の中で3〜4人の間でチームを組みgitで共有された[ホットペッパービューティー](https://beauty.hotpepper.jp/)の１ページのパフォーマンス性能をできるだけ高めるというものでした。

ちなみに僕のチームの結果はこんな感じです
### スタート時
![スクリーンショット 2020-03-07 20.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/bab9f36c-9107-c4be-9a33-5b4ed9bc52ad.png)

### 終了時
![スクリーンショット 2020-03-07 20.35.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/e11db73b-b216-8eb6-319e-50ef7a10b7b3.png)

約5時間の調整でここまでの成果が、、、
チーム内にすでにがっつり実務でフロントエンドやっている方がいたのでその方のおかげもありパフォーマンス性能を60以上あげることができました。
ただ、今回参加した全８チーム中僕たちのチームは5位でした。。。
全体的にとてもレベルが高く、周りのレベルの高さに驚きですね😅


# パフォーマンス効率改善方法
今回のイベントでのパフォーマンスの改善方法をざっくりと説明していきます。

※基本的にはパフォーマンスチューニング童貞でも大枠くらいはわかるようにするために、できるだけ簡単な言葉でざっくりと説明しています。もし、ちゃんと正確な事知りたい！という人は他の記事を読むことをお勧めします笑

## まずは測定！、そして改善へ！
1. chromeで対象の計測するサイトを開く
2. 検証ツールを開く(macだと「⌘ + ⌥ + i」で開きます)
3. 検証ツールの上のタブから***Audits*** を選択  
<img width="389" alt="スクリーンショット 2020-03-07 23.03.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/7ed9de6d-03f8-ce02-3e6e-b4b81b58c5ad.png">
4. 「Generate report」を押す  
<img width="516" alt="スクリーンショット 2020-03-07 23.09.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/8eb3eaf0-6c9e-13d4-ca3e-e02500b0bbc5.png">
5. するとこんな感じのレポートを出してくれます！（もちろんlocalhostでも検証できます！）
<img width="716" alt="スクリーンショット 2020-03-07 23.12.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/d4b6109b-d8bd-b56d-747f-0535331eef55.png">
6. スクロールすると`Opportunities` という項目があるのでその項目を愚直に潰していく
![スクリーンショット 2020-03-07 21.00.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/b903d69c-9024-90bc-d36b-be1467c8b029.png)

基本的には`Opportunities`に書かれていることを潰していくだけです。
僕たちのチームはほぼこれを潰しただけでしたが、60以上もスコアが改善されました。

# 今回対処したOpportunitiesとその方法

## Enable text compression（テキスト圧縮して送ってよw）
<img width="642" alt="スクリーンショット 2020-03-07 23.55.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/9bd1b41e-eb29-c986-ac8d-84e484d230e2.png">
なんか色々書いていますが、結局何が言いたいかと言えば ***テキストは圧縮して送れよ！*** これだけです笑
なので今回はnode.jsの圧縮ライブラリである[compression](https://github.com/expressjs/compression)を用いてテキストを`gzip` 形式で圧縮して送信しました


※ちなみに最適解は[brotli](https://github.com/foliojs/brotli.js)という形式での圧縮をすることだったそうです。

## Properly size images(画像サイズ大きすぎね？)
<img width="651" alt="スクリーンショット 2020-03-07 23.34.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/c0ecbe12-7fac-e7f3-43f3-fd311c8bb49b.png">
めちゃ簡単にいうと、画像サイズ不適切だから適切なファイルサイズに圧縮しろよな！っていう警告です
色々とやり方はあると思うのですが、今回は

[Squoosh](https://squoosh.app/)

という画像圧縮webアプリを使いました。（使い方は下記サイトを見てください）
https://blog.marswee.com/entry/squoosh-how-to



ついでに今回は画像関連で
### Serve images in next-gen formats（古いJPEGとかPNGとか使うなよ〜）

っていうエラーも出ていたので`webp`という形式で画像を変換、圧縮しました。
webpの難しいことについてはそれぞれ調べていただくとしてざっくり特徴を書くと、、、

- 結構軽いよ〜！
- でも対応してないブラウザあるから気をつけてね！

こんな感じです。
おそらく今回のハッカソンではchromeでしか検証を行っていないのでwebp形式に変換してhtml側の拡張子も.webpにすればよかったと思うのですが、本来ならば `<picture>` タグというタグを使ってユーザーの閲覧環境に合わせて画像を出し分ける処理を書く必要があります。（全部対応しようとすると結構大変です笑）


## Eliminate render-blocking resources(読み込むファイルが多いんじゃ！)
<img width="633" alt="スクリーンショット 2020-03-08 0.27.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/785f88fa-8413-3b14-ab69-7fab99918044.png">
こいつは***ページ表示するまでに読み込むもの多すぎてページ表示させるの遅れてるよ！***ってやつです。
そもそもwebサイトの表示はざっくり

```
1. ブラウザーがHTMLファイルをダウンロードする
2. HTMLファイルの読み込みと、CSSファイル、JavaScriptファイル、画像ファイルの確認
3. 画像ファイルをダウンロード
4. ページを表示するためにCSSファイルとJavaScriptファイルが必要になる
5. CSSファイルをダウンロードして読み込む　←ファイル読み込んでるせいでページ表示できない
6. JavaScriptファイルをダウンロードして読み込む　←ファイル読み込んでるせいでページ表示できない
7. Webページを表示する
```
という順番で表示されています（下記のURL参考）
https://goworkship.com/magazine/rendering-block/

これの一番簡単な方法としては
***Minify***してhtmlに***インラインで書き込む***という方法です

※ Minifyってのはcssとかの不要なスペースや改行を全部無くしてファイルサイズを小さくする方法です！（jsファイルが無駄に長い１行のファイルになってることあるでしょ？あれですw）
↓みたいなサイトを使って簡単にMinifyをすることができます
https://csscompressor.net/ja/

※ インラインで書き込む、、、
つまり本来↓のような形でcssファイルを読み込むのですが、、、

```css
<link rel="stylesheet" type="text/css" href="example.css">
```

↓みたいにMinifyしたcssを直接html内に書き込むということです。

```
<style>
  body,dd,div,dl,dt,h1,img,li,ol,p,table,td,ul{margin:0;paddi......
</style>
```

## Defer offscreen images(画像はあとで読み込んだら？)
<img width="636" alt="スクリーンショット 2020-03-08 1.36.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/7a781d63-81d8-c40a-2eca-7cdd3272dc87.png">

これも上記と同様に読み込む系のやつなのですが、画像ファイルはどうしても外部から読み込む必要があるのでスクロールしていって必要になったら画像を読み込むようにします（下記のURL参照）
https://webtan-tsushin.com/seo-lazy-image-load

## Remove unused CSS（使ってないcssあるんだけどw）
これはその名の通り使ってないcssがあるから消してねっていうやつです
今回は↓あたりを参考に使ってないcssを削除しました
https://www.monotalk.xyz/blog/Use-UnCSS-with-gulp/


## Preconnect to required origins(どうせ使うなら先に接続したら？)
<img width="633" alt="スクリーンショット 2020-03-08 1.48.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/1efa86d6-7556-8d79-2808-5626edbad989.png">
そもそも外部のサーバーとの接続は

- DNS look up
- リダイレクト

などなど、たくさんの処理があり、それらの処理を低速ネットワーク下でやるとかなり時間がかかってしまいます。（とりあえず、結構いろんな処理走っててネット環境悪いと遅くなっちゃうってことです。）なので、これらの処理を事前にやっておくことで処理を早くすることができます。
対応方法は簡単でheadタグ内に

```html
<link rel="preconnect" href="https://example.com">
```
とを入れるだけです


※ ちなみに写真にある`t.tgknt.com`はソース内に存在しなかったので何なのかとちょっと調べてみたら、広告配信するときに使うバナーを生成するドメインみたいです。（間違ってたら誰か教えてください汗）


以上が
`Opportunities`のざっくりとした対応です

# まとめ
正直僕が今まで参加して来たインターンの中では一二を争うレベルでめちゃめちゃ為になるイベントだと思います！
イベントの結果発表後には改善のポイントや解説はもちろんのこと、リクルート社員さんのLT会もありそれぞれのLT全てがとても為になるものでした。
このイベントは去年からやっているイベントらしく、おそらく来年も開催されるのではないかと思うのでぜひ参加してみるのをオススメします！