Compiled code size and performance: Js.Array or Belt.Array; native or standard library?


#1

I use ReasonML for my pet-project (educational so far). I have chosen ReasonML over JavaScript for its strong, static type system, and simple JS interop.

So, my code is supposed to be:
(1) compiled to JavaScript,
(2) used mainly from JavaScript (both Node and browsers).

So far, I’ve been using Js.Array, mainly since they are translated directly to JS native arrays.

In general, I’m concerned with two different long-term problems of the compiled JS code: size of the code, and its performance. I think the size is much more important (when it comes to performance, it is JavaScript, not OCaml nor C…).

What should be used? Js.Array? Or rather Belt.Array?
(With the mentioned problems in mind.)


#2

I don’t think there’s a straightforward answer to that (or rather, the answer is: it depends).

Belt.Array functions are mostly thin wrappers on top of native JS functions. If you’re concerned about compiled JS code size, Belt.Array is fairly small, but it relies on other BuckleScript modules for features like currying.

Js.Array, by contrast, is just a binding to the existing JS API. It compiles to pure JS array methods with no dependencies or additional runtime cost.

From reading that, it probably sounds like Js.Array is superior. But there are other factors to consider. For example: If your project is nontrivial, then you’re probably using the same BuckleScript modules that Belt.Array relies on anyway. Belt.Array also has functions that aren’t in Js.Array. Js.Array lacks the ability to “safely” get a value, which gives up one of the main benefits of using Reason the first place.

(Reason code like arr[1] does not compile to JS arr[1]. It compiles to an OCaml function that will throw an exception if the item doesn’t exist. See more examples here.)

Belt.Array largely exists to provide an API that’s consistent with the rest of Belt. If you’re using other Belt modules, then it will fit in much easier with the rest of your code.

As with everything performance related, what’s best for your project will depend on a lot of factors. It’s possible that you may be better off using a different data type, like a list (or even a map or a hashmap).

Finally, here’s some anecdotal bundle size data: In my personal project that uses ReasonReact, Belt.Array is 2.42KB (0.6% total bundle size), and bs-platform is 35.37KB (8.5% total bundle size).

For me, the bundle size and runtime cost is so small that choosing one API or the other is just a matter of personal taste. :grin: