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

Reactfire preventing lazy loading of firebase modules #488

Open
matt-kinton opened this issue Nov 18, 2021 · 7 comments
Open

Reactfire preventing lazy loading of firebase modules #488

matt-kinton opened this issue Nov 18, 2021 · 7 comments
Assignees

Comments

@matt-kinton
Copy link

matt-kinton commented Nov 18, 2021

When using ReactFire I want to lazy load Firestore to reduce build initial build size and improve load times. When using ReactFire lazy loading firestore does not happen even while using import('firebase/firestore').

I have included a version that does not use ReactFire with working lazy loading as shown by the initialisation time.
I have also included a version that does use ReactFire where I am trying to use lazy loading but I believe it is not working.

I noticed this in a Nextjs project with the bundle analyzer but haven't included Nextjs in the examples for simplicity.

Version info

React: 17.02

Firebase: 9.4.1

ReactFire: 4.2.1

Test case

Test case without using ReactFire and lazy loading working:
https://codesandbox.io/s/blissful-scott-05qj6?file=/src/App.tsx
https://csb-9c5hc.netlify.app/

Test case with using ReactFire and lazy loading not working:
https://codesandbox.io/s/elegant-roentgen-2iyt8?file=/src/App.tsx
https://csb-2iyt8.netlify.app/

You can use the network tab to see that 6 networks requests are made without ReactFire but only 5 are made with using it, you can also see the breakdown of chunks in the lighthouse analysis.

Lighthouse Treemap without ReactFire
Lighthouse Treemap with ReactFire

This is quite a big blocker for me so any help would be appreciated.

Steps to reproduce

Open the two codesandbox's/netlify deployments above.

Expected behavior

Firestore is loaded in a separate chunk.

Actual behavior

Firestore is loaded in the initial chunk.

@jhuleatt jhuleatt self-assigned this Nov 19, 2021
@jhuleatt
Copy link
Collaborator

jhuleatt commented Nov 19, 2021

Hi @Mattinton, this is really interesting, thanks for the repros.

My first thought was that maybe we were accidentally only exporting the .cjs build of ReactFire, but we do have the module field in our package.json, so I don't think that's it. Will keep investigating.

@jhuleatt
Copy link
Collaborator

jhuleatt commented Nov 19, 2021

I wonder if it's because our package.json is missing the exports field. react-scripts, which is bundling your examples, uses webpack, and it looks like webpack expects the exports field. I'm not sure if it looks at the module field. The webpack docs say:

exports field is preferred over other package entry fields like main, module, browser or custom ones.

Related TSDX issue (ReactFire uses TSDX for the build): jaredpalmer/tsdx#298 (comment)


update: I pulled https://codesandbox.io/s/elegant-roentgen-2iyt8?file=/src/App.tsx down locally, npm installed, then modified ReactFire's package.json in the node_modules folder to have an exports field. Then built and checked the bundle. Doesn't seem to have made a difference.

@jhuleatt
Copy link
Collaborator

jhuleatt commented Nov 19, 2021

It seems that just using FirebaseAppProvider (without any call at all to import or lazy import Firestore) is enough to pull Firestore and Storage into the bundle 😬 🤯

I'm not sure why, because FirebaseAppProvider doesn't import either of those. It only imports the following:

import * as React from 'react';
import { getApps, initializeApp, registerVersion } from 'firebase/app';

When I try to just import getApps, initializeApp, registerVersion directly in an app (without importing FirebaseAppProvider), Firestore and Storage are NOT included in the build, so it doesn't appear to be a bug in the Firebase JS SDK itself.

I think it has something to do with our build.


UPDATE: After investigating more, I didn't have tree shaking properly enabled in my tests for my comment above. Once I got tree shaking set up, the extra stuff was dropped from my bundle

@matt-kinton
Copy link
Author

I did fork the repo and play around with it myself and also had no luck. I did notice that importing performance lazily didn't add to the overall package size and worked as expected. What are the differences between performance and firestore/storage?

@matt-kinton
Copy link
Author

Hey @jhuleatt did you ever make any progress on this? Cheers

@alexduhem
Copy link

Hey there, got the same issue, I just pulled all my hairs out my head to know what libraries was causing this.

finally I just did a little hack with the webpack config by using https://webpack.js.org/configuration/externals/

config.externals = { 'firebase/database': 'root Math', };

this hack force remove the firebase/database dependency out of the bundle.
why putting Math ? because webpack will add a small line in the bundle : "e.exports=math", so I used a builtin package to export to not crash the whole app

@Gbuomprisco
Copy link

Gbuomprisco commented Sep 16, 2022

When using Next.js, every module in Firebase appears to be bundled: #489 (comment)

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

No branches or pull requests

4 participants