React Tokyo with ZEITカンファレンスメモ

# 概要
* [React Tokyo with ZEIT](https://www.meetup.com/ja-JP/ReactJS-Tokyo/events/260331790/) に参加してきました。
* カンファレンスの内容を自分なりに理解した範囲で残しておきます。
* 自分の理解不足により正確に表現できていないところも多々あると思いますので、参加していらっしゃった方がもしご覧になっていたらどうかご指摘お願いします。

# 発表内容
## 1. SPR(Serverless Pre Rendering)について
### Guillermo Rauch氏 (from ZEIT)
#### staticが良い！
* 計算（computing）させるとどうしても遅い
* 静的（static）なものは速い

#### キーワードとなるのは「キャッシュ（cache）」
* キャッシュすることでビルドはめっちゃ速くなる
* staticはstaticでしかない。動的（dynamic）なデータでレンダリングしたい
* 単純なtypoを修正するだけでもデプロイには時間がかかる

#### そこで、Serverless Pre-rendering（SPR）
* fetchのときにプリレンダリングする
* notion
  * 裏でプリレンダリングすることでデータ取得が速くなる

#### SPRの仕組み
* `next build` のコマンドを打つだけ
  * jsはjsとして認識する
  * CDN cache
* staticなレンダリングは100msほど！
* バックエンドの仕組みを気にせず開発できる
  * standard HTTPを採用している
* getiInitialPropsでキャッシュコントロールのヘッダーをセットする
  * ZEITのネットワークのレイテンシがとても速い

#### SPRは様々な用途に使える！
* CMS
* EC
* Documentのサイト　などなど
* これからも「計算しない（computingless）」世界を目指して頑張っていくよ！

## 2. AMPについて
### Tim Neutkens氏 (from ZEIT)
#### AMPをサポートしているNextjs 8.1の特長
  * プリレンダリングが安定している（stable prerendering）
  * ロードしやすい（easy loading）

#### Nextjs 8.1の使い方
  * `withAMP` をインポートする
  * `withAMP` でコンポーネントをラップする
    * こうするとAMPでコンポーネントが読み込まれる
    * imgタグもAMP-imgタグとして読み込まれる
  * ビルドした時に　`powered by AMP` と表示されたら、AMPで起動できている
  * if "hybrid = true", reactFok
  * `useAMP` をインポートすると、AMPかどうかで表示を出し分けることもできる
    * 例： const isAMP = useSAMP();
    * `isAMP` が `true` かどうかで画像を表示し分ける
* [ドキュメント](https://nextjs.org/blog/next-8-1) にAMPのことが詳しく載っているよ！

## 3. SPRのアーキテクチャについて
### Connor Davis氏 (from ZEIT)
#### ビルドのアーキテクチャについて紹介
* キーワードは「高速なビルド（fast build）」
* これまでNextjsはどのように動いてきたか？
  * ページは毎回リレンダリングされる
  * 単純なタイプミスを修正するのにもビルドに4分ほどかかる
* そこで、次のような工夫をすることによって大幅にビルドにかかる時間を改善！
  * キャッシュ最大化（maximize chaching）
      * webpack
      * chunk
      * module(react, npm) などを最大限キャッシュすることにした
      * それでもなお、ビルドには14秒ほどかかる…
  * 何回もビルドすることを防止（avoiding rework）
      * 変更があったページのみを再ビルドすることにした
      * この仕組みを「**Fyling Shuttle**」と言うよ！

## 4. 質疑応答

#### 発表者はみんなMacを使用していたが、Windowsでも同じように機能するの？
* OSは関係ない！
* Flying ShuttleはCIに特化した（ci featured）サービス
* CIのbuildを可能な限り速くするものである

#### webpack4のnumericIDを再利用することはできるの？
* できる。ビルドの間に残り続ける

#### AMPを使用しているかどうかは具体的に何が判定しているの？
* ReactHookを使えば、AMPでレンダリングしているかどうか分かる
* AMPでレンダリングしたらGoogleがそのサイトを特定することができる
* AMP scriptというのもある
  * AMP scriptは大量のバイトを別々のworkerで読み込む
  * 使い方としては、すべてAMPにしてしまってAMPかそうでないか分別させる

## 5. Reactのパフォーマンスチューニングについて
### Kento Tsuji氏 (from Recruit)

#### AirShift開発で行なったパフォーマンスのチューニング
* AirShift開発はシフト調整のサービス
  * virturized化
  * 再レンダリングの最適化

#### チューニング後の再調査
* 画面描画までの時間は13秒から3秒に短縮したが、そもそも3秒は速くない。ということで再度ボトルネック調査
* 下記、新たに見つかった原因と対策
  * 時間の計算にmomentを使用していることでインスタンスを大量生成
    * ----> memoize
  * 再レンダリングが発生
        * reselectで毎回違うオブジェクトを返していた
    * ----> reselectの性質や使用すべき箇所をチーム内で再確認
* 上記を解決してもなお、25%のユーザーが画面表示に3秒以上かかる
  * 原因は、ユーザーがCPUが低いPCを使用している
  * **CPUを使わないアプローチ**が必要！

#### CPUを使わない解決策
* prefetchする
  * APIへのアクセスログから分析し、必要なリソースをprefetch
  * APIリクエストと同時に分析サーバーにもリクエストを送る
  * レスポンスのヘッダーに次に取得すべきリソースの名前の一覧をヘッダに注入
  * そのヘッダを解釈し、ユーザーがアクションする前にprefetchするLRUキャッシュに保存
  * ユーザーが実際にアクションした際、LRUキャッシュにデータがあればそこからリソースを取得
* webworker × suspence
  * webworkerは古いAPI、互換性も良い
  * comlinkで重い計算を外にだすことができる。相性が良い
    * reactで重い計算をするときは使える
* lazy rendering
  * ユーザーが見たいものはページの中でも優先順位がある
  * そこで、描画の優先順位をつける。 たくさんの計算をするものを遅らせる
  * 全体で見れば遅くなる可能性はあるが、ユーザーの求めるものは「必要な情報の速さ」
* まだまだ改善中。アイディアあればぜひ教えてください

# 所感
* フロントエンドの進化の速さを実感、これからSSRはもっと便利になる。
* 結局時代はStaticなレンダリングに戻るのではないかと思っていたけれど、そうではなさそう。SPRは最先端な感じがする。
* 技術や自分達が作り上げてきたものを活き活きしながら語る人、めちゃくちゃかっこいい。そのコミュニティが広いことも実感した。

# 参考URL
* [AMPについて（NextJS公式ドキュメント）](https://nextjs.org/blog/next-8-1)
* [React Performance Tuning](https://speakerdeck.com/maxmellon/react-performance-tuning)