Further improving the footprint
LLRT already has features that other runtimes do not have, but we believe that we need to further refine them, even if we have to forego some compatibility.
To further improve the small footprint, one of the features of this product, we are considering the following:
- llrt_fetch: Keep http2 support as a crate, but default LLRT to http1 only (this will prevent the
h2crate from being included) - llrt_fetch: By adopting
rustls-platform-verifierinstead ofwebkpi-roots, certificates are not stored internally. See also https://github.com/awslabs/llrt/issues/768#issuecomment-2930897137 - llrt_fetch/llrt_zlib: The crate will retain brotli functionality, but will not use it as an LLRT. I think it won't be a problem as long as it supports zstd, which is used for other purposes and is indispensable, and gzip, which is still widely used. https://w3techs.com/technologies/details/ce-compression
- llrt_os: We'll put all the functions the
sysinfocrate needs behind the feature flags and change the default to off. - llrt_crypto: Organizing crates required for subtleCrypto (this requires improvements to the crate it uses).
Is there anything else you can think of?
For reference:
% cargo bloat --profile=flame --crates
File .text Size Crate
13.6% 20.8% 1.4MiB rquickjs_core
11.1% 16.9% 1.2MiB [Unknown]
7.4% 11.2% 795.0KiB std
3.3% 5.0% 353.6KiB h2
3.1% 4.8% 339.6KiB llrt_stream_web
2.4% 3.7% 260.3KiB rustls
2.0% 3.1% 217.7KiB zstd_sys
1.7% 2.7% 188.9KiB tokio
1.4% 2.1% 147.9KiB ring
1.3% 2.0% 141.0KiB llrt_crypto
1.2% 1.8% 124.7KiB hyper
1.1% 1.7% 117.0KiB llrt_core
1.0% 1.6% 112.9KiB hyper_util
0.9% 1.4% 100.7KiB rquickjs_sys
0.9% 1.3% 92.0KiB brotlic_sys
0.8% 1.2% 83.6KiB llrt
0.6% 1.0% 67.3KiB num_bigint_dig
0.6% 0.9% 66.8KiB primeorder
0.6% 0.9% 63.2KiB llrt_utils
0.6% 0.9% 61.0KiB http
10.2% 15.6% 1.1MiB And 120 more crates. Use -n N to show more.
65.4% 100.0% 6.9MiB .text section size, the file size is 10.5MiB
I'm not sure if there is a definite target size, such as within 10MB?, but judging from the bloat results, there is little room for optimization.
Yes. I don't expect any dramatic improvements, such as cutting the footprint in half. There are also no target values. The idea is that features that are not high priority can be omitted.
I'm interested in the image you presented. For example, if we could remove the h2 crate, would that lead to roughly a 10% reduction overall?
NOTE: I would be grateful if you could tell me how to output this image. I would love to try it myself. :)
I'm interested in the image you presented. For example, if we could remove the h2 crate, would that lead to roughly a 10% reduction overall?
I'm not sure, since size optimization often depends on dependencies. For example, phf is a dependency of rquickjs-core, so simply removing it from llrt won't necessarily reduce the final binary size.
NOTE: I would be grateful if you could tell me how to output this image. I would love to try it myself. :)
This is a tool https://github.com/ahaoboy/bloaty-metafile I previously used to analyze the size of llrt modules. Feel free to follow the instructions in the README to try it out. If you run into any issues, you're welcome to open an issue.
@ahaoboy Thank you! It worked fine on my device. I think it would be a good idea to improve the README.md file a bit. I'll do a PR on another occasion.
This is cool! I think one target will be using openssl instead of all the rust based crypto we currently have and allow dynamic linking to it.
I wonder if it's possible to do treeshaking of the rust deps themselves (compression, crypto, stream, http, etc) when running llrt compile index.mjs --executable.
When the index.mjs is export const handler = () => {};, it compiles into an executable that's 11_138_495 bytes.