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

Fix stripping local debug code so can that dead-code-elimination produces smaller bundles with fewer function calls (part 1) #1606

Merged
merged 9 commits into from
Sep 11, 2024

Conversation

NullVoxPopuli
Copy link
Contributor

@NullVoxPopuli NullVoxPopuli commented Sep 7, 2024

Goals:

  • fix prod build
    • import.meta.env behavior was based on an env var (MODE), which rollup wasn't using
  • inline @glimmer/debug so we can strip away via dead-code-elimination the calls to check(...)
    Turns out, this wasn't needed, and we can keep @glimmer/debug separate -- terser seems to have figured out now that functions from @glimmer/debug are not needed in the consuming packages.

Of note, in ember's build, the output of @glimmer/debug is changed to things like:

function CheckInterface(obj) {
  return isDevelopingApp() ? new PropertyChecker(obj) : new NoopChecker();
}

which is great!

But this keeps the check call in source, unless production mode is smart enough to see that the NoopChecker can be removed.

Maybe we should move the production checks to the check call sites if we determine they remain in production ember apps.


There are a number of flags that are meant to be internal to glimmer-vm and not exposed to ember.js.

There are also flags that are meant to be exposed to ember.js (which are swapped out with DEBUG from '@glimmer/env' during the build)

Output size (using dust)

DevProd
This PR
cd packages/\@glimmer
du --ignore_hidden \
   --reverse --apparent-size \
   --filter ".+\/dist\/dev\/index.js$" \
   --no-percent-bars --only-dir --depth 1

618K └─┬ .
170K   ├── runtime
168K   ├── syntax
104K   ├── compiler
 63K   ├── opcode-compiler
 23K   ├── manager
 19K   ├── validator
 17K   ├── util
 13K   ├── program
8.9K   ├── reference
6.0K   ├── debug
6.0K   ├── destroyable
4.5K   ├── vm
4.1K   ├── node
3.7K   ├── global-context
2.5K   ├── wire-format
966B   ├── encoder
844B   ├── vm-babel-plugins
502B   └── owner

cd packages/\@glimmer
du --ignore_hidden \
   --reverse --apparent-size \
   --filter ".+\/dist\/prod\/index.js$" \
   --no-percent-bars --only-dir --depth 1

258K └─┬ .
 73K   ├── syntax
 70K   ├── runtime
 49K   ├── compiler
 22K   ├── opcode-compiler
7.1K   ├── manager
6.8K   ├── util
5.7K   ├── program
4.1K   ├── validator
3.7K   ├── debug
3.7K   ├── reference
2.8K   ├── vm
2.1K   ├── node
1.7K   ├── destroyable
1.6K   ├── wire-format
563B   ├── global-context
511B   ├── encoder
469B   ├── vm-babel-plugins
155B   └── owner



main
cd packages/\@glimmer
du --ignore_hidden \
   --reverse --apparent-size \
   --filter ".+\/dist\/dev\/index.js$" \
   --no-percent-bars --only-dir --depth 1
   
650K └─┬ .
181K   ├── runtime
162K   ├── syntax
104K   ├── compiler
 63K   ├── opcode-compiler
 29K   ├── debug
 23K   ├── manager
 19K   ├── validator
 17K   ├── util
 13K   ├── program
9.5K   ├── reference
6.2K   ├── destroyable
5.5K   ├── global-context
5.0K   ├── vm
4.2K   ├── node
2.4K   ├── wire-format
967B   ├── encoder
870B   ├── vm-babel-plugins
497B   └── owner
cd packages/\@glimmer
du --ignore_hidden \
   --reverse --apparent-size \
   --filter ".+\/dist\/prod\/index.js$" \
   --no-percent-bars --only-dir --depth 1

301K └─┬ .
 80K   ├── runtime
 74K   ├── syntax
 50K   ├── compiler
 25K   ├── opcode-compiler
 21K   ├── debug
 11K   ├── manager
8.7K   ├── util
7.6K   ├── validator
5.9K   ├── program
4.1K   ├── reference
3.0K   ├── destroyable
2.8K   ├── vm
2.1K   ├── node
1.6K   ├── wire-format
1.4K   ├── global-context
604B   ├── encoder
469B   ├── vm-babel-plugins
155B   └── owner

I applied this branch to ember-source 5.10, (which can be tested here) and came out with these production build sizes:

# 5.10 + this branch
❯ du --no-percent-bars --apparent-size --filter ".js$" dist/assets/

4.4K   ┌── chunk.2772c50f98341aff4d18.js
 98K   ├── chunk.04801e0d37536e3eb752.js
394K   ├── vendor.89b515acd0ef98846b07babf4e0f28a9.js
496K ┌─┴ assets
# 5.10 

❯ du --no-percent-bars --apparent-size --filter ".js$" dist/assets/ 

4.4K   ┌── chunk.39bc453487af3c4b70e2.js
 97K   ├── chunk.0bb4a1b44f780f8fed74.js
411K   ├── vendor.a80a7a73fcea3dc743e6a8ccc8536d9e.js
513K ┌─┴ assets

It is 17K smaller overall.

That's still far from the 52KB production vendor growth reported by emberjs/ember.js#20628


In a future PR, I'd like to switch the build to SWC, because SWC's minifier solves the problem we have:
https://play.swc.rs/?version=1.7.24&code=H4sIAAAAAAAAA12OTQqDMBCF957iIS4iFALJ0ssYdYqCNSEmNKl496at1trd%2B%2FnmMZzjbgdH0BZGzUm0uiP0ZCm7%2Bql1g54QWCixwJLzNrkK69FFFi6IFzz%2BiCo7GNW0TP32yZ1GEiBORNyIjILR1uFLUlA3MxJLbAZwDu2d8Q5zr%2F3YoaFPus3UAgISsq5SvGfFEpgoVxRLZLnI3%2Br1odyVYLlMcTpanwuGSssfAQAA&config=H4sIAAAAAAAAA31VPY%2FbMAzd71cEmjsUGTp0vivQIehQ4FZBsShHV1kyRCqXIPB%2FLy07H5fQ2Sw%2BPlLix%2FPpZbVSH9ion6sTf%2FKhNxkhX85swWMkc2CLomMP2GTfk%2Fp2RglHyJmAUE3DhCgyuQUaWYDr7%2Bv1zFAhJYQzY7Z1Pnp3vM3ZpK7PgHhjYyuHLB1Ewq%2F8GcvpcwQol1v7NqUAJj5BtEHtI0ELWQrcpBBMj6D3JgtRxpua7DFJKUawEFjd59SLeLSefIqc8xG1YKxukgUB8hka8nuQaJyLaRH5ecJ7KmxhW9q29vmODXsTiiEhJxxqS%2Fi2QtRd8kjalSiVcAIXajCBc3Hvmd7pDFRyfOR9JB8XevIPgCsQDGI0HUhxq4fjeVpiu6dMHx2PLB0FnOdbemWElouqvXdCZcfKQCYvdTODLQ2MlW2k68zwQvnQW9DgHM%2BKEBo%2FPTU7Kem46MkJAPfXOGmqJkBftnABHxfiCfyLX0nygM0enaHdMorHbpvCkwQd0C7ZJw7cCkrLcGaVOPTLeIkWeDTAii4FK%2FAoArwAlHSoevkwG7weHFG3IW2vMjE7DBcd7kxs7%2Ff9osWZZc6l3H2VWE67SbaEOgEndU1wUlUf6tfvv%2Fr17V1v%2Fry%2BjWJeo6thGKYEL3MS1dVA19%2FIOEGT%2BP9QV6ezzl%2FuqDxuzsz6rOE%2FQnOQmpIGAAA%3D

image

Terser fails at this:
image

And terser failing at this is one of the reasons we've had so much dev code in prod

@NullVoxPopuli NullVoxPopuli changed the title How do we get the stack-checks removed from the prod build? Fix production stripping in the production bundle Sep 7, 2024
@NullVoxPopuli NullVoxPopuli changed the title Fix production stripping in the production bundle Fix production stripping in the production bundles Sep 7, 2024
Copy link

github-actions bot commented Sep 7, 2024

duration phase no difference [-175ms to 29ms]
renderEnd phase no difference [-1ms to 2ms]
render1000Items1End phase no difference [-18ms to 4ms]
clearItems1End phase no difference [-4ms to 2ms]
render1000Items2End phase no difference [-18ms to 0ms]
clearItems2End phase no difference [0ms to 2ms]
render5000Items1End phase no difference [-58ms to 8ms]
clearManyItems1End phase no difference [-1ms to 2ms]
render5000Items2End phase no difference [-65ms to 1ms]
clearManyItems2End phase no difference [-4ms to 2ms]
render1000Items3End phase no difference [-23ms to 7ms]
append1000Items1End phase no difference [-24ms to 29ms]
append1000Items2End phase no difference [-15ms to 9ms]
updateEvery10thItem1End phase no difference [-4ms to 1ms]
updateEvery10thItem2End phase no difference [-1ms to 0ms]
selectFirstRow1End phase no difference [0ms to 0ms]
selectSecondRow1End phase no difference [0ms to 0ms]
removeFirstRow1End phase no difference [-1ms to 1ms]
removeSecondRow1End phase no difference [0ms to 1ms]
swapRows1End phase no difference [0ms to 1ms]
swapRows2End phase no difference [0ms to 0ms]
clearItems4End phase no difference [-2ms to 1ms]
paint phase no difference [0ms to 0ms]

[16:59:30] Generating Benchmark Reports [started]
[16:59:39] Generating Benchmark Reports [completed]

Benchmark Reports    

JSON: /home/runner/work/glimmer-vm/glimmer-vm/tracerbench-results/compare.json

PDF: /home/runner/work/glimmer-vm/glimmer-vm/tracerbench-results/artifact-1.pdf

HTML: /home/runner/work/glimmer-vm/glimmer-vm/tracerbench-results/artifact-1.html

…do a custom babel plugin..."

This reverts commit 5cddba2b0a4616350ba4d9da572863e77cad0ffe.
…e can inline the package"

This reverts commit 57406f687a7991b8b35c907b1e7483bb40a4d521.
@NullVoxPopuli NullVoxPopuli force-pushed the stack-checks-are-not-removed-in-prod branch from 45ce614 to 19303b5 Compare September 8, 2024 21:55
…uldn't figure out -- I also left some notes about the problem that terser is running in to -- it seems to be related to indirection of identity functions that 'passes' isn't smart enough to figure out

We get big wins (side-wise) from sideEffects: false, but things break.

This babel plugin is feeling more and more brittle, the more we want to
strip.
Copy link
Contributor

@lifeart lifeart left a comment

Choose a reason for hiding this comment

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

Amazing work!

@NullVoxPopuli
Copy link
Contributor Author

image

@NullVoxPopuli NullVoxPopuli merged commit 3768842 into main Sep 11, 2024
6 checks passed
@NullVoxPopuli NullVoxPopuli deleted the stack-checks-are-not-removed-in-prod branch September 11, 2024 15:59
@github-actions github-actions bot mentioned this pull request Sep 11, 2024
@NullVoxPopuli NullVoxPopuli changed the title Fix production stripping in the production bundles Fix stripping local debug code so can that dead-code-elimination produces smaller bundles with fewer function calls (part 1) Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants