[Firestore]bundleサイズを削減する方法


#Overview

Webアプリにおいて初回の画面描画にかかる時間を短く保つことは非常に重要です。
検索から遷移して数秒経っても何も表示されなくてはユーザーは逃げてしまいます。
Firestoreは優秀な製品ですが、バンドルサイズが約100KB(執筆時点)あり、初回の画面描画にはかかわらせたくなかったのが本音です。
そんなFirestoreがバンドルサイズ縮小に向けて動き出したようなので、展開しておきます。

**<2020/02/22 追記>**
Version7.9.0のリリースにて、後述している```index.cjs.min```へのimport切り替えは不要になったとのこと。
実際にビルドして90KB弱になったことを確認。

**<2020/03/29 追記>**
Version7.13.0のリリースにて、オフライン対応を外したバージョンがリリースされました。
実際にビルドして73.06 KBになったことを確認。

**<2020/04/12 追記>**
Version7.14.0のリリースにて、オフライン対応を外したバージョンが65.44 KB (-7.62 KB) になったことを確認。

**<2020/05/02 追記>**
Version7.14.2のリリースにて、オフライン対応を外したバージョンが62.95 KB (-2.49 KB) になったことを確認。

**<2020/06/26 追記>**
Version7.15.5のリリースにて、オフライン対応を外したバージョンが61.32 KB (-1.28 KB) になったことを確認。
`Updated grpc-js to version ^1.0.0.`が効いたのかな？

#Target reader

- FirestoreをWebで使用しているフロントエンドの方。


#Body

##Firebaseファミリーのバンドルサイズたち

執筆時点から1年程度前にバンドルサイズを計測した結果が以下。（結果は全てGzipのサイズ）

```javascript

// import firebase from 'firebase';         // 199.99KB
import firebase from 'firebase/app';
// import 'firebase/auth';                 // 48.9KB
// import 'firebase/firebase-firestore';   // 86.8KB
// import 'firebase/firebase-functions';   // 2.38KB
// import 'firebase/messaging';            // 7.75KB
// import 'firebase/firebase-storage';     // 9.68KB

```

Firebaseパッケージを丸ごとインポートすると約200KBもあり、Firebaseを使用しない比較的小さなWebアプリのサイズに匹敵する。
個別インポートでもfirebase-firestoreが約90KB、認証が約50KBととにかくサイズが大きい。
Firestoreからデータを検索するだけで約90KB、Googleアカウントでログインさせる機能を付けるだけで約50KBも増加します。
アプリに必須の機能でなければ使用しない選択をする人もいるでしょう。
実際のところ私も可能な限り避け、やむなく導入する際には動的インポートすることで影響を最小限にとどめていました。

ちなみにですが、執筆時点の最新バージョンではFirestoreはほぼ100KBに成長しています。
https://bundlephobia.com/result?p=@firebase/firestore

##ついに来たminified import!

~~リリースノートから変更されたimport方法を引用します。~~

~~https://firebase.google.com/support/release-notes/js#cloud-firestore_1~~

>
~~```javascript
import firebase from 'firebase/app';
import '@firebase/firestore/dist/index.cjs.min';
```~~

~~この変更を使用してみるとバンドルサイズは以下のように変化します。
96.84KB => 83.91KB
10%程度のサイズ縮小に成功しています！
ただし、この変更はまだExperimentalなので、Firestoreを全体的に利用しているPJに適用するのは危険です。
バグがいつくか出てくる可能性があるため、最悪機能しなくても問題ないというレベルでない限りStableになるのを待ちましょう。~~

##オフライン対応が不要な場合のバージョンが登場!<2020/03/29 追記>

オフライン対応が不要な場合、bundleサイズを14%程度小さくできるバージョンが登場しました。
オフラインでのFirestoreへの操作が不要なら積極的に採用していいでしょう。
オフライン対応に関する公式ドキュメントはこちら。
https://firebase.google.com/docs/firestore/manage-data/enable-offline?hl=ja

オフライン対応が不要なメモリバージョンの採用方法はこちら。
https://firebase.google.com/support/release-notes/js#version_7130_-_march_26_2020

採用してみたところ、88.52 KB＝＞73.06 KBと確かに小さくなったことを確認しました。

##今後のさらなる削減について

なんだ10%かよと思うかもしれませんが、bundleサイズ削減に対して動き出したことが重要です。
まずはこの取り組みに至ったissueがこれです。
bundleサイズ削減する方法を知りたいとゴリゴリ質問していて、最初悪いいねが多かったけど結局これが推進力になった模様:joy:
強引なのも時には必要ですね、相手によりますが…

https://github.com/firebase/firebase-js-sdk/issues/2241

この中で今後について言及あったのがこれ。

https://github.com/firebase/firebase-js-sdk/issues/2241#issuecomment-572684031

>When the mangled version of Firestore is released, our bundle size will go down by about 9% gzipped. We are also looking at releasing an ES6 only version (for our prebuilts that we push to CDN, since this can be done already using our NPM builds), which shaves of another 10%. Furthermore, we are looking at making offline persistence optional might again will have a similar amount of savings (as a rough estimate).
>
We are also in the early stages of figuring out how we can best reduce the bundle size for Auth and might release a tree-shakeable version at some point that will allow you to only depend on the Auth providers that you need.

Google翻訳先生お願いします。

>Firestoreのマングルバージョンがリリースされると、バンドルサイズが約9％gzip圧縮されます。 また、ES6のみのバージョン（NPMビルドを使用して既に行うことができるため、CDNにプッシュするプリビルド用）のリリースも検討しています。 さらに、オフラインの永続性をオプションにすることも検討しています（大まかな見積もりとして）。
>
また、Authのバンドルサイズを最適に削減する方法を考え出す初期段階にあり、ある時点でツリーシェーカブルバージョンをリリースして、必要なAuthプロバイダーにのみ依存できるようにします。

bundleサイズ削減のため、今後も対応を進める発言があったことは頼もしい限り。（いつやるとは言ってない:sweat_smile:重要なのは希望）
認証プロバイダーの個別インポートや、Firestoreをクラスから関数ベースに移行＋オプション化を駆使してサイズ削減が進んでほしいものです。

issueの中の記事ですが、Web WorkerでFirestoreを処理することで、初期描画に影響を与えない方法が掲載されているようです。
状況によってはこういう手法も使えるかもしれません。
https://davidea.st/articles/firebase-bundle-size

#Conclusion

Firestoreのバンドルサイズ削減がついに動き出したという話でした。
正式リリースや認証の削減等の動きを見落とさないよう、リリースノートはチェックしておきましょう。
https://firebase.google.com/support/release-notes/js

Have a great day!