Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

What takes up space in deno? #9243

Closed
lukebrowell opened this issue Jan 23, 2021 · 2 comments
Closed

What takes up space in deno? #9243

lukebrowell opened this issue Jan 23, 2021 · 2 comments

Comments

@lukebrowell
Copy link

Genuine question, want to understand.
Js in WASM (4mb): https://github.com/mbbill/JSC.js
Stand-alone WASM runtime (4mb): https://github.com/bytecodealliance/wasmtime

There’s clearly a heap of functionality missing when comparing JS in a standalone WASM runtime to Deno. My naive question is this, what features make up the difference in binary size? Is it mostly file and network IO?

@lukebrowell lukebrowell changed the title Why is deno so large? What takes up space in deno? Jan 23, 2021
@lucacasonato
Copy link
Member

I think this is a very interesting question:

  1. We use V8, not JSC or quickjs. Why V8? It is by far the most advanced JS runtime out there. It is very fast, has a relatively expansive public API, has a WASM runtime built in, runs on pretty much every platform, has a the "V8 inspector" (used for debugging support, and line coverage), and is always very fast to adopt new ECMA features. V8 is really big (over a million lines of C++). It itself is already 10-15 MB compiled.
  2. We have the typescript compiler written in JS, and SWC, a TS transpiler/bundler written in Rust built in. To make TSC start up quickly we use something called V8 snapshots. These are essentially heap dumps of V8 that can be very quickly re-hydrated to start up a new V8 isolate quickly. SWC is also relatively large (3-5MB in the final executable).
  3. We have many tools like a linter, formatter, and doc generator built in. These and their dependencies add another 5-10 MB to the executable.
  4. The rest of the ~50MB executable is the rest of our Rust runtime code (http client for fetch (reqwest), our event loop (tokio), and various other crates.

The actual bare minimum code required for us to execute JS (without TS support) is 32.7 MB on linux (see denort in filesize benchmark here: https://deno.land/benchmarks#executable-size).

Compared to Node we are doing very well. Node.js is 92.7 MB on Linux (v15.6.0 downloaded from https://nodejs.org/en/), and does not contain a built in linter, formatter, doc generator, coverage tool, typescript compiler and package manager. Just the Deno runtime (without tooling) is about 2.8x smaller than all of Node. Even Deno with all of its built in tooling is still 1.75x smaller than Node.

@nettybun
Copy link

Deno's been growing and I've been trying to distribute as-small-as-possible deno compile executables so thought I'd go poking around. Here's a screenshot of the /benchmarks?all metrics linked above since they aren't very accessible (it takes several minutes and 1.03GB of RAM to load the webpage 🏋)

image

I think it's ICU data and WebGPU? @lucacasonato do you know if that's what the jumps in the graph are from? I found 0cf952e which shows a 10MB ICU data payload.

I read through an article about reducing Rust binary size but learned that Deno has already enabled those size optimizations. So I'll post some findings on stripping the binaries and using cargo bloat utility in case anyone's interested and doesn't want to checkout+build Deno:

~/_/work-theirs/deno on  main [!⇣] via 🦀 v1.50.0
❯ cargo bloat --release --crates
   ...
   ...
   Compiling deno_runtime v0.9.3 (/home/today/_/work-theirs/deno/runtime)
   Compiling deno v1.8.1 (/home/today/_/work-theirs/deno/cli)
    Finished release [optimized] target(s) in 25m 02s
    Analyzing target/release/deno

 File  .text     Size Crate
13.5%  37.3%   9.7MiB rusty_v8
 4.8%  13.2%   3.4MiB [Unknown]
 2.7%   7.4%   1.9MiB std
 1.3%   3.6% 959.4KiB deno_runtime
 1.1%   3.2% 841.0KiB deno_webgpu
 1.1%   2.9% 781.7KiB deno_lint
 1.0%   2.7% 729.0KiB deno_core
 0.7%   2.0% 535.6KiB deno
 0.7%   2.0% 532.3KiB dprint_plugin_typescript
 0.6%   1.7% 454.3KiB serde
 0.6%   1.5% 410.4KiB lspower
 0.5%   1.5% 394.5KiB swc_ecma_transforms_base
 0.5%   1.5% 390.8KiB spirv_cross
 0.5%   1.4% 363.1KiB reqwest
 0.3%   1.0% 257.3KiB swc_ecma_transforms_proposal
 0.3%   1.0% 254.8KiB swc_bundler
 0.3%   0.9% 231.9KiB rustls
 0.3%   0.8% 219.5KiB naga
 0.3%   0.8% 204.5KiB wgpu_core
 0.2%   0.7% 180.7KiB clap
 4.3%  11.9%   3.1MiB And 168 more crates. Use -n N to show more.
36.1% 100.0%  26.0MiB .text section size, the file size is 72.1MiB

Note: numbers above are a result of guesswork. They are not 100% correct and never will be.

~/_/work-theirs/deno on  main [!⇣] via 🦀 v1.50.0 took 25m6s 
❯  

Doesn't tell me much but it looks like V8 is now less than the previously mentioned size of 10-15MB.

Stripping the binaries produces a 38MB executable for Linux, which is great:

73M deno*
54M deno-stripped*
53M denort*
38M denort-stripped*

@denoland denoland locked and limited conversation to collaborators Mar 17, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants