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

disable Terser's "reduce_funcs" option for performance #3000

Merged
merged 2 commits into from
Dec 26, 2024

Conversation

kfule
Copy link
Contributor

@kfule kfule commented Dec 23, 2024

Terser's “reduce_funcs” option seems to degrade performance. So, disable it. This commit will increase file size of "mithril.min.js" slightly, but performance appears to improve.

Description

This PR makes mithril.js and mithril.min.js code equivalent (except mangling) by disabling Terser's “compress” option.
This will increase the file size of “mithirl.min.js” by about 0.01KB (gzipped), but seems to improve performance.
Edit: The code in mithril.js and mithril.min.js is not equivalent because only reduce_funcs is disabled.

results of npm run perf (nodejs, using mithril.min.js)

  • before
construct large vnode tree x 21,998 ops/sec ±0.49% (127 runs sampled)
rerender identical vnode x 3,876,899 ops/sec ±0.47% (122 runs sampled)
rerender same tree x 83,591 ops/sec ±0.19% (126 runs sampled)
add large nested tree x 6,869 ops/sec ±1.55% (122 runs sampled)
mutate styles/properties x 123 ops/sec ±1.29% (91 runs sampled)
repeated add/removal x 3,007 ops/sec ±0.69% (124 runs sampled)
Completed perf tests in 56568ms
  • after (improves "rerender same tree" and "add large nested tree")
construct large vnode tree x 20,641 ops/sec ±0.51% (128 runs sampled)
rerender identical vnode x 4,029,056 ops/sec ±0.56% (129 runs sampled)
rerender same tree x 90,134 ops/sec ±0.25% (125 runs sampled)
add large nested tree x 7,452 ops/sec ±0.84% (123 runs sampled)
mutate styles/properties x 130 ops/sec ±1.41% (93 runs sampled)
repeated add/removal x 3,047 ops/sec ±0.34% (128 runs sampled)
Completed perf tests in 57709ms

Motivation and Context

While measuring performance under various conditions, I noticed the performance was different between "mithril.min.js" and "mithril.js" ("mithril.min.js" seems slower).
Looking into the cause, I found that compressing the code with Terser's “compress” option seemed to affect performance as well as it reduced the amount of code.

I use mithril.min.js as is for prototyping, so I prefer mithril.min.js to be faster.

How Has This Been Tested?

npm run test

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • My change requires a documentation update, and I've opened a pull request to update it already:
  • I have read https://mithril.js.org/contributing.html.

Terser's  “compress” option seems to degrade performance. So, disable it.
This commit will increase file size by about 1%, but performance appears to improve.
@kfule kfule requested a review from a team as a code owner December 23, 2024 15:21
@dead-claudia
Copy link
Member

dead-claudia commented Dec 25, 2024

I'm 90% sure it's related to the fact Terser inlines larger functions by creating IIFEs it doesn't proceed to flatten.

Better would be finding the offending function(s) and either inlining it manually (if it's easy) or marking it with /*@__NOINLINE_*/ (if it's complicated).

This isn't a merge blocker, though.

@@ -42,7 +42,8 @@ async function build() {
return
}
console.log("minifying...")
const minified = Terser.minify(original)
// Terser's “compress” option seems to degrade performance. So, disable it.
const minified = Terser.minify(original, {compress: false, mangle: true})
Copy link
Member

Choose a reason for hiding this comment

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

Could you see if just disabling reduce_funcs helps, and keeping the rest of compression on? terser/terser#1305 among others are related.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried the following setting where only reduce_funcs is false, but the output result seems to be the same as in v2.2.11...

const minified = Terser.minify(original, {compress: {reduce_funcs: false}, mangle: true})

Copy link
Contributor Author

@kfule kfule Dec 26, 2024

Choose a reason for hiding this comment

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

It seems that a newer version of terser works well with reduce_funcs: false and produces output that is both small file size and performance. However, installing a newer version of terser seems to install packages that do not support node v18.

@kfule
Copy link
Contributor Author

kfule commented Dec 26, 2024

@dead-claudia Thank you for your review comments.
In my opinion, I don't want to make changes to the mithril code itself because of terser's behavior.
So I want to improve only terser options. But it seems that the version of terser needs to be upgraded for reduce_funcs to work well, and it may not support node 18...
(It seemed that reduce_funcs, if it worked, could be a good solution for both file size and performance...)

@kfule
Copy link
Contributor Author

kfule commented Dec 26, 2024

@dead-claudia
Very sorry, the node 18 issue was not related to the Terser's upgrade.
So, I upgraded Terser to make reduce_funcs work well. This allowed better performance with little increase in file size (0.01KB gzipped).

@kfule kfule force-pushed the disable-compress-option branch from 19ee8ed to c5f00b7 Compare December 26, 2024 13:39
@kfule kfule changed the title disable Terser's "compress" option for performance disable Terser's "reduce_funcs" option for performance Dec 26, 2024
@kfule kfule requested a review from dead-claudia December 26, 2024 13:46
@dead-claudia dead-claudia merged commit 4ba76ac into MithrilJS:main Dec 26, 2024
7 checks passed
@JAForbes JAForbes mentioned this pull request Dec 26, 2024
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

Successfully merging this pull request may close these issues.

2 participants