8000 Reapply object tree-shaking by lukastaegert · Pull Request #5737 · rollup/rollup · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Reapply object tree-shaking #5737

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

Merged
merged 37 commits into from
Feb 1, 2025
Merged

Conversation

lukastaegert
Copy link
Member
@lukastaegert lukastaegert commented Nov 18, 2024

This reverts commit 10bc150.

This PR contains:

  • bugfix
  • feature
  • refactor
  • documentation
  • other

Are tests included?

  • yes (bugfixes and features will not be merged without tests)
  • no

Breaking Changes?

  • yes (breaking changes will not be merged unless absolutely necessary)
  • no

List any relevant issue numbers:

Description

This re-applies #5420 when we have fixes for #5733, #5734, #5735, #5480 (comment) and some improvement for #5729

Copy link
vercel bot commented Nov 18, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
rollup ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 1, 2025 7:07am

@lukastaegert lukastaegert marked this pull request as draft November 18, 2024 16:04
Copy link
github-actions bot commented Nov 18, 2024

Thank you for your contribution! ❤️

You can try out this pull request locally by installing Rollup via

npm install rollup/rollup#object-property-treeshaking

Notice: Ensure you have installed the latest stable Rust toolchain. If you haven't installed it yet, please see https://www.rust-lang.org/tools/install to learn how to download Rustup and install Rust.

or load it into the REPL:
https://rollup-oma6i1jqy-rollup-js.vercel.app/repl/?pr=5737

Copy link
github-actions bot commented Nov 18, 2024

Performance report

  • BUILD: 7156ms (-378ms, -5.0%), 743 MB
    • initialize: 0ms, 27.7 MB
    • generate module graph: 2796ms, 559 MB
      • generate ast: 1282ms, 552 MB
    • sort and bind modules: 406ms, 601 MB (+2%)
    • mark included statements: 3948ms (-382ms, -8.8%), 743 MB
      • treeshaking pass 1: 2348ms (+955ms, +68.6%), 743 MB (+7%)
      • treeshaking pass 2: 449ms (-223ms, -33.2%), 753 MB (+4%)
      • treeshaking pass 3: 383ms (+102ms, +36.4%), 744 MB (+3%)
      • treeshaking pass 4: 373ms (+109ms, +41.1%), 744 MB (+3%)
      • treeshaking pass 5: 367ms (+59ms, +19.1%), 743 MB (+2%)
      • treeshaking pass 6: 253ms, 729 MB, removed stage
      • treeshaking pass 7: 238ms, 728 MB, removed stage
      • treeshaking pass 8: 230ms, 734 MB, removed stage
      • treeshaking pass 9: 214ms, 730 MB, removed stage
      • treeshaking pass 10: 214ms, 729 MB, removed stage
      • treeshaking pass 11: 211ms, 734 MB, removed stage
  • GENERATE: 735ms, 987 MB
    • initialize render: 0ms, 883 MB
    • generate chunks: 74ms, 894 MB (+2%)
      • optimize chunks: 0ms, 892 MB
    • render chunks: 642ms, 964 MB
    • transform chunks: 16ms, 987 MB
    • generate bundle: 0ms, 987 MB

Copy link
codecov bot commented Nov 18, 2024

Codecov Report

Attention: Patch coverage is 97.13467% with 20 lines in your changes missing coverage. Please review.

Project coverage is 98.54%. Comparing base (494483e) to head (2158b6b).
Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/ast/nodes/MemberExpression.ts 90.47% 4 Missing ⚠️
src/ast/nodes/ExportDefaultDeclaration.ts 71.42% 2 Missing ⚠️
src/ast/nodes/RestElement.ts 81.81% 0 Missing and 2 partials ⚠️
src/ast/nodes/shared/Node.ts 81.81% 2 Missing ⚠️
src/ast/nodes/ArrayPattern.ts 95.00% 0 Missing and 1 partial ⚠️
src/ast/nodes/JSXExpressionContainer.ts 66.66% 1 Missing ⚠️
src/ast/nodes/JSXIdentifier.ts 85.71% 1 Missing ⚠️
src/ast/nodes/JSXMemberExpression.ts 80.00% 1 Missing ⚠️
src/ast/nodes/JSXOpeningFragment.ts 85.71% 1 Missing ⚠️
src/ast/nodes/MetaProperty.ts 85.71% 1 Missing ⚠️
... and 4 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5737      +/-   ##
==========================================
- Coverage   98.79%   98.54%   -0.25%     
==========================================
  Files         260      269       +9     
  Lines        8123     8527     +404     
  Branches     1373     1460      +87     
==========================================
+ Hits         8025     8403     +378     
- Misses         72       92      +20     
- Partials       26       32       +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@lukastaegert
Copy link
Member Author

I added a fix for #5735. What I found is that for MemberExpressions, we dynamically determine the value of computed properties not only when determining their "literal value" or their "return value", but also when deciding what to include or deoptimize. For the latter two cases, we do not have a mechanism to handle the case where we discover that the property value is reassigned later, which is also the case when a function is called more than once with different values.
I solved this by using a much more conservative strategy in those cases that only relies on static or literal property values that can never change.

@lukastaegert
Copy link
Member Author

I added another fix for #5739. There was indeed a severe issue here: If the first call to a function with rest arguments did not supply any parameter value that would make it into the rest argument, then the logic would wrongly assume the value to be undefined as an exception for rest parameters was missing in this part of the logic.

@TrickyPi
Copy link
Member
TrickyPi commented Dec 8, 2024

👍 Awesome! The "Maximum call stack size exceeded" error is fixed in commit 40e2447!

@lukastaegert
Copy link
Member Author
lukastaegert commented Dec 8, 2024

But it is noticeably slower now. So this is what the problem was: Because we replaced include with includePath and called the latter directly on the initializers of included variables (to include the necessary paths), we eagerly included much more in the bundle in the first run. This is why the logic needed much fewer runs for the same result. However, this resulted in extremely deep recursions. Technically, a single "includePath" could step through the entire code base sequentially before returning. And this without any infinite recursions happening, just on normal operations. What I did is that I separated includePath into include, which would happen on each pass, and includePath, which would only include paths that are actually needed. These path inclusions would happen in includeNode, which is something only happening the very first time a node is included. Thus as includePath is no longer including everything but just what is relevant to include a given path, this breaks the long recursions.
Now let's see if this can be speeded up. The main issue is that we are now back to the original number of passes, but each pass is a little slower...
I have some ideas what we can try, let's see, how much is possible without doing another major refactoring.

Copy link

This PR has been released as part of rollup@4.31.0-0. Note that this is a pre-release, so to test it, you need to install Rollup via npm install rollup@4.31.0-0 or npm install rollup@beta. It will likely become part of a regular release later.

# Conflicts:
#	browser/package.json
#	package-lock.json
#	package.json
This is a massive performance improvement especially in scenarios with recursive
calls where different properties of a function argument are passed to the same
function.
This should save some memory which is rarely needed.
Copy link

This PR has been released as part of rollup@4.33.0-0. Note that this is a pre-release, so to test it, you need to install Rollup via npm install rollup@4.33.0-0 or npm install rollup@beta. It will likely become part of a regular release later.

# Conflicts:
#	browser/package.json
#	package-lock.json
#	package.json
#	test/form/samples/pure-comment-scenarios-complex/_expected.js
@lukastaegert lukastaegert marked this pull request as ready for review February 1, 2025 07:07
@lukastaegert lukastaegert merged commit d7062ef into master Feb 1, 2025
39 of 41 checks passed
@lukastaegert lukastaegert deleted the object-property-treeshaking branch February 1, 2025 08:17
Copy link
github-actions bot commented Feb 1, 2025

This PR has been released as part of rollup@4.34.0. You can test it via npm install rollup.

@printfn
Copy link
printfn commented Feb 2, 2025

I believe this has just broken my build, I'm getting errors with rollup 4.34. My application uses webassembly (https://github.com/bytecodealliance/jco and the wasi-p2 shim), triggering an exception "TypeError: invalid variant tag value undefined (received [object Object]) specified for StreamError".

I can try and make a minimal reproduction and open an issue for this later.

@lukastaegert
Copy link
Member Author

Thank you to the quick reproduction. Let me know if rollup@4.34.1 will resolve this issue.

@dgreensp
Copy link

I'm not sure if I should report this as a bug, but, it seems function properties are treated specially, and using any function property retains all of them? Even if they don't use this or are arrow functions? Is that intentional?

const obj = {
  x: 1,
  y: () => {},
  z: () => {}
};

console.log(obj.x); // only retains x
console.log(obj.y()); // retains both y and z

@dgreensp
Copy link

And I would love to see this extended to assigned properties, as in:

function foo() {}
foo.bar = function() {}
foo.baz = function() {}

console.log(foo.bar()); // only retains bar

@lukastaegert
Copy link
Member Author

At the moment, the property tree-shaking logic is quite conservative and, as you see, does not include properties that are added later. One big complexity comes from the fact that any assignment could trigger a setter that again modifies the entire object (admittedly, this also applies to getters...). Also, a method call can modify the object via this. I assume the issues come from some deoptimizations in this area. We plan on adding further optimizations, but at the moment we focus on making sure that no bugs crept in.

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