Firebase-js-sdk: Please optimize the size of libs

Created on 24 Nov 2017  Â·  100Comments  Â·  Source: firebase/firebase-js-sdk

Could you optimize the size of libs? We have limit ~ 50 KB per route on 3G mobile networks. :-/

Check out the video Measure Time to Interactive.

The Cost Of JavaScript is high.

core enhancement

Most helpful comment

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 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!

All 100 comments

Hey there! I couldn't figure out what this issue is about, so I've labeled it for a human to triage. Hang tight.

Hmmm this issue does not seem to follow the issue template. Make sure you provide all the required information.

Hey @JosefJezek!

Thanks for your interest in this! We are working on making the SDKs easier to consume for mobile networks but nothing currently to report here. I will keep this issue open and will update as the situation improves!

Anyway we can make it more modular in the form of:

import { sendVerificationEmail, reauthenticateWithCredential, ... } from 'firebase/auth';
...

etc.

setup:

I'm trying with ES6 import as below.
The firestore import increased 300+kb to my bundle (which is even larger than the CDN version).
What are the recommended settings with webpack? Are there any example for cherry picking the imports for the most basic db operations?

import firebase from '@firebase/app';
import '@firebase/firestore';

I'm using firebase-js-sdk only to login in user and getting his tokenId, later I pass this token to my api proxy so I can do other operations in backend. It would be great to at least reduce auth module bundle size first.

(Side note for the record, individual packages became available starting with v4.1.0 (released in May 2017)).

I'm using firebase-js-sdk only to login in user

I would second the request to optimize the size of the auth solution, since this would be a great onboarding path for many developers. Authentication is hard, and getting it right using Google's security is a smart choice.

However, the minimum bundle size for signing up a user with the Firebase Web UI and federated identity providers is huge:

That's 411kB (120kB gzipped) just to log users in. This comes pretty close to the performance budget Google recommends for mobile.

One immediate optimization would be load Firebase UI only when the user is not logged in, using Dynamic imports or an equivalent. Dynamic imports have been supported since 2019 in all major browsers..

Temporary solution for Firestore is described in this article https://davidea.st/articles/firebase-bundle-size

Instead of Server Side Rendering we can use Firestore REST API and PRPL-50.
https://firebase.google.com/docs/firestore/reference/rest/

@jshcrowthe do you have any updates on the progress towards slimming down the bundle size, especially when working with webpack?

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 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!

One "gateway" use case for the JS SDK is authentication. Very hard to get right on your own, and much easier to leverage Google's infrastructure and security.

The problem I've run into is that social login is a lot slower than with other systems. Try to log in with GitHub in the Firebase demo, and by comparison at https://spectrum.chat/login

More at https://github.com/firebase/firebaseui-web/issues/511

Have you already thought about a kind of mono-repo structure with different packages in the @firebase namespace (e.g. like babel)? I'm asking because the code example looks like it in principle.
A nice side effect would be that IDEs automatically import the optimized paths (e.g. with TypeScript an automatic import of firebase always ends in import * as firebase from 'firebase' and if I forget to adjust the import path, it happens again that everything is imported).

The example shown would then possibly look like this:

import { initializeApp } from '@firebase/app';
import { 
  getFirebaseAuth, 
  GoogleAuthProvider, 
  signInWithPopup 
} from '@firebase/auth';
// ...

@firebase/app would probably be a peerDependency that all other packages must have.

edit
I just realized you already have this structure. It might be useful to release these packages directly if you want to go the way of modularizing the API anyway.

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.

My app loads firebase app and auth js at the startup to get user's login state and profile. Other firebase services are loaded lazily when needed, especially firestore js is too big that must load lazily(this lead to all related operations are async). All firestore operations and some cloud functions are only for logged in users, so firebase auth is loaded at the startup. Firebase app+auth is 190KB, hope it less than 50KB.

For firebase auth, I only used one provider(Google) to login(by token) and logout, all other auth methods are disabled. In addition, hope auth return cached login state at once at the startup when online, rather than wait login state from firebase backend(it usually waits 2-3 seconds).

I use lazy loading of Firebase components but I get them from CDN.
For instance my loadApp function looks like this (simplified):

let app = null

export loadApp = () => app || app = new Promise( (resolve, reject) =>
  document.body.appendChild(Object.assign(document.createElement('script'), {
    src: `https://www.gstatic.com/firebasejs/${FIREBASE_VERSION}/firebase-app.js`
    onload: () => resolve(firebase.initializeApp(config))
    onerror: reject
})))

Same for loadFirestore, loadAuth, loadUi etc.

@dandv Thanks for sharing your story! I'm not sure if the lib size is the main cause of the slowness you experienced, but we understand Auth is a very important use case for users. Auth is going to be a big focus of this effort and we hope this redesign leads to a much smaller auth footprint in your bundle, so your app loads much faster.

@PutziSan Yes! we already have scoped @firebase/{component} packages. We don't have any plan to change it with the redesign. We will continue to have the all in one firebase package as well since it provides a convenient way to get all firebase services that are compatible with each other.

@hanguokai Thanks for sharing your use case! Our goal is making it possible to include only what you need in your bundle. Since it looks like you use only a small set of auth functionalities, app + auth can be a lot less than 190KB after tree shaking.

Some followup questions on firestore: What firestore features do you use (read/write, transaction, batch writes, realtime updates, offline persistence)?
You mentioned you have to lazily load firestore. I'm curious how you do it. Does making all operations async present any problem for you? Do you wish you can load part/all of firestore statically? What is the size limit you want to put on firestore?

@laurentpayot Thanks! I assume you did this because of the size of firebase. Would you consider bundling firebase in your app statically if you can include only what you use? What features do you use for Auth and Firestore respectively ? What is your standard on size?

@Feiyang1,

I'm not sure if the lib size is the main cause of the slowness you experienced, but we understand Auth is a very important use case for users. Auth is going to be a big focus of this effort and we hope this redesign leads to a much smaller auth footprint in your bundle, so your app loads much faster.

I agree, there's a lot of animation going on while the user logs in, and firebase-auth is already loaded at that point, so the slowness has got to be somewhere else. Any ideas?

@Feiyang1 thanks for caring about the size of Firebase. This is an issue that concerns all developers using Firebase products as well as end users.

My standard on size is whatever can keep my PWA lighthouse _performance_ indicator in the green zone, as recommended by Google. I'm using SSR to have better first contentful/meaningful paint metrics, but I also need to be interactive as fast as possible. I agree that "size matters" but parsing all that Firestore JS also has a high impact on the main thread. I had to use the above lazy loading trick to have finer timing control so I can delay download+parsing to the actual use of Firebase features instead of when the module is loaded. Even if I use chunks and tree shaking (Rollup bundle), will building Firebase in my app statically with only needed features really help performance-wise knowing that my app is a SPA and thus most modules are loaded at the beginning?

I'm using pretty much everything in Firestore, except GeoPoint for now.
I was using also pretty much everything in Auth (except SAML, Github and generic OAuth providers) but I gave up building a custom UI for authentication because best practices for security and UX are evolving so fast. Thanks to FirebaseUI now I'm only mostly using the firebase.auth.Auth interface minus the SignIn-related functions. FirebaseUI, even bloated with material design light and associated fonts, is a life changer and would deserve more visibility in the Firebase ecosystem.

Some followup questions on firestore: What firestore features do you use (read/write, transaction, batch writes, realtime updates, offline persistence)?
You mentioned you have to lazily load firestore. I'm curious how you do it. Does making all operations async present any problem for you? Do you wish you can load part/all of firestore statically? What is the size limit you want to put on firestore?

@Feiyang1 For firestore, I use read/write, batch delete( to clear all resources), and offline persistence with multiple tabs support. Multiple tabs are the essentials of the web, you can not ask user to only open one tab. So I use experimentalTabSynchronization option. I sync firestore data periodically, rather than use realtime updates, because the app is only for one user with multiple devices.

Offline persistence feature with multiple tabs support is good, but the default offline behavior maybe overwrite user's data if there is a conflict (like source code version control). So I implement sync(pull or push) method instead of read/write. Depends on the data types, sync method may auto merge data or resolve conflict by user manually. (PS: The logic of sync is a little complicated since many edge cases need to be considered)

I use the code like DB.init().then(firestore_db => {...} ) to perform all firestore operation. DB.init() load firestore.js asynchronously and init firestore instance (call settings() and enablePersistence()) only once for the first time, and return the Firestore instance. (PS: it checks some intermediate states to guarantee concurrent calls correctly). Both load firestore.js and db.enablePersistence() are asynchronous, so anyway using firestore will be asynchronous. That is no problems for me.

I don't know what firestore features can be split. But if there a smaller libraries can fit my needs I will use it. Currently I use read/write/batch delete/query all(for a collection) and offline persistence.

Except tree shaking, I hope firebase can supply a custom building method for selected features to generate smaller libraries.

As most others on this thread, I'm most concerned with auth and after that, firestore.

For most pages on my app, I need to know if the user is logged in or not before displaying any meaningful content. If they aren't logged in, then I can paint the log-in prompt immediately, but I also lazily load firestore and display non-sensitive information when it finishes loading. In this scenario, loading the auth quickly is most important, but the info coming from firestore might also be important. For example, if someone's friend sent them a link to my site, they might be uncomfortable creating an account until they see their friend's avatar. If it takes too long to load, a conversion is lost.

If the user is already logged in then I can't really paint anything meaningful until firestore is loaded, but in theory, this should be less of a problem due to service worker. The large bundle size isn't great for my user's mobile data caps in any case, but it only affects load time before the service worker is installed, and that is almost always before the user has logged in.

Thank you all for the amazing use cases!

@dandv TBH I couldn't say without looking into the details and I'm no expert in firebaseui. Sorry! @wti806, Do you have any idea?

@laurentpayot If you use most features from firestore/auth and want to keep the app light, you probably still need to do some kind of lazy loading. What the proposed APIs enable you to do is to lazy load in a more granular fashion instead of at the entire component level.

For example, you can include just read/write from firestore in your main bundle, so you can have a fast first paint with meaningful data while still keeping your main bundle small and lazy-load realtime updates or offline persistence.

@hanguokai Thanks so much for sharing the detailed user journey, really appreciate it! I like the idea of creating custom build. I think the proposed APIs can help you achieve it. You can pick the firebase features you need and import just them. If it is small enough, you may include it in your main bundle, otherwise you can create a separate chunk and load it lazily. Do you think it's something that would work for you?

Ho FB Team, wanted to give my quick notes to you.

I’m currently building Geoman.io with it. Size is a problem, yes.

We started to abstract Firebase away in our own API to get rid of the firestore module on the frontend. At some point, we only had it in to generate the unique firebase document keys. Would be nice to have that feature modularized.

I lazy load most modules by bundling them in async components that get loaded when needed so initial page load isn’t hit that hard. However, auth is in there. FirebaseUI is only loaded when the user clicks on “sign in”.

Regarding Auth we would love to have the following functions available as separate imports:

  • verifying an Access Token
  • refresh access token
  • sign in with [provider]
  • auth state change handler

I appreciate that you recognize the size problem and start with this change 👍.

Providing a few basic functions as a separate import would be already a nice first step, like generating a new document ID for firestore.

Best,
Sumit

Hi everyone, we are conducting a study on the SDK Size. If you are interested in talking to us on this subject, please complete this survey. https://forms.gle/utyTEXJXqPapLEWp9

Thanks!

@Feiyang1 you may have looked at it already, but was just wondering have you looked at rxjs for inspiration on how they rewrote their library similar to the way you mention above to improve performance through code splitting?

The main thing to point out when rewriting the SDK in this way is that you don't get the nice chaining syntax we have today like:

const docRef = db
    .collection("cities")
    .doc("SF")
    .get();

The way rxjs got around this to get a syntax close to chaining and avoid us having to wrap all our functions inside each other was by creating the .pipe() method which is a method in all observables.

We could do something similar with the core class types like firestore, auth, etc. An example below could be where we add a .chain() method to the db and then we can use it to chain on things like collection() or doc() like so:

import { collection, doc } from 'firebase/firestore';

const docRef = db
    .chain(
        collection("cities"),
        doc("SF")
    ).get();

This is just a thought I had which could possibly get a balance of performance and developer experience.

Just wanted to comment on my use-case for this thread.

I'm using firebase for web development, wanted to provide google/fb login on our site which is for a delivery service and is mobile first.

The sites pages are mostly rendered server-side by PHP using XSL templates. Our platform was designed with node in mind and can proxy requests to node if needed - but we haven't actually finished this or implemented anything on node yet.

Client-side JS loads firebase-app and firebase-auth, was using CDN but now using local as our site is served as XHTML and a bug in Closure resulted in it not working so we had to build our own static firebase locally for this, in fact the closure compiler optimized out our fix and required a hack; but other issues are open for that stuff.

So, client visits our website. There's a gateway that asks if they are of age, then they can access the site (though we are thinking of making them sign in first) where they can choose to register. Registration offers them the option of simply filling in their email/pw for email auth, or selecting facebook or google login, if they click facebook or google we do a firebase signInWithPopup asking for their birthdate, email, phone number.

We then plan to use the response with that info (facebook giving it up freely, google isn't, created issue about that) to pre-fill out our form; being a delivery service we need the users address, phone number, etc. but we want to pre-fill anything we can from their chosen auth provider.

From there we create an entry in our local database with the token of the firebase auth and all the extra user info that we need.

On future server-side renders, I believe we will have to have PHP use the firebase-admin-sdk to verify the user's token to ensure they're logged in to show them the appropriate template/page. Will also be used for our websites admin control panel to manage users.

We are possibly going to use firebase-auth for even just email/password authing, allowing firebase to handle all auth essentially while storing any extra data needed locally.

It is definitely important to us that the (client-side) libraries are small as they are only used briefly for auth.

Hey guys,

Any update on this ? are you close to get something more optimal ?

Just to add another use case: we don't use Firebase for auth, but we do use other features, including cloud messaging.

any updates? using the auth module requires huge amount of bundle size :/
image

PR #2230 removed 7873 LOC (and added 36). Wait and see...

@Feiyang1 any news on this? can't see anything in repo...

Looking forward to this. My current method is to build the app with Firebase and then replace the minor functionality with the REST api... this lets me cut out about 150k for realtime database since i only use it as a basic read/update most of the time.

/// Realtime Database update path
const update = (path, token, object) => {
  return axios.patch(
    `https://${projectId}.firebaseio.com/${path}.json`,
    JSON.stringify(object),
    { params: { auth: token } }
  );
};

/// Realtime Database fetch path
const fetch = async (path, token) => {
  const { data } = await axios.get(
    `https://${projectId}.firebaseio.com/${path}.json`,
    {
      params: { auth: token }
    }
  );

  return data;
};

I am dropping 2MB of JavaScript (improving both download and parsing) from my app by using Firestore over a WebSocket connected to App Engine. It allows me to:

  • ditch Firebase RTD connection which I was using for presence and to know when I was online
  • ditch Firestore's bloated libraries which have a ton of dependencies (and some edge-case bugs)
  • decreases my latency by 55%, almost twice as fast
  • hoping it solves issues with Firestore being blocked by some work-place firewalls when RTD is not.

I can also get rid of the auth because I only use email/password, so the majority of that code (which I assume is for oauth providers) is not needed, and I can use the REST APIs.

I will be implementing security in the socket code, so that should reduce my read requests on Firestore with the security rules and I can send data down I know my client needs rather than having it set up listeners (since I know my use-case). I _think_ I will be using Cloud Functions to send written data to PubSub and have my websocket code listen to that and send required updates to connected clients. Memory Store is another option on the table.

I'm very pleased with my initial experiments. Fingers crossed everything goes well. Just wanted to share that with a bit of work there are other options. I am excited this work is happening though! Other projects will need it.

My current bundle size

image

Currently the bundle size is incredibly large, so anything that can be done would be great. Firebase is now 6x larger than the rest of all other modules, assets and the app combined. It seems to go against googles web philosophies.

page_load_warnings

The size of these packages is ridiculous. And even more importantly in direct violation of Google their speed related criteria for an actual open web...

Any updates on this?

since this issue is now over 2 years old, and no work seems to be being done on this (as far as I can tell?), should we assume browser bundle size is just not a priority for FB?

i'm on the fence about whether to plump for firebase or use a collection of services over of this.

firebase is very appealing, but auth + firestore is 583kB/160kB, while auth0 + pouchdb are 136kB/44.8kB.

it's pretty hard to justify that...

@sndrs I also gave up now and am currently switching to auth0 and FaunaDB in my current project. I have to say that the size of these packages was NOT the only reason though.

I'm still a fan of firebase, especially since I was able to visit the team once in SF. Hope they tackle this at some point 👍.

@codeofsumit that's interesting - did you get subscriptions working with fauna?

Subscriptions to handle realtime stuff? I'm currently not requiring that functionality so can't tell

First, thanks for the hard work on this.

Is there a rough timescale that the revamp is expected? Firebases auth and firestore make writing apps absurdly easy. Unfortunately, these two together are massive and are often needed on the front end to show meaningful data. A useful data point when choosing the tech stack will be whether or not a potential file size reduction is on the scale of weeks, months, or years out.

Unfortunately I'm not able to give any specific timeline on this (I wish I could) but we are hopeful we finally are gathering the resources we need for this rewrite and hope to get it done this year. Firestore in particular has already started on some efforts right now, such as a minified bundle that is currently available to try out experimentally. Firestore is also trying to separate out code for persistence, so developers who don't want that feature can leave it out of their bundle.

Auth will probably take more time, as the first step will likely be to convert it from Closure to Typescript, to match the rest of the SDK, which is a significant rewrite.

Thanks for the response @hsubox76, it's good to know there's movement.
We actually grew a bit weary and wondered whether Firebase for the web turned from an advantage to a disadvantage. Hope to see some progress in the coming months.

@hsubox76 Thanks for linking that. The experimental build in 7.8.0 definitely looks promising! I just dropped it in and ran a build. It reduced my main bundle by almost 90k. I'll of course have to carve out some time to actually run the app and do some testing, but I'll definitely be keeping tabs on it.

@hsubox76 Thank you for the update. This is a big blocker for some of us.

EDITED to correctly state all browser bundles are minified.

FYI, starting from version 7.9.0 and after, the minified Firestore bundle is now the default, if you are importing the ESM bundle. You will get that bundle if your bundler (webpack, rollup, etc.) is configured to prioritize the "module" field in package.json or if you are directly importing the firestore/dist/index.esm.js file. (This is also true if your bundler is prioritizing the "esm2017" field, which imports the index.esm2017.js bundle.)

The Node and CJS bundles (what you get if your bundler prioritizes the "main" or "browser" fields) are not currently minified.

The Node bundle (what you get if your bundler prioritizes the "main" field) is not currently minified.

The other efforts (separating persistence in Firestore, rewriting Auth) are still in progress.

Great news @hsubox76! Thank you for moving this forward.

I'm using firebase 7.10 with webpack 4.42

Looking at production build with source-map-explorer it shows firestore with 269Kb pointing to commonjs build: firestore/dist/index.cjs.js

Interestingly, auth module loads esm version: auth/dist/auth.esm.js

This is how i'm loading firebase:

import * as firebase from 'firebase/app'

// Add the Firebase products that you want to use
import 'firebase/auth'
import 'firebase/firestore'

import { firebaseConfig } from './firebase.config.js'

firebase.initializeApp(firebaseConfig)

Should not webpack load the esm version by default?

Can someone confirm if webpack is loading esm version by default in its projects?

It depends on your webpack config. Please look at your resolve.mainFields entry: https://webpack.js.org/configuration/resolve/#resolvemainfields

There are different defaults depending on target, or you can specify the order explicitly. If module is highest priority, you will get the esm file. Otherwise you will get the various files mentioned above.

My webpack config does not touch resolve.mainFields, its the default with module taking precedence over main.

Other modules are loading esm like the mentioned firebase auth.

I will be loading the esm version directly but maybe there is something going on that is preventing the expected behavior.

I have the exact same issue. I use nextjs and I do not have any mainFields in my package.json.

I have the auth.esm but for firestore the index.cjs.

Please see below:
Screenshot 2020-03-13 at 14 23 16

Auth does not have a cjs package. See its package.json. It only has 2 options, main and module.

Firestore has more bundle options. Its esm bundle is also in the module field, same as auth, but there is also a browser field that contains the cjs field. See firestore package.json for all its 4 bundle options.

If you are getting the auth esm bundle but the firestore cjs bundle, your bundler is almost certainly prioritizing "browser" over "module". Again this is the default for webpack (documentation)

When the target property is set to webworker, web, or left unspecified: module.exports = { //... resolve: { mainFields: ['browser', 'module', 'main'] } };

You do not have to set mainFields for this to happen. This is the default behavior if you do not specify a target or mainFields.

Is there a way to specify the target in the package.json or how can I specify this?

It is a webpack (or rollup, or whatever your bundler is) configuration setting. I linked the webpack docs above. If you have another bundler, you can look up those docs, or if you are having trouble working with webpack config, try asking for help in webpack/rollup forums or Stack Overflow.

CORRECTION: The CJS build is minified. So sorry for the confusion. I will edit the post above. (So don't worry about reconfiguring webpack to get the esm bundle.)

I already commented with my solution in a different issue, but I think its relevant here too:
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.

I already commented with my solution in a different issue, but I think its relevant here too:
I wrote an alternative library for auth, storage, and Firestore in order to address the performance and size issues of the official SDK.
...
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.

Thanks for your work, and posting here. I haven't taken a look at it, but seems like you're definitely headed in the right direction.

If you've truly done most of the functionality at an order of magnitude better performance and code-size, makes me wonder what's going on here or what 'overhead' the official has that you've been able to cut.

I already commented with my solution in a different issue, but I think its relevant here too:
I wrote an alternative library for auth, storage, and Firestore in order to address the performance and size issues of the official SDK.
...
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.

Thanks for your work, and posting here. I haven't taken a look at it, but seems like you're definitely headed in the right direction.

If you've truly done most of the functionality at an order of magnitude better performance and code-size, makes me wonder what's going on here or what 'overhead' the official has that you've been able to cut.

Well, by functionality I didn't mean features.
So for example in the official Auth SDK you can perssist a session with localStorage/indexedDB/cookies.
In my alternative, I only support localStorage right now, cookies coming up.
So basically, my SDKs have most of the "core" functionality, meaning, you can use all of the services that firebase offers, but not necessarily all of the "features" that SKD offers, mainly because I don't think it's smart to bundle all features under the sun in the same package.

Also, one thing to note is that I only try to support relatively modern browsers(if the browser supports fetch, or you polyfill it then it should work).

@samuelgozi Maybe Google just kicked the can on this knowing that a community member would get fed up enough to fix it for them. :thinking:

@samuelgozi Maybe Google just kicked the can on this knowing that a community member would get fed up enough to fix it for them. đŸ€”

I don't think so. they still have employees working on this. It's probably the bureaucracy of the company. And they are also lucky that the competitors are not much better at this...

Thanks for putting my conspiracy theory to bed... and thanks for the packages!

I don't understand how a one-man army (@samuelgozi) can do the job in a month but the whole Firebase team from Google can't in 2 years and a half đŸ€·â€â™‚
This lib generates revenue I'd assume it has some priority for the company

Nevermind, I'll just go with auth0 + FaunaDB
I cannot jeopardize my app by shipping 400kb of things that nobody needs, sorry.

P.S.: And sorry for being so hard but this goes way beyond my understanding

@jenperson is a Developer Advocate from Google who has worked on Firebase.

@dandv just FYI Jen is no longer working on Firebase (although she's still at Google!), but I'm here listening/watching and so are some others like @jamesdaniels.

@Feiyang1 Im new to firebase
Did that get implemented since you spoke of the plan?

Thanks!

"// 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 => {...});"

@philliprousu The work is in progress. Please keep an eye on the repo and I hope to have something to show you very soon!

For everyone on this thread, I'm sorry that it takes so long for another update - @hsubox76 gave a good overview of the state of things earlier. To add to that, we have already started working on some SDKs, @firebase/app branch and @firebase/auth branch. We will start working on other SDKs one by one.

We plan to release these rewrites experimentally as they become available. Possibly using a special release tag in the existing packages. e.g. you can install the modular @firebase/app by npm install @firebase/app@exp. We'd like to collect as much feedback as possible from the community during the experimental phase, so we will need your help.

Please stay tuned and Thanks!

@Feiyang1 wow thanks for getting back to me so fast, as a junior dev (currently at hack reactor), would you recommend using the hosted urls for these SDKs, I know thatll take care of the config for me due to hosting and the hosted url sdks OR would you recommend going the npm install route and having one giant bundle for production? or a vendor bundle from webpack for the react/firebase stuff and a seperate bundle for logic..? is there a speed increase for the hosted URL route versus installing with NPM and building these bundles on my own?

@hsubox76 thanks for reply and sorry for delayed response. You are right.

Firestore has more bundle options. Its esm bundle is also in the module field, same as auth, but there is also a browser field that contains the cjs field. See firestore package.json for all its 4 bundle options.

Just like to point that does not makes sense browser field point to cjs version because:

  1. consistency with other firebase packages
  2. the browsers does does not understand cjs export but, most of them, supports es module exports

So i would suggest to remove browser field (bundlers will use module on browser) or make it point to esm version in next breaking version

@samtstern, @jamesdaniels, @hsubox76: great to see the ongoing effort to slim down Firebase!

I wonder if the slowness of firebaseui-web social logins is related to the large bundle size, or independent. Context:

@dandv Its both.
The firebase ui libs alone is 66KB(minified and gzipped).

@samuelgozi: I'm not sure 66KB downloaded over a 300Mbps connection (even plus parsing) explains 3+ seconds of animations. Do you think replacing Firebase Auth with your 2Kb alternative in firebaseui-web would bring down the social login time to something comparable with Auth0?

@dandv Im not saying it's the only issue.But its a big part of it.
It's 66KB that needs to be unzipped, and then parsed and executed.
In addition you'll need the firebase library which is huge. So the UI will need to wait for that library to download before doing anything.

Then there is the design of the authentication flow.
In the official library, you are redirected to https://project.firebaseapp.com/__/auth/handler
for additional "handling" which also loads few hundreds of KBs of code, that then redirect you back to your app.

With my reply to you my intention wasn't to plug my lib(I'm not shy about doing that either), but to answer your question, my lib is orders of magnitudes faster.

I have a proof of concept app that I built with my libraries. Feel free to roam around and see how I use all my libs there, and look at the performance difference:

https://nano-inventory.web.app

(The UI or code in this site is not open source unfortunately, but I uses my Firestore, auth and storage libs. And please don't abuse the site)

A quick note, the versions of my libs in this project are relatively old. so if you encounter a bug its probably fixed in the new ones.

Wow! Signing in with Google was very fast! Faster than Auth0 even, or comparably fast to not perceive a difference.

How hard would it be to add Apple login?

Wow! Signing in with Google was very fast! Faster than Auth0 even, or comparably fast to not perceive a difference.

How hard would it be to add Apple login?

It should technically already work. But I couldn't try it since I only have a free developer account at apple.

Google needs to acquihire your open source library haha. From what I can tell you've done quite a bit of work for them.

I already commented with my solution in a different issue, but I think its relevant here too:
I wrote an alternative library for auth, storage, and Firestore in order to address the performance and size issues of the official SDK.
...
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.

Thanks for your work, and posting here. I haven't taken a look at it, but seems like you're definitely headed in the right direction.
If you've truly done most of the functionality at an order of magnitude better performance and code-size, makes me wonder what's going on here or what 'overhead' the official has that you've been able to cut.

Well, by functionality I didn't mean features.
So for example in the official Auth SDK you can perssist a session with localStorage/indexedDB/cookies.
In my alternative, I only support localStorage right now, cookies coming up.
So basically, my SDKs have most of the "core" functionality, meaning, you can use all of the services that firebase offers, but not necessarily all of the "features" that SKD offers, mainly because I don't think it's smart to bundle all features under the sun in the same package.

Also, one thing to note is that I only try to support relatively modern browsers(if the browser supports fetch, or you polyfill it then it should work).

Try using something like store.js or other relevant libs for adding cookies/ indexedDB as additional storage options. Perhaps some libs automatically store data based on the kind of storage available on device/ browser.

@waleedshkt I avoid using dependencies at all costs. But it is currently possible to provide a storage object to the constructor and it will use it to persist the data.

The object needs to have get, set and delete methods, and follow a specific signature for the paeans and return value, but for now it’s pretty flexible.

In addition I’m planing to make IndexedDB the default, but I’m not yet sure if it will come on v1.0.0 or later.

@samuelgozi That's great.

Btw, I'll be using your lib for firebse auth in my web app in production. I know you haven't made it fully production-ready yet but it's way lightweight, fast and works promisingly well. Would be locking the current version of it for next 2 months.

@waleedshkt Im working very hard on v1.0.0 and I hope it will be ready in the next few weeks.
I feel like a broken record saying this, but I'm very close now, and I'm making it even smaller and easier to maintain.
Just letting you know that when moving to that version, some minor refactoring will be needed. But after that, It won't change for a while.

To follow up on my last update, we have published a few modularized SDKs to npm under a special tag exp. You can install them using npm install firebase@exp. Currently only @firebase/app, @firebase/functions and @firebase/firestore are available, we are actively working on others.

See @schmidt-sebastian's post for sample usage for @firebase/firestore and the link to reference docs. As mentioned in the post, we still have more work to do and we are mostly looking for feedback on the API surface at the moment. Thank you!

@samuelgozi legend. Forgive the noobie question as I dont know much, but Security wise, is it this same with Google Firebase Auth? Im planning to use your SSO in my website.

@heliosnarcissus Thank you, and yes, it's the same level of security. I adhere to the openID standard.

If you have any more questions feel free to open an issue in the repo, I don't want everyone here to get notifications for that.

@Feiyang1, I don't see the auth module in the firebase@exp or am I missing something. The first step in using firebase in a web application is to use the auth! Without auth module in, I don't see how this work is going to be useful for most of the devs out there! Rest of the modules, even now, can be loaded asynchronously. The biggest pain point discussed in this thread is auth and that is not available in the first cut you have provided.

If I am missing something here, please correct me!

It's not in 'exp' yet but we're definitely working on the smaller Auth
SDK! We 100% agree that it's probably the most important one to make your
apps fast.

On Wed, Sep 23, 2020 at 9:16 AM Phani notifications@github.com wrote:

>
>

@Feiyang1 https://github.com/Feiyang1, I don't see the auth module in
the firebase@exp or am I missing something. The first step in using
firebase in a web application is to use the auth! Without auth module in, I
don't see how this work is going to be useful for most of the devs out
there! Rest of the modules, even now, can be loaded asynchronously. The
biggest pain point discussed in this thread is auth and that is not
available in the first cut you have provided.

If I am missing something here, please correct me!

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/firebase/firebase-js-sdk/issues/332#issuecomment-697209692,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ACATB2VNOC7ZKBIRMISED7DSHGVG7ANCNFSM4EFGII2Q
.

@samtstern Thank you for your quick response on this one. Do you have an ETA by when we can expect this? because we are currently using firebase SDK only, and thinking to move to @samuelgozi 's light version. If the ETA is very near, it doesn't make sense for us to change our application multiple times.

@phani1kumar we're working hard on this but can't offer any timelines (as a rule, we never do).

Once again ,thank you very much for your prompt reply @samtstern

@schmidt-sebastian The pull request appears to be merged, but @firebase/auth is still not available in firebase@exp?

We're still waiting for a few processes and final checks to happen before we roll out the experimental release.

We're still waiting for a few processes and final checks to happen before we roll out the experimental release.

So where exactly was it merged into exactly? I saw it was merged into master but is that just a holding place before it gets rolled out in a release?

Releasing is separate from merging code to master. We can control what packages get released when in the release process.

master is just where code sits before someone wants to use it to create a release

Still waiting. It is 700kb gZipped.

Such a comment is useless. The discussion is active on this issue. Please be patient. There are people behind a github repo!

The issue is 3 YEARS OLD :-(((

@hsubox76 I'm still not seeing auth module added to firebase@exp. How long before it'd be included?
It's just that I need to include authentication with phone number, and still don't want to add all the humongous-sized firebase in the app build!

Btw, my current Firebase-sdk version is 0.800.11

There's a new version of (experimental!) firebase@exp, and it's working! Sorry to preempt any official word on this, but I was excited to try it and see the size difference. In my app it shaved about 30k off the gzipped chunk containing Firebase, using it like so:

import * as firebase from "firebase/app";
import * as firebaseAuth from "firebase/auth";

firebase.initializeApp(firebaseConfig);

const app = firebase.getApp();
const auth = firebaseAuth.initializeAuth(app);
const response = await firebaseAuth.signInWithEmailAndPassword(auth, "foo", "bar")

_Edit: I'm not associated with Firebase, I'm just an excited user. Definitely don't use this experimental package in your production app. But if your goal is to see which way the wind is blowing and plan for the future, the package is an important piece of evidence, especially for anyone deciding whether to use Firebase Auth on a new project._

BRILLIANT!!

(edit: @jrr is not in the team hehe) @hsubox76 @Feiyang1 and the rest of firebase devs, a BIG THANK YOU!
Whoever from the firebase team heard the request to add the auth module and released a new exp version within 24hrs is a champ!
Now that there are modularized firebase libs, we are talking clapping

Alright so in a new version, to create a firebase app with auth , the following is the new way (@jrr, just making it clear; your above snippet is correct):

import { initializeApp, getApps, getApp } from 'firebase/app';
import { initializeAuth, signInWithEmailAndPassword } from 'firebase/auth';

// default app initialization (with logic to prevent reinitialization)
//FYI, getApps is like firebase.apps, and getApp returns app instance
const app = !getApps().length ? initializeApp(configObj) : getApp();

//Initialize auth instance
//previously app.auth(). But now:
const auth = initializeAuth(app);

//Now here is a big change made to auth functions. Almost all main functions needed to signin require auth instance as a firest argument. 
//Obviously, one should only import the functions needed like e.g signInWithEmailAndPassword from firebase/auth
const response = await signInWithEmailAndPassword(auth, 'EMAIL', 'PASS'); // or use .then().catch()

Hope it helps 😃

Just to be clear, the exp packages are not officially released even in alpha. The versions being published right now are primarily meant for internal testing. If you use them right now, many things (possibly entire products) could be broken, and we aren't offering any support yet. We hope to begin offering it for limited testing in a few weeks and will have a sign-up form for those who want to help test. Even when the trial is open, we want to emphasize the exp packages are experimental and should not be used in production at all until GA.

Yeah, noted it is a pre-alpha. But it is a pretty big thing seeing firebase-sdk getting modularized

@hsubox76 I understand the testing stages new improved firebase-sdk has to go through yet till officially stable release.
But can you give a rough estimate for how long this testing process will take?

Was this page helpful?
0 / 5 - 0 ratings