Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reduce firebase bundle size?

I'm building my app to deploy to production. And my client bundled code is split by libraries.

And I've noticed that firebase has produced a quite large chunk.

It's 667kb as you can see below:

enter image description here

This is how I'm importing it on my code:

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
import 'firebase/functions';
import 'firebase/storage';

// .env file in root folder
const config = {
  apiKey: process.env.FIREBASE_APP_API_KEY,
  authDomain: process.env.FIREBASE_APP_AUTH_DOMAIN,
  databaseURL: process.env.FIREBASE_APP_DATABASE_URL,
  projectId: process.env.FIREBASE_APP_PROJECT_ID,
  storageBucket: process.env.FIREBASE_APP_STORAGE_BUCKET,
  messagingSenderId: process.env.FIREBASE_APP_MESSAGING_SENDER_ID
};

firebase.initializeApp(config);

Is there a way to reduce it?

Webpack is always warning about this chunk size.

like image 904
cbdeveloper Avatar asked Jan 14 '20 15:01

cbdeveloper


4 Answers

Bit late to the party, but one potential way to solve bundle size is dynamically importing firestore.

Turns out firebase.firestore is undefined if you haven't imported it into the module. This means you can ensure it is only imported once and export an async function that will return the firestore instance.

// firebase.js
export async function getFirestoreInstance() {
  if (!firebase.firestore) {
    await import('firebase/firestore');
  }

  return firebase.firestore();
}

// Other file that needs firestore
async function doSomething(){
  const firestore = await getFirestoreInstance();
  firestore.collection('do stuff')
}

I'm yet to test this in production, but it seems to work fine in development with React & NextJS. I will update once I do.

Update: Ran this in production for over a year now and faced zero problems. Firebase has since released V9 with support for both legacy (compatibility) and tree shakeable mode.

like image 162
Chief koshi Avatar answered Oct 04 '22 08:10

Chief koshi


There is an active issue on the firebase-js-sdk repository: https://github.com/firebase/firebase-js-sdk/issues/2241. At the moment there isn't so much that can be done.

If you don't need some features like realtime, you can use a lite version developed here but the API is still unstable: https://github.com/samuelgozi/firebase-firestore-lite

Someone also tried to improve the loading time by separating the firebase code into a separate bundle, lazy-loading it and executing it in a WebWorker: https://davidea.st/articles/firebase-bundle-size

In my experience, I wasn't able to do anything. I need real-time features from firestore and only lazy-loading the bundle helped a little to avoid showing a blank page, but my page still needed firestore to shown content obviously.


UPDATE

The bundle file sizes issue is now being tracked in: https://github.com/firebase/firebase-js-sdk/issues/332

like image 28
Jiayi Hu Avatar answered Oct 04 '22 10:10

Jiayi Hu


As of 2021, May. The Firebase team has released version 9 of the Firebase JS SDK now available in beta! Version 9 is fully modular and tree shakable

Learn more how to upgrade from version 8 to 9 here

like image 23
Yassin Ajdi Avatar answered Oct 04 '22 09:10

Yassin Ajdi


I am using firebase (app, auth, database) in a vue application. What I observed that for entrypoints, I don't need the firebase modules, just user state is needed to show/hide some relevant parts. However, firebase comes into picture on actions (for example). I managed to reduce the entrypoint size by lazy loading the firebase service and making use of webpackChunkName as below.

src\store\user.js
export default {
  namespaced: true,
  state: {
        ...
  },
  actions: {
    LOGIN ({ commit, dispatch, rootState }, { payload }) {
      const { email, password } = payload
      import(/* webpackChunkName: "templates" */'@/services/firebase')
            .then(firebase => {
        firebase.login(email, password)
                .then(success => {
          if (success) {
            ...
          }
        })
      })
    },
  }
}

Before this approach

File                                                          Size                                   Gzipped

  dist\js\chunk-vendors.c70c4cf6.js                             624.69 KiB                             177.55 KiB
  dist\js\app.ccbb0255.js                                       12.17 KiB                              4.51 KiB
  dist\js\chunk-2d21aab9.6d5ea268.js                            1.74 KiB                               0.75 KiB
  dist\service-worker.js                                        1.04 KiB                               0.61 KiB
  dist\precache-manifest.dfe6c8710d17438b19417144e7fe3fdf.js    0.67 KiB                               0.33 KiB
  dist\js\chunk-2d0c08d4.242e678f.js                            0.49 KiB                               0.33 KiB

After lazyloading,

File                                                          Size                                   Gzipped

  dist\js\templates.513b1084.js                                 491.87 KiB                             128.23 KiB
  dist\js\chunk-vendors.5b33c361.js                             135.65 KiB                             48.76 KiB
  dist\js\app.357109e3.js                                       8.62 KiB                               3.64 KiB
  dist\js\chunk-2d21aab9.afa42bc6.js                            1.75 KiB                               0.75 KiB
  dist\service-worker.js                                        1.04 KiB                               0.60 KiB
  dist\precache-manifest.abfe3a14b7eef653a3ed134b55abc947.js    0.76 KiB                               0.35 KiB
  dist\js\chunk-2d0c08d4.242e678f.js                            0.49 KiB                               0.33 KiB

May be someone can point out to improve it further.

like image 40
Furqan Yousuf Avatar answered Oct 04 '22 08:10

Furqan Yousuf