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

Dynamic side-effect imports show up in "first load JS" sizes #15478

Closed
nicholaschiang opened this issue Jul 25, 2020 · 2 comments
Closed

Dynamic side-effect imports show up in "first load JS" sizes #15478

nicholaschiang opened this issue Jul 25, 2020 · 2 comments

Comments

@nicholaschiang
Copy link
Contributor

Bug report

Describe the bug

A clear and concise description of what the bug is.

To reduce the "first load JS" bundle sizes, I'm dynamically importing the individually installable Firebase services only when they're needed:

import firebase from 'firebase/app';

export async function signupWithGoogle(): Promise<void> {
  await import('firebase/auth');
  const provider: AuthProvider = new firebase.auth.GoogleAuthProvider();
  const [err, cred] = await to<UserCredential, AuthError>(
    auth.signInWithPopup(provider)
  );
}

This should only load the Firebase Authentication SDK when signupWithGoogle is actually called client-side. Thus, the @firebase/auth module should not be included in the "first load JS" sizes outputted by next build.

But, it appears that they are because there was no change in those "first load JS" numbers after I added the dynamic import (that was previously a static import):

Before:

Page                                                           Size     First Load JS
┌   /_app                                                      4.61 kB         117 kB
├ ● /[locale]                                                  7.6 kB          287 kB
├   └ css/4641472c8e3dea0827b7.css                             5.38 kB
├   └ /en                                        
├ λ /[locale]/[org]                                            4.49 kB         304 kB                                                       
├   └ css/ed87a86cf5ab98379191.css                             3.96 kB
├ λ /[locale]/[org]/dashboard                                  2.96 kB         286 kB          
├ λ /[locale]/[org]/dashboard/appts                            2.96 kB         286 kB          
├ λ /[locale]/[org]/dashboard/people                           2.96 kB         286 kB
├ λ /[locale]/[org]/search/[[...slug]]                         2.52 kB         282 kB
├ λ /[locale]/[org]/signup                                     450 B           **287 kB**
├ λ /[locale]/dashboard                                        421 B           284 kB
├ ● /[locale]/login                                            3.01 kB         260 kB
├   └ css/39acfc9bc2c049ec4b5a.css                             1.28 kB
├   └ /en/login                                    
├ λ /[locale]/search/[[...slug]]                               2.52 kB         282 kB
├ ● /[locale]/signup                                           415 B           287 kB
├   └ /en/signup
├ ○ /404                                                       2.57 kB         120 kB
├ λ /api/account
├ λ /api/appts
├ λ /api/orgs
├ λ /api/orgs/[id]
├ λ /api/redirect
├ λ /api/users
├ λ /api/users/[id]
└ λ /api/users/[id]/parents
+ First Load JS shared by all                                  117 kB
  ├ static/pages/_app.js                                       4.61 kB
  ├ chunks/1cb40a160d55ae59901b648a7c2e9ad60c50f4db.b82183.js  53.9 kB
  ├ chunks/commons.4e7daa.js                                   10.7 kB
  ├ chunks/edf3fb46.90ba64.js                                  65 B
  ├ chunks/framework.126679.js                                 40.3 kB
  ├ runtime/main.4a2881.js                                     6.28 kB
  ├ runtime/webpack.740335.js                                  1.26 kB
  ├ css/407651ee3d4b67a4780f.css                               128 B
  └ css/c51f0120853a257269f3.css                               20 kB

λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerSideProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)

After:

Page                                                           Size     First Load JS
┌   /_app                                                      4.61 kB         117 kB
├ ● /[locale]                                                  7.6 kB          287 kB
├   └ css/4641472c8e3dea0827b7.css                             5.38 kB
├   └ /en
├ λ /[locale]/[org]                                            4.49 kB         288 kB
├   └ css/ed87a86cf5ab98379191.css                             3.96 kB
├ λ /[locale]/[org]/dashboard                                  2.96 kB         286 kB
├ λ /[locale]/[org]/dashboard/appts                            2.96 kB         286 kB
├ λ /[locale]/[org]/dashboard/people                           2.96 kB         286 kB
├ λ /[locale]/[org]/search/[[...slug]]                         2.52 kB         282 kB
├ λ /[locale]/[org]/signup                                     451 B           **270 kB**
├ λ /[locale]/dashboard                                        421 B           284 kB
├ ● /[locale]/login                                            2.91 kB         260 kB
├   └ css/39acfc9bc2c049ec4b5a.css                             1.28 kB
├   └ /en/login
├ λ /[locale]/search/[[...slug]]                               2.52 kB         282 kB
├ ● /[locale]/signup                                           415 B           270 kB
├   └ /en/signup
├ ○ /404                                                       2.57 kB         120 kB
├ λ /api/account
├ λ /api/appts
├ λ /api/orgs
├ λ /api/orgs/[id]
├ λ /api/redirect
├ λ /api/users
├ λ /api/users/[id]
└ λ /api/users/[id]/parents
+ First Load JS shared by all                                  117 kB
  ├ static/pages/_app.js                                       4.61 kB
  ├ chunks/a3e22fb7e7642551f7c385a0bb084aba98bf002b.b82183.js  53.9 kB
  ├ chunks/commons.4e7daa.js                                   10.7 kB
  ├ chunks/edf3fb46.90ba64.js                                  65 B
  ├ chunks/framework.126679.js                                 40.3 kB
  ├ runtime/main.4a2881.js                                     6.28 kB
  ├ runtime/webpack.8b08c2.js                                  1.29 kB
  ├ css/407651ee3d4b67a4780f.css                               128 B
  └ css/c51f0120853a257269f3.css                               20 kB

λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerSideProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)

And there should definitely be at least a 50 KB difference:

image

What's strange is that the /[locale]/signup page size did seem to change slightly, which might have been due to me adding a similar dynamic import:

import firebase from 'firebase/app';

export function PhotoInput(): JSX.Element {
  // An event handler on a `PhotoInput` component that is used to collect the user's
  // profile photo on the signup page.
  const handleChange = async (event: React.FormEvent<HTMLInputElement>) => {
    const file: File = event.currentTarget.files[0];
    const lastDotIndex: number = file.name.lastIndexOf('.');
    const filename: string = file.name.substring(0, lastDotIndex);
    const extension: string = file.name.substring(lastDotIndex + 1);
    const pathname = `${
      process.env.NODE_ENV === 'development' ? 'test' : 'default'
    }/temp/${uuid()}.${extension}`;

    setHelperValue(`Uploading ${filename}.${extension}...`);

    // I dynamically import the Firebase Storage SDK which I use to upload the user's 
    // profile photo.
    await import('firebase/storage');
  };
}

To Reproduce

See the code snippets above. If needed, I can also create a repro (just comment if you want one).

Expected behavior

A clear and concise description of what you expected to happen.

The dynamic imports should show up in the bundle-analyzer output, but they shouldn't be included in the "First load JS" sizes that are logged by next build.

System information

  • OS: Ubuntu 18.04.2
  • Version of Next.js: 9.4.4
  • Version of Node.js: 12.16.1
@nicholaschiang
Copy link
Contributor Author

Nevermind, turns out I was importing firebase/auth in other places as well. Just had to change those to dynamic and it worked as expected.

I still have some issues with bundle analyzing though (see #15481).

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants