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

refactor(@angular/build): add experimental chunk optimizer for production application builds #27953

Merged
merged 1 commit into from
Jun 28, 2024

Conversation

clydin
Copy link
Member

@clydin clydin commented Jun 27, 2024

An experimental chunk optimizer is now available for initial usage. To enable the optimization, script optimization must be enabled as well as an environment variable NG_BUILD_OPTIMIZE_CHUNKS=1. This build step uses rollup internally to process the build files directly in memory. The main bundling performs all resolution, bundling, and tree-shaking of the application. The chunk optimizer step then only needs to access the in-memory built files and does not need to perform any disk access or module resolution. This allows the step to be performed fairly quickly but it does add time to the overall production build. The NG_BUILD_DEBUG_PERF=1 environment variable can be used to view how long the step takes within a build via the OPTIMIZE_CHUNKS entry. In the future, this optimization step may be automatically enabled based on initial file entry count and size. There are several current known issues:

  1. Bundle budgets for named lazy chunks may not work as expected.
  2. The console output may not show names (files will be present) for lazy chunk files.
  3. The stats file (--stats-json option) will not exactly reflect the final written application files. This is similar to the current behavior of the browser builder with Webpack's stat file.

@clydin clydin marked this pull request as ready for review June 27, 2024 20:24
@clydin clydin requested a review from alan-agius4 June 27, 2024 20:25
@clydin clydin added the action: review The PR is still awaiting reviews from at least one requested reviewer label Jun 27, 2024
@ChristopherPHolder
Copy link

#27715

Would love to help with this issue, I have a functioning implementation on a large project and would love to cooperate.

@clydin clydin added the target: rc This PR is targeted for the next release-candidate label Jun 27, 2024
Copy link
Collaborator

@alan-agius4 alan-agius4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alan-agius4 alan-agius4 removed the action: review The PR is still awaiting reviews from at least one requested reviewer label Jun 28, 2024
…tion application builds

An experimental chunk optimizer is now available for initial usage.
To enable the optimization, script optimization must be enabled as well as
an environment variable `NG_BUILD_OPTIMIZE_CHUNKS=1`. This build step uses
`rollup` internally to process the build files directly in memory. The main
bundling performs all resolution, bundling, and tree-shaking of the application.
The chunk optimizer step then only needs to access the in-memory built files and does not
need to perform any disk access or module resolution. This allows the step to be
performed fairly quickly but it does add time to the overall production build.
The `NG_BUILD_DEBUG_PERF=1` environment variable can be used to view how long the step
takes within a build via the `OPTIMIZE_CHUNKS` entry. In the future, this optimization
step may be automatically enabled based on initial file entry count and size.
There are several current known issues:
1) Bundle budgets for named lazy chunks may not work as expected.
2) The console output may not show names (files will be present) for lazy chunk files.
3) The stats file (`--stats-json` option) will not exactly reflect the final written application files. This is similar to the current behavior of the `browser` builder with Webpack's stat file.
@clydin clydin force-pushed the application/chunk-optimizer branch from 8e7bb83 to 0691746 Compare June 28, 2024 12:34
@clydin clydin added the action: merge The PR is ready for merge by the caretaker label Jun 28, 2024
@clydin clydin merged commit a5f1b91 into angular:main Jun 28, 2024
31 checks passed
@clydin
Copy link
Member Author

clydin commented Jun 28, 2024

The changes were merged into the following branches: main, 18.1.x

@clydin clydin deleted the application/chunk-optimizer branch June 28, 2024 12:59
@clydin
Copy link
Member Author

clydin commented Jun 28, 2024

@ChristopherPHolder Thank you for offering to help. This will be available for use in the release next week. If you (or anyone else interested) have the time, please try it with your application and let us know how well it works for your project. If you are interested in trying it out sooner, there are also snapshot builds available:
If using @angular/build:application, github:angular/angular-build-builds#8d314a1.
If using @angular-devkit/build-angular:application, github:angular/angular-devkit-build-angular-builds#8d314a1.
Depending on the package manager used, you may need to use the --force option with the snapshot builds.

Please provide feedback in the mentioned issue (#27715).

@ChristopherPHolder
Copy link

Absolutely, thanks, will try it out and update the issue.

Are you planing on specifying the number of initial chunks? I ask because of the environmental variable.

We are if not this means we end up with one large chunk.

And when using manual chunks rollup does not take into account circular dependencies which means the strategy you use needs to prevent that.

Ideally we could choose the number of maximum chunks and try to distribute the bundle in the rest as evenly as possible.

@dimeloper
Copy link

@ChristopherPHolder did you manage to try it out? if yes did it work for you?

We are facing the same issue at our application (excessive amount of chunks), and I tried the rollup workaround mentioned in the #27715 issue, however this caused some unexpected side effects to our app and we had to revert it.

@ChristopherPHolder
Copy link

@dimeloper no, not yet but i have a similar implementation in a mono repo filled with enterprise apps, so i know the general solution works.

We are facing the same issue at our application (excessive amount of chunks), and I tried the rollup workaround mentioned in the #27715 issue, however this caused some unexpected side effects to our app and we had to revert it.

When we implemented it, we also faced a bunch of issues, circular deps, broken sourcemaps, invalid import transformations, etc.

What is the issue you are facing? Maybe i got a solution for you? I will also happily publish my solution but since @clydin is working on it internally and that would allow us to handle the build transformation in memory, that seems like a nicer solution

@dimeloper
Copy link

dimeloper commented Jul 9, 2024

@ChristopherPHolder while the esbuild production app runs fine, after running the rollup command to reduce the amount of chunks, we get errors like the following in random places, that prevent specific components from being loaded:

Error: no ngModuleRef constructor found
    at chunk-UKEZH6HP-Djqkv2-u.js:246:4618
    at Generator.next (<anonymous>)
    at n (chunk-UKEZH6HP-Djqkv2-u.js:1:1248)
    at k.invoke (zone.js:368:26)
    at Object.onInvoke (chunk-UKEZH6HP-Djqkv2-u.js:9:52548)
    at k.invoke (zone.js:367:52)
    at se.run (zone.js:130:43)
    at zone.js:1260:36
    at k.invokeTask (zone.js:403:31)
    at Object.onInvokeTask (chunk-UKEZH6HP-Djqkv2-u.js:9:52359)
    at k.invokeTask (zone.js:402:36)
    at se.runTask (zone.js:174:47)
    at E (zone.js:582:35)

@ChristopherPHolder
Copy link

@dimeloper That issue was mostly related to circular deps in out case.

Did you simply run the rollup cli on it? or did you add minChunkSize ?

Unfortunately minChunkSize will not work or at lease did not for us

@dimeloper
Copy link

@ChristopherPHolder thank you for your input. Yes I tried this with minChunkSize since we had to reduce the amount of generated chunks. May I ask how did you made it work without the minChunkSize option?

@dimeloper
Copy link

@clydin I have one question, so today I decided to upgrade our project to 18.1-rc and now I am trying to use the optimisation you introduced without success, even though I set the following environment variable, as per your instructions: NG_BUILD_OPTIMIZE_CHUNKS=1.

We are on an NX project though (version 19.5.0-beta.0), and therefore we use the @nx/angular:application builder. I suppose your change is not available there (yet)?

@dimeloper
Copy link

@clydin not sure if you are still following this issue, today I managed to define the necessary environment variable (btw if anyone is using NX, here is how you can do it), however I'm still getting the same (excessive) amount of chunks (I also debugged the chunk optimizer and went through some breakpoints to make sure it was being called while it was building).

  • Before switching to the application builder: 326 chunks in total
  • Application builder, before enabling the chunk optimizer: 510 chunks in total
  • Application builder, after enabling the chunk optimizer: 510 chunks in total

My guess would be that we would need to inject some rollup parameters to that optimizeChunks method for our case. If you have any further guidance or if you think I'm missing anything, let me know.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Aug 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker target: rc This PR is targeted for the next release-candidate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants