Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR] Bundle size #1426

Open
hffmnn opened this issue Aug 30, 2021 · 12 comments
Open

[FR] Bundle size #1426

hffmnn opened this issue Aug 30, 2021 · 12 comments

Comments

@hffmnn
Copy link

hffmnn commented Aug 30, 2021

Is your feature request related to a problem? Please describe.
When using firebase-admin on AWS lambda it adds a big blog to the bundle size. We are using esbuild to bundle our sources written in TS, and bundling the admin sdk adds an extra of 5.7MB, minified 2.8MB. This is far from optimal, because the bundle should be as small as possible for better cold-start performance. The code looks like this:

import * as admin from "firebase-admin";

const app = admin.initializeApp();
console.log("app :>> ", app);

const firestore = app.firestore();
console.log("firestore :>> ", firestore);

Describe the solution you'd like
Make it possible to load or install only the parts of the SDK that are really needed (like the new version of the js client sdk => https://github.com/firebase/firebase-js-sdk)

Describe alternatives you've considered
I tried to add only parts of SDK we need, e.g.

import { initializeApp } from "firebase-admin/lib/firebase-namespace";

const app = initializeApp();
console.log("app :>> ", app);

const firestore = app.firestore();
console.log("firestore :>> ", firestore);

but this gives the same bundle size and it does not work, even when compiling with tsc: When running via node main.js it gives this:

/some/path/main.js:6
var app = (0, firebase_namespace_1.initializeApp)();
                                                 ^

TypeError: (0 , firebase_namespace_1.initializeApp) is not a function
@google-oss-bot
Copy link

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

@hiranya911
Copy link
Contributor

We are adding ES modules support and the ability to import individual modules soon. But the overall bundle size won't change anytime soon, since we plan to keep the old admin namespace and the App interface for a while. Also a lot of the bundle weight you're seeing today comes from our dependencies like @firebase/database and @google-cloud/firestore. Therefore any programs that use those services will not see a size improvement even if we did fully modularize the Admin SDK:

$ du -hs * | sort -rh | head -10
 15M	@firebase
8.0M	google-gax
6.5M	protobufjs
6.4M	@google-cloud
1.9M	@types
1.8M	node-forge
1.4M	@grpc
1.1M	firebase-admin
616K	date-and-time
524K	google-auth-library

Have you done any tests on AWS regarding cold start latency? Do you know how the bundle size of the SDK has affected its performance on AWS Lambda? At least on GCF we haven't seen any common latency issues, except in a few cases where Firestore is involved.

@hffmnn
Copy link
Author

hffmnn commented Sep 2, 2021

Hi and thanks for the answer. I did not explicitly test it against our setup, but various tests seem to indicate, that bundle size matter: https://mikhail.io/serverless/coldstarts/aws/ => See headline Does Package Size Matter?

I guess there are 2 things that make a difference:

  • The download for the zip (which hopefully is negligible)
  • The time it takes node to parse/interpret/whatever node does to start executing the code

And I guess the second point should make a difference?

@hiranya911
Copy link
Contributor

I'm not sure at 5.7MB (2.8MB minified) it makes a huge difference. Looking at the results in that article it shows a 1KB package with a cold start latency of ~0.5 seconds, and a 14MB package with a cold start latency of 1.5-2 seconds. So it may be the case that the few extra MBs added by the SDK doesn't affect the latency a lot. We'll need to run some targeted tests to know for sure.

If you're interested, please checkout #1230, which shows what our ES module entry points would look like. Although I doubt it will have any immediate effect on bundle size (please let us know if you get a chance to test).

@hiranya911
Copy link
Contributor

@hffmnn if you can please try out the changes in #1432 and let us know if it helps. You can checkout the PR branch and do:

npm install
npm pack

And then install the generated tarball package to your project:

npm install path/to/tarball

@dhoulb
Copy link

dhoulb commented Oct 7, 2021

@hiranya911 Is there any long-term plan to update the Node Admin SDK to match the new v9 Javascript SDK and support tree shaking etc? It's strange that the two SDKs are now so different. Has that been considered internally and is there an intention to fix it?

It would also solve this issue.

@hiranya911
Copy link
Contributor

We have discussed this at length, and an effort to fully match the JS SDK is not something we want to take on. You will find some of the rationale at our modular Admin SDK alpha site: https://modular-admin.web.app/get-started/why-change (This document is somewhat outdated now, since we changed our minds about certain points during the alpha testing program. But the high-level thinking remains the same.)

The key point is that Firebase server-side SDKs (i.e. Admin SDKs) should look like GCP server-side SDKs. We also know that bundling is not a common practice in the server-side Node.js world, and size reduction in general has no significant impact on most server-side deployments -- you can typically manage the overhead via techniques like module lazy loading, which we already do. So an effort to fully treeshake the SDK doesn't even benefit most of the users. With that in mind, the modularization story for the Admin SDK is focused on delivering these:

  1. Continue to follow a style that's consistent with GCP server-side SDKs (Firestore, Storage etc).
  2. Support native ES modules, which is a feature available on Node.js 12 and up.
  3. Remove namespaces, an outdated API style in JS, and support modules with separate entry points instead.
  4. Provide some reasonable bundle size reduction via internal refactoring, for those developers that do use bundlers.

@hffmnn
Copy link
Author

hffmnn commented Nov 15, 2021

I tested with the new modular version and it stripes off around one MB.

@IchordeDionysos
Copy link
Contributor

@hiranya911 Another point to consider here is the number of transitive dependencies:

Installing firebase-admin also installs 165 additional packages (mostly via Google Cloud Storage and Firestore)

Would be nice if this could be reduce, I've already files issues with @google-cloud/storage and @google-cloud/firestore.

http://npm.anvaka.com/#/view/2d/firebase-admin
image

@alexplumb
Copy link

I'm now starting the process of upgrading Firebase from v8 to v9 and Firebase-Admin from v9 to v11 and I think it really needs to be said that the difference between the two experiences is confusing. Previously, I was able to write (almost) exactly the same code on the front-end and back-end, but now I'm forced to either write code in totally different ways OR build an adapter for the two projects.

As far as reducing bundle size, I know the difference is pretty minimal in terms of cold start performance, but surely there's an argument to be made for trigger deployment reliability. I maintain a fairly large app with quite a few triggers, and although I admit this is totally anecdotal, when the size of the bundle gets to a certain point, the triggers just stop deploying as consistently. I frequently run into errors where one of many triggers just hangs during deployment. Perhaps that's an issue with firebase-tools instead of this package, but I feel that bundle size reduction is not something that's solely in the wheelhouse of front-end packages.

Just my two cents.

@laurentpayot
Copy link

@alexplumb To write the same code on the front end and the back end with v9 I ended up writing a compatibility module: #1238 (comment)

@juniorforlife
Copy link

juniorforlife commented May 8, 2024

I'm also suffering from the heavy SDK size. It makes my Vercel serverless cold start time super slow even if I use modular import.
@hffmnn Have you found a way to work around this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants