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

Strategies to keep the runtime light? #772

Open
s-h-a-d-o-w opened this issue Jan 6, 2025 · 5 comments
Open

Strategies to keep the runtime light? #772

s-h-a-d-o-w opened this issue Jan 6, 2025 · 5 comments

Comments

@s-h-a-d-o-w
Copy link
Contributor

I don't know how much Node's (or llrt's - I mention Node because obviously, one stumbles across this when looking for a lightweight alternative) size has increased due to including features that maybe could've been released separately but I found it concerning that you're also e.g. including a test runner already.

Are there plans to either release runtimes that are to be used for production only and don't contain things like said test runner and possibly other features only needed during development? Or maybe the ability to create custom runtimes that don't include them? Or does the footprint of the engine make up so much of the runtime that anything that could be reasonably excluded is negligible?

@richarddavison
Copy link
Contributor

Hey @s-h-a-d-o-w. Thanks for that comment. Keeping the runtime light has always been a top priority for LLRT. It's crucial that we keep things as tight as possible to reduce both memory footprint and improve startup times. A lot of effort has been put into keeping things as slim as possible. One example of this is that we only support a low number of encodings, and try to opt out of dependencies adding to much we don't need. Another one is that we pack the entire executable in a zstd compressed self-extracting executable to improve startup and reduce size on Lambda. Rust does a pretty good job of removing unwanted stuff at compile time using DCE (dead code elimination), LTO (link time optimization) and minification. However there is a always a constant balance between features, size and performance.

As we also prioritize performance we unfortunately put on some weight. For example we use opt-level 3 (or -O3) when compiling release binaries which causes some monomorphization, loop unrolling and a lot of function inlining. All these increases performance but significantly increases size as well.

The engine itself, quickjs-ng, weights in about 1mb. On top of that there are a lot of things that are quite bulky in Rust projects we can't get away from. I'll attaching a list of biggest size contributors F.Y.I:
llrt-bloat.txt

As you can see there are many things that add size other than the engine such as Rust standard library, Tokio asynchronous runtime, tls/certificates/encryption (ring, rustls, webpki), certificates, compression algorithms (zstd, brotli, deflate), http client and protocols (hyper, h2) etc.

As the current strategy of LLRT is to be WinterCG there are still a few things missing (webstreams etc). We have tought about somehow modularizing even further by building shared libraries for each LLRT module and load them at runtime. Users can then just remove the shared libraries they don't want and the core will be 10x smaller. The tricky part with that is it requires a lot of effort and Rust doesn't have a stable ABI so introduces a whole heap of problems and is not being considered at the moment.

That being said with this new modular approach you can build your own runtime "just" including what you need. Most of the runtime components is moved to separate crates.

@richarddavison richarddavison pinned this issue Jan 8, 2025
@s-h-a-d-o-w
Copy link
Contributor Author

Unfortunate that modularity isn't feasible but thanks a lot for this thorough explanation!

@richarddavison
Copy link
Contributor

@s-h-a-d-o-w forgot to mention that test runner + repl + compiler are not included in the lambda built variants. Similarly the embedded AWS SDK is also excluded in the -no-sdk build flavors

@s-h-a-d-o-w
Copy link
Contributor Author

Oh so there are some different versions already, that's great!
(I've not seen that in the releases because I'm waiting at least for fs support. My use case would be pretty niche and of no business value - being able to ship JS-based desktop apps that are reasonably lean.)

@ahaoboy
Copy link
Contributor

ahaoboy commented Jan 15, 2025

https://github.com/ahaoboy/rquickjs-llrt-demo

If you are looking for a lite version of llrt, then you can refer to this demo, llrt has separated a lot of common modules, so in other rquickjs project to use, if only the fs, path and other modules, then only need about 1-2mb

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

No branches or pull requests

3 participants