Jsoo, production use and user facing applications questions

Beware of functors. They are evaluated at runtime, and thus cannot be optimized by the js_of_ocaml compiler (flambda does not trigger in the bytecode process)

I think that all the expressions declared in your Browser module are copyied verbatim into the generated code, regardless of whether they are actually used or not.

1 Like

Thanks. This is a very interesting hint. I am using functors extensively, because they are an excellent language feature which allows for welldefined abstractions.

If I understand you correctly, every module which is used to instantiate a parameter in a functor module is treated like a c++ object with a vtable. The compiler is not able to shrink the vtable to its actually used size in the byte code and therefore jsoo cannot remove the unused functions. Does this correctly reflect what you are saying?

Does the same problem exist if I compile to native code (i.e. without jsoo)? Or can the compiler optimize the generated code to remove unused functions in modules which are used as parameters?

I think this should be fairly standard as long as I don’t user first class modules. With first class modules it is clear that the compiler cannot remove unused code, because the parameter module is not known until runtime.

It is a pity that jsoo cannot remove unused functions in parameter modules. For me this means that all my code which I want to use in the browser will have a lot of unused functions in it.

Do you know a way to avoid this problem without giving up the abstraction power of functors?

Regards
Helmut

4 Likes

I have made some experiments with code sizes and found the grave error I have made.

I have compiled my libraries with

(libraries
   js_of_ocaml
   js_of_ocaml-ppx       ; <-- grave error, inclusion of the library not necessary
)
(preprocess
    (pps js_of_ocaml-ppx) ; <-- only preprocessing necessary
)

The inclusion of the library js_of_ocaml-ppx causes an explosion of the code size even of the simplest hello world example.

Regards
Helmut

7 Likes

Oh, nice ! This was my first intuition when I told you the two main causes which cause compiled code > 20Mb.

Now you can enjoy the power of js_of_ocaml !

1 Like

Yes, you have mentioned the problem exactly in your first response. Unfortunately I did not connect it to my case, because the dependency was hidden within my virtual dom library.

Therefore instead of reading your post carefully I had to find it out through experiments :wink:

This is one area where bucklescript excel (or used to) and there is no replacement for it right now. I don’t think that anything over 1 MB is acceptable for any web application

2 Likes

To make sure to not link certain libraries by mistake you can now use (forbidden_libraries ...) in dune. It should help to figure out if it happens and what is bringing it in.

10 Likes

I find that using esbuild can help minify the js output a bit and you don’t need any setup for that:

npx esbuild main.js --minify > out.js

The resulting file is still not small (444KB for the ocaml-vdom counters example) but it’s better than 3MB at least.

UPDATE: With --profile release the output got quite a bit smaller: 642K for the compiled js and 122K for the minified.

5 Likes

Doing the same experiment, I get 107k for the “counters” example for both the jsoo and esbuild output.

To be more precise, esbuild bring the size down by 157bytes
108744 → 108587

1 Like

You’re right, I get the same results now,

I still got (js_of_ocaml (flags --no-inline --disable share --pretty)) as flags in my dune file and I thought that using --profile release would ignore those, but that’s not correct.

Once the jsoo dev community starts writing articles like How should we set up apps for HMR now that Fast Refresh replaces react-hot-loader? ¡ Issue #16604 ¡ facebook/react ¡ GitHub, as well as describing how to integrate with the various css approaches including the css-in-js libraries, and there is a well documented guide to avoiding large bundle pitfalls, I would consider it on the short list when starting new front end projects.

1 Like