firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.86k stars 894 forks source link

Firestore import - Bundle size is huge #2241

Closed maheshkumar2150 closed 4 years ago

maheshkumar2150 commented 5 years ago

import firebase from '@firebase/app'; import '@firebase/firestore'; // this one is very very huge.

I am using only firestore in my app. How to reduce the bundle size of firestore?

google-oss-bot commented 5 years ago

I found a few problems with this issue:

AutanaSoft commented 5 years ago

This way you will only import what corresponds to Firestore

import * as firebase from 'firebase/app';
import 'firebase/firestore';
maheshkumar2150 commented 5 years ago

Nope. The size is +36B increased after adding the above code.

laurentpayot commented 5 years ago

@AutanaSoft see #332

schmidt-sebastian commented 5 years ago

@maheshkumar2150 Thanks for reporting! We are aware that there is a lot of room for improvement and are planning to prioritize reducing the SDK size in the very near future.

maheshkumar2150 commented 5 years ago

In the mean time, is there any solution?

import firebase from '@firebase/app';
import '@firebase/firestore'; -- increases the bundle size. 

Because of firestore import, the bundle size is huge and loading time is increased and started to lose visitors on my site.

I think firestore is not an optimal solution to websites and webapps right now. Firestore is very easy to use and very quick for developers. But the size is one of the very very big drawback.

If there is any solution, please tell me to reduce the size.

maheshkumar2150 commented 5 years ago

Hi

Can you please suggest me how to make backup firestore data and implement it in mongodb? It seems size is matter for web app.

Google analytics shows the app takes around 1 min to load for the first time which is really bad. I am from India. The network is not super fast here.

schmidt-sebastian commented 5 years ago

@maheshkumar2150 We currently don't have a MongoDb specific export functionality. Please take a look here to see if this works for you: https://firebase.google.com/docs/firestore/manage-data/export-import If you are interested in better support for this, please file a dedicated feature request.

maheshkumar2150 commented 5 years ago

Hi

What is dedicated feature request? import { ...,...,....} '@firebase/firestore';

Is something like that possible? Or do i have to import the whole firestore package?

maheshkumar2150 commented 5 years ago

Hi

I am thinking to convert the reactjs application to next.js Just to use firestore, i am about to convert the web app.

Is it possible to use firestore in node server? Will it reduce the bundle size? Please share some tutorials regarding this. I am not able to find it.

schmidt-sebastian commented 5 years ago

Our Node module for Servers is https://www.npmjs.com/package/@google-cloud/firestore

GuilhermeBCC commented 5 years ago

"1 min to load for the first time" 😨 You've already checked for an issue with your app, I don't think this is a normal time. As your case should be from low networks, I think you better use the REST API link

maheshkumar2150 commented 5 years ago

I am using firebase hosting and firebase firestore.

What are my chances? I am recreating the app with nodejs server.

Is it easy to move the firebase hosting to zeit hosting? So, i can keep the firebase firestore as backend and nodejs based frontend in zeit hosting. I believe it will reduce the loading time,

Right now, the app is designed with reactjs. I am changing it to next.js

Is this the right solution? Is there any better option available?

schmidt-sebastian commented 5 years ago

@maheshkumar2150 I am not sure I fully follow, but our Server SDKs can run on any Node 8 environment.

maheshkumar2150 commented 5 years ago

@maheshkumar2150 I am not sure I fully follow, but our Server SDKs can run on any Node 8 environment.

Hi,

Thanks. I am actually coded the app using create-react-app. Now, I am converting the app to server side rendering. So i can reduce the firebase SDK size.

I have just checked Firebase Rest API. Is there a chance that i can use it without any authentication token?

mikelehen commented 5 years ago

I believe that would only work if you don't have any security rules, which would not be recommended for a production app.

pjbrown11 commented 5 years ago

@maheshkumar2150 Thanks for reporting! We are aware that there is a lot of room for improvement and are planning to prioritize reducing the SDK size in the very near future.

Bundle size is the only drawback I've encountered (and it is a major one to me) with Firebase and it's great to hear that this is coming up in priority!

laurentpayot commented 5 years ago

@pjbrown11 I could make the size less annoying by using firebase (auth+firestore) in a worker thread: see #983

pjbrown11 commented 5 years ago

@pjbrown11 I could make the size less annoying by using firebase (auth+firestore) in a worker thread: see #983

Interesting approach. Thanks for sharing!

maheshkumar2150 commented 5 years ago

Good. Actually i am using code splitting and firebase is not loaded on my homepage. The team still has to work and reduce the bundle size as low as they can.

Everyone is using react, angular or other frameworks which itself little big for web apps. Adding firebase completely spoils the size.

We need reduced firebase sdk. That is the permanent solution. I started to use node and mongo just because of the webapp size.

Please give high priority and reduce the bundle size.

lukehtravis commented 5 years ago

+1 ! Firebase sdk currently taking up 453 kb of space on my app. that's almost as big as just about everything else combined in a create-react-app app

wiesson commented 5 years ago
Page                Size
┌ * /               3.09 kB
├   /_app           651 kB
├   /_document
├   /_error         1.96 kB
â”” * /products/[id]  3.82 kB

σ  (Server)       page will be server rendered (i.e. getInitialProps)
*  (Static File)  page was prerendered as static HTML

Same for me - the pages are quite small, but with firestore included, my app folder gets quite big..

mafergus commented 4 years ago

I love Firebase but it's crazy right now guys, firestore + auth is ~500kb of bundle.

Plantain commented 4 years ago

@schmidt-sebastian is there a roadmap for reducing the bundle size? I saw there is some progress in #2495, but I'd love some guidance on whether there's more coming - currently the bundle size makes it a non-starter for us, but if there's more substantial improvements coming I'd love to get started building on Firebase.

schmidt-sebastian commented 4 years ago

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.

laurentpayot commented 4 years ago

Unfortunately not many changes since a year ago. I guess we have to be patient :wink:

schmidt-sebastian commented 4 years ago

Hello :) We just published an experimental version of the SDK that minifies the code and reduces the code size by about 9% gzipped. We would love if we could get some mileage on it before we transition our default build to be minified. Instructions for how to use this build are in our release notes: https://firebase.google.com/support/release-notes/js#cloud-firestore

remorses commented 4 years ago

Minifying the library is not the solution, it is already done in the consumer webpack build.

As you already know from 2 years the problem is that firebase is not tree shakable, you should transition away from the class based api so that webpack can remove unused code

Instead you are doing the opposite making the code impossible to static analyze by webpack by minifying it

Please give us some ETA so that you limit the number of people abandoning firebase

As @Feiyang1 already pointed out 1 year ago:

Hi Guys, I want to provide some updates on what we are thinking about the size optimization. We had a lot of discussion about it recently. While it’s not completely settled, I can share some ideas we have discussed.

At the root of the issue, firebase components expose the entire API surface in the component instance. For example, all Firebase Auth APIs hang off the firebase.auth() object. Bundlers can’t tree shake them because they can’t be statically analyzed. To solve the problem, we need to export functions/classes as the top level module exports to expose the APIs, so you can explicitly import what you need. For example:

// today
import * as firebase from 'firebase/app';
import 'firebase/auth'; // import the entire component

const app = firebase.initializeApp({});
const provider = firebase.auth.GoogleAuthProvider();
app.auth().signInWithPopup(provider).then(user => {...});
// future
// This is just an example to illustrate the idea and the final syntax 
// is not going to look exactly like it
import { initializeApp } from 'firebase/app';
import { 
  getFirebaseAuth, 
  GoogleAuthProvider, 
  signInWithPopup 
} from 'firebase/auth'; // import functions individually.

const app = initializeApp({});
const auth = getFirebaseAuth(app);
const provider = new GoogleAuthProvider();

signInWithPopup(auth, provider).then(user => {...});

Just to clarify, this is just an example to illustrate the idea. The functions and their names are likely to be different in the final product.

Besides the API changes, we also have a lot of work to do to refactor the implementation in order to decouple components and separate interconnected logics, otherwise you might run into a situation where you import just a few symbols but end up pulling in 80% of the codebase.

It’s a big change for Firebase. The API is going to look completely different and we may need to rewrite a large part of the codebase, so it’s going to take some time before we can present it to you. We also realize it’s a very disruptive change to firebase developers, so we want to hear your voice about it as early as possible.

Finally we’d like to learn more about your use cases. What product/feature do you use? What do you wish you could exclude from your bundle? Do you have a use case where you want to load some firebase features at the startup and load more features later? Please leave the comment below. Your feedbacks are very important to us!

Thanks!

schmidt-sebastian commented 4 years ago

The minification I alluded to above goes beyond the "white space removal" that all of our libraries already go through. The additional size reduction comes from property name minification (mangling), which is something that only we as library authors can safely do. The savings with this version are clearly just a starting point, and making Firebase library tree-shakeable remains a priority. Please do note that some Firebase libraries (such as Auth) are much more suited for tree shaking, so the savings will differ vastly between products.

As for making it harder to static analyze - we now ship to NPM:

If that is not enough, you can directly refer to our source files in your Rollup/Webpack builds.

We are aware that we need to completely revamp out JS libraries across the board, but making this happen without breaking all of your apps is quite a significant undertaking.

deanc commented 4 years ago

@schmidt-sebastian When might the minified experimental build make it into the main release?

hdr-js commented 4 years ago

image

Tried every possible way but this is the minimum I got to use firebase in my app!

schmidt-sebastian commented 4 years ago

When might the minified experimental build make it into the main release?

@deanc Either this week or next.

hdr-js commented 4 years ago

When might the minified experimental build make it into the main release?

@deanc Either this week or next.

Counting on this!

Studio384 commented 4 years ago

Updating to 7.9.1 and reversing the changes required from 7.8.0 still results in the old default bundle.

schmidt-sebastian commented 4 years ago

@Studio384 Can you share some details about your build pipeline? 7.9.1 should now have the following Firestore artifacts:

Please let us know if you are using the Node or the CJS version of Firestore and require mangling. We can work on that next.

samuelgozi commented 4 years ago

I'll shamelessly plug my own solution to this. I wrote an alternative library for auth, storage, and Firestore in order to address the performance and size issues of the official SDK.

It's not yet production-ready, but it's getting there, and you should give it a try. Currently what might stop you from switching to my alternatives is that the Firestore library doesn't support listening for changes(live updates) and offline support.

firebase-auth-lite - (2KB vs 50.8KB) | Most of the official features are ready. firebase-firestore-lite - (2.9KB vs 92KB) | ~70% of the official functionality. firebase-storage-lite - (1.4KB vs 18.4KB)| 100% of the official functionality.

My Alternative SDK performs on average 13 times better and is 27 times smaller than the official ones.

If any of you end up trying it, please give me some feedback, I'm usually very responsive so if there is an issue it will be fixed quickly.

schmidt-sebastian commented 4 years ago

An update from our end: We have now published memory-only builds for Firestore that decrease the size for users that don't invoke enablePersistence(). Our next goal is to make this SDK as well as other tree-shakeable, but this requires a fair amount of refactoring on our end and will result in a major breaking API change.

maheshkumar2150 commented 4 years ago

I dont see much improvement in the build size. You may launch separate package namely 'firebase lite' or 'firebase web' for web alone.

Because i stopped using firebase for web apps and which makes me to stop using firebase on some mobile apps too.

But i have huge hope on you. Firebase was the easiest and fastest way to implement backend to my apps.

GriffinJohnston commented 4 years ago

I'm seeing a ~9kb improvement gzipped. That's not nothing. There's a long way to go still, but saving 10kb here and 10kb there can definitely add up if they keep at it. Thanks for the work so far @schmidt-sebastian! I just hope that this issue is going to continue to be a serious focus of the Firebase team.

samuelgozi commented 4 years ago

An update from our end: We have now published memory-only builds for Firestore that decrease the size for users that don't invoke enablePersistence(). Our next goal is to make this SDK as well as other tree-shakeable, but this requires a fair amount of refactoring on our end and will result in a major breaking API change.

Finally, the right decision. Make breaking changes. It's the right thing.

willhalling commented 4 years ago

Trying to get my vendors.app.js file below 244 KiB as per recommendation in Nuxt, but currently not possible to get close with Firebase. Thanks to the Firebase team for focussing on this, on your roadmap.

dotpxg commented 4 years ago

Having this same problem. Not able to figure out from last 48 hours. Help please as this is killing load time. Im using vue with vuetify and during build webpack recommend to lower bundle size..will appreciate for the help

david0178418 commented 4 years ago

The way I've dealt with it is to defer the loading of these to at least allow the frame to come up faster. Since this is hopefully something that will be fixed, I've isolated these to one file. For example:

// side-effect-modules.js
import 'firebase/firestore';
import 'firebase/auth';

export { firestore, auth } from 'firebase/app';

Then, later in your code, you can do:

const { auth } = await import('side-effect-modules')

auth().onAuthStateChanged(async newUser => {
    // Do stuff.
});

That doesn't solve the problem of getting the app up and running faster, but it at least lets the user see something other than a white screen while everything gets loaded.

kasperkamperman commented 4 years ago

Doing some research and thanks to the hint of @david0178418 I came across this gist, that provides a clear example on how to lazy load firebase: https://gist.github.com/dyaa/8f8d1f8964160630f2475fe26a2e6150

To clarify, in my setup I only use Firebase for Cloud Messaging.

samuelgozi commented 4 years ago

@kasperkamperman It's important to note that this method won't decrease the time to interactive, and all app functionality that depends on Firebase will need to wait for it to load.

So If your app heavily depends on Firebase this method will be slower than just bundling everything together because it adds requests.

Dynamic imports are great when the functionality is not immediately needed, but otherwise, it will make things worse.

wiesson commented 4 years ago

I think the topic is similar - I'd like to import

firebase.firestore.FieldPath.documentId without doing import firebase from 'firebase' - any idea how to achieve this?

schmidt-sebastian commented 4 years ago

I don't think that is possible at this point in time, but it will be possible once we release tree-shakeable versions for FirebaseApp and FirebaseFirestore.

mb8z commented 4 years ago

@schmidt-sebastian Just a quick question – is there any issue we can track or at least approximate date of releasing those versions? Thanks for your work!

schmidt-sebastian commented 4 years ago

There is nothing to track. My widely inaccurate estimate would be for an experimental release in late June/early July (which could mean anything from May till November).

gabrielsze commented 4 years ago

Here to upvote this thread, with a couple of comments.

I don't think that is possible at this point in time, but it will be possible once we release tree-shakeable versions for FirebaseApp and FirebaseFirestore.

Great work and thank you, this will be great. I am wondering whether this will be made available for Firebase Realtime Database, Auth etc etc?

PS:

I'll shamelessly plug my own solution to this. I wrote an alternative library for auth, storage, and Firestore in order to address the performance and size issues of the official SDK.

It's not yet production-ready, but it's getting there, and you should give it a try. Currently what might stop you from switching to my alternatives is that the Firestore library doesn't support listening for changes(live updates) and offline support.

firebase-auth-lite - (2KB vs 50.8KB) | Most of the official features are ready. firebase-firestore-lite - (2.9KB vs 92KB) | ~70% of the official functionality. firebase-storage-lite - (1.4KB vs 18.4KB)| 100% of the official functionality.

My Alternative SDK performs on average 13 times better and is 27 times smaller than the official ones.

If any of you end up trying it, please give me some feedback, I'm usually very responsive so if there is an issue it will be fixed quickly.

Why doesn't Firebase just hire this dude?