Anyone know what's the minimum size of the compiled JS now? Is there any way Scala.js can produce code as compact as BuckleScript/ReasonML in the future?
I like Scala's syntax but the last time I tried Scala.js, the output was several hundred kb for something slightly more than a Hello World -- it used some List and Seq functions. I'd bet the comparable ReasonML output would likely be in tens of kb (including List and Array functions from Belt).
The bare minimum for a hello world is 6 KB (before gzip). But of course as soon as you start using Scala collections, it's getting bigger. The minimum for a realistic application is 90 KB (before gzip).
That's less than your typical JavaScript framework, so for any realistic application it shouldn't be a concern.
For refernce- Jquery unzipped is similar size- 87K and while it adds much more functionality, Scala collections easily trump jquery's in usability and power.
SJRD, Would you also add a bit more info about how this size increases? I haven't cared much but it seems from your comments that the slope should be much less once you reach 90kb.
ClojureScript ends up somewhere around the same size. Maybe it's some magic number that a full-featured environment converges to.
Since Scala.js (like CLJS) is backed by Google Closure Compiler, I bet you'll also reach for the Closure Library for a lot of stuff where one might reach for JQuery or equivalent otherwise. The stuff in there is of course optimized for Closure Compiler, and slims down quite well.
There is a significant difference between CLJS and Scala.js regarding their use of GCC (Google Closure Compiler).
In ClojureScript, GCC is a user-visible feature of the toolchain, so users are encouraged to use GCC-compatible libraries and the Closure Library in particular.
In Scala.js, GCC is really an implementation detail of the toolchain, and its constraints are completely abstracted away from the user. This does not really encourage using GCC-oriented libraries like the Closure Library.
The two approaches each have pros and cons:
* CLJS' approach allows tree shaking across the CLJS code and the GCC-compatible libraries that are used. However, it makes it more difficult to use libraries that do not comply with GCC's Advanced Optimizations requirements, as one needs to declare the proper `externs` files.
* Scala.js' approach means that you can use any JavaScript library out of the box, whether or not it was designed for GCC, and without having to declare any `externs` file. However, it means that GCC's tree shaking will not be applied across the Scala.js code and the JS libraries. It only applies to Scala.js' own code.
I think the externs file maneuver might be outdated.
Admittedly, I'm using shadow-cljs as my go-to compiler (so I'm not sure what the state of vanilla is), but all I do is yarn add <package>, and then require it in the file where I want to use it, and interact with it as if it were any other library.
Though it is true of shadow-cljs as well that it doesn't try to tree-shake external (non-CLJS/Closure) libs by default, though it will do it for project code and Clojure libraries.
Indeed, once you end up pulling in most common Scala classes (collections, futures, etc.), adding new functionality to your app increases app size by very little. Our app has ~600KB gzipped js (attributable to Scala.js compiled code) + ~200KB of React and other libraries. The overall size has barely moved beyond +-100KB in last few years despite adding new functionality all the time.
Once Scala.js supports lazy loading of modules (hopefully soon after 1.0), the size issue will have significantly less practical impact.
Scala.js is being fed to the Google Closure compiler [1] for minification via tree-shaking, after applying optimizations on its own. Output can be unreadable, but debugging works via source maps.
It's not perfect, but you should not get hundreds of KB for a Hello World. And indeed, the code cannot be as minimal as hand crafted code either.
Note that this is often a false problem, because people often use a lot of JavaScript libraries without any tree-shaking in their build process, so if you do care about tens of KB, then you don't use JQuery, React, etc. A valid use case indeed, I've been there, but not for your typical app.
While i understand your concern, i wouldn't use scala.js in a context where several hundred kb are an issue. I've tried it and it works great, but i think it only pays of if you implemented a complicated web-app with complicated server-side code, e.g. if you replace a desktop-application to manage some system with a web-based one. Something where showing a loading-screen on the first visit is totally reasonable.
> the output was several hundred kb for something slightly more than a Hello World -- it used some List and Seq functions
That's just nonsense, maybe 6 or 7 years ago that could have been the case. There's an approximate 100KB "tax" for pulling in Scala collections (i.e. as soon as you depend on List, Map, Seq, etc.), which is the price to pay for being able to use the power of Scala in the browser.
> Is there any way Scala.js can produce code as compact as BuckleScript/ReasonML in the future?
No, iirc, not without a redeisgn.
There's a longstanding issue wrt lazy loading, which is slated to be worked on at some point post-1.0 -- I'd say that's probably the biggest missing feature, the ability to break out one's app into dynamic chunks, so for example a lightweight frontend/public facing area of an app can be isolated from the backend where all the heavy lifting is done.
Perhaps with Dotty (AKA Scala 3) next year there will be further reductions in Scala.js code size, but no, nothing like BuckleScript.
I made this TailwindCSS Playground over the last two weeks. I really like the core idea of Tailwind and the productivity gains it gives and would like to build more stuff with it in the future!
Features:
* Compile custom @tailwindcss config and CSS in the browser
* Live preview in 5 screen sizes
* Class name autocompletion with CSS definition preview
Adam Wathan (creator of Tailwind CSS) is working on an excellent screencast series about using Tailwind: https://tailwindcss.com/screencasts. I highly recommend watching it.
Wordless, at its core, is just a big set of helper methods, plus a way to compile SASS/Coffeescript without the need to open a terminal, plus the embedded Phampl library to write views. So yes, the theme depends on the plugin, just like any other Wordpress plugin.
It might be faster to write the code, but it's definitely not the fastest way to find the minimum/maximum value. Some simple test cases I wrote show a simple for loop iterator over an array to be 2x faster than Math.min.apply in Firefox 4, and 3x faster in Chrome 10.
If you take out the (currently unused: it is updated but never referred to afterwards) the first-index-of-the-smallest-value-was-found-at variable the difference in FF is even larger.
These are the results on FF 3.6.16 on my desktop:
~33.5 ops/sec (million test, using Array.min.apply)
~57.0 o/s (with index var)
~86.5 o/s (without index var)
I'm a little surprised it makes that much difference (I assumed the two set operations, one of which I removed, would be less significant than that in the execution timings compared to the array object lookup in the comparison, given JS arrays aren't actually arrays strictly speaking). The difference may be less significant (zero, in fact) with a JS engine that does dead-code analysis that successfully works out that min_i is set in the loop but otherwise never used.
I like Scala's syntax but the last time I tried Scala.js, the output was several hundred kb for something slightly more than a Hello World -- it used some List and Seq functions. I'd bet the comparable ReasonML output would likely be in tens of kb (including List and Array functions from Belt).