Hacker News new | ask | show | jobs
by schneidmaster 2181 days ago
Rails 6 by default includes webpack to bundle assets for production. Aside from webpack, several of the top 10 on your list are libraries that ensure a great user & developer experience across browsers:

- babel transpiles ES6/7+ JavaScript syntax to the least-common-denominator of the browsers you designate as supported by your application

- core-js provides implementations of features that are not supported in older browsers -- things like array methods that cannot simply be transpiled

- caniuse-lite is a database of supported browser features to determine what needs to be transpiled and when

This toolchain allows developers to write code with the latest language features (which usually results in simpler, more elegant code) while seamlessly supporting legacy browsers as needed. If you decide to drop support for an older browser, you can simply remove it from your browserslist instead of going through all your code to figure out which hacks you put in just for that browser. It takes a ton of cycles out of development googling "can I use feature X in browser Y".

Prior to Rails 6, asset precompilation was powered by Sprockets by default. Sprockets still bundled many analogous libraries, just hidden in ruby gems instead of node_modules. For example, if you want to use SASS then you need a library that compiles SASS to CSS -- whether it's node-sass on your list or the sassc gem.

As noted in other comments, very little of this code is actually loaded in the frontend by end users.

3 comments

Regardless of whether you think all those components are necessary, there is still the question of whether the amount of space they require is justified; JavaScript is a high-level language, and in fact one of the higher-level ones in comparison to things like C/C++. 1KB of JS should be able to do far more than 1KB of C or even binary.

Thus, 100MB of JS is astoundingly huge. It's roughly the same size as all the binaries in a full install of Windows 95, with all its features and drivers.

In the spirit of https://prog21.dadgum.com/116.html perhaps we need a list of "Things an empty Rails app is smaller than".

It takes a ton of cycles out of development googling "can I use feature X in browser Y".

...or you could just avoid the trendchasing and use a minimal subset that you are sure will work everywhere, but that's a different discussion.

"1KB of JS should be able to do far more than 1KB of C or even binary"

This doesn't make sense and isn't a relevant comparison.

I completely disagree with the premise that a high-level language should be able to do substantially more work with the same amount of code as C. That is not the point of a high-level language, not even close. The point of a high-level language is simply to abstract away some of the more difficult problems inherent to programming closer to the metal.

And as far as languages go, JavaScript is not nearly so far removed from raw machine code as most interpreted languages.

100MB of JavaScript code is not “astoundingly huge” at all , considering the bulk of that is tooling. Compared to the tooling for many other commonly used C/C++ development environments, 100MB is pretty modest.

At $50 for a 1TB hard drive, that 100MB is costing you half a cent. It doesn’t get sent to users over the network so it doesn’t affect performance. Why does that matter again?
106MB of source code is perhaps five million lines of code, if written in a typical way. Some people use longer lines, not so many "{" lines, but anyway.

Storing five million lines of code is cheap, sure, no question. But don't you feel curious about how why you need that much code in the first place?

This comparison done by Google is really helpful at understanding all the work that Webpack (and related tools) do: https://bundlers.tooling.report/ .

Click through each test and read through some of the descriptions. They do a lot of advanced techniques that are important for web performance.

Those optimizations are another big part of why modern Javascript build tools are so complicated. There's no other language where we care nearly as much about optimizing for code delivery. On the web, a frontend app should (hopefully) be around 100k of Javascript bytes, and it should have good caching and CDN behavior. Compared to other platforms where 10mb to 100mb binaries are considered just fine.

Thank you for the well thought out answer. This is why I asked.

This was brought to my attention working on a new project. This is the first time I've done rails 6 on heroku. Heroku out of the box with this app gives me a ~360mb buildpack; this exceeds their soft limit of 300mb. Historically not been an issue for me but I guess now with webpack, I need to customize the buildpack to cleanup the node_modules after compilation.

No problem! FYI there may be something else bloating your slug. With the ruby buildpack, heroku by default will install node_modules to a shared cache directory and not include them in the slug artifact. For example I have a Rails app that has 250MB of node_modules locally but my slug on Heroku is only 93.4MB.
Good to know, Ill keep digging on the heroku side.
Actually, I guess I was wrong about node_modules not being included in the slug -- it's just that the slug is compressed so node_modules don't take up anything close to their stat size. One common gotcha is that if you have large non-code files in your git repo (binaries/images/gzips/etc), those will end up in your slug and they don't compress well so they'll add a lot of bloat. If that's the case you can use a .slugignore file[0] to tell Heroku to exclude them. Good luck!

[0]: https://devcenter.heroku.com/articles/slug-compiler#ignoring...