I finished compiling our app with js_of_ocaml, and now would like to reduce the size of its output significantly. The output is currently 3.2MB, and I managed to reduce it to 2.4MB, but now i’m stuck.
The main things I’ve already done:
- removed a lot of the ppx_derivers, especially ppx_bin_prot, which saved about 800KB (derivers like show, eq, compare, sexp, etc, saved about 20kb each after I removed them).
-
--setenv FORCE_DROP_INLINE_TEST=true
(saved about 170k) - removed any runtime js files I could
Here’s things I tried which didn’t make much difference:
- using
--opt 3
(maybe 10KB difference) -
--disable debugger
: no difference -
(link_flags (-linkall))
: made it a little bit bigger - tried running ocamlclean on the bytecode, but it didnt work (we’re using ocaml 4.07, and got the error “Error: invalid bytecode file (magic string does not match)”)
-
--no-inline
: made it 300k bigger, unsurprisingly
Has anyone got advice on how to approach this?
PS: There are our dune files, using dune 1.1.1:
$ cat bin/jbuild # this is the entry point
(executable
((name darkjs)
(public_name darkjs)
(modules darkjs)
(flags (-no-check-prims))
(js_of_ocaml
((flags (+nat.js
+dynlink.js
--opt=3
--disable=debugger))))
(libraries (js_of_ocaml libfrontend))
(preprocess (pps (js_of_ocaml-ppx)))
(package dark)))
$ cat libcommon/jbuild
(jbuild_version 1)
(library
((name libcommon)
(flags (-warn-error (+A)))
(libraries (core_kernel libtarget))))
$ cat /libfrontend/jbuild
(jbuild_version 1)
(library
((name libfrontend)
(flags (-warn-error (+A)))
(preprocess (pps (
ppx_deriving_yojson
ppx_pipebang)))
(libraries (libtarget_js libexecution))))
$ cat server/libexecution/jbuild # this is where most of the source code is
(jbuild_version 1)
(library
((name libexecution)
(flags (-warn-error (+A) -opaque))
(preprocess (pps (
ppx_compare
ppx_deriving_yojson
ppx_pipebang)))
(libraries (
; note that libtarget.{ocaml,js} are not included here
libtarget
libcommon
core_kernel
uuidm
base64
ppx_deriving_yojson
ppx_deriving_yojson.runtime))))
$ cat libtarget/jbuild # empty lib
(library
((name libtarget)
(public_name libtarget)
(wrapped false)
(flags (:standard -no-keep-locs -opaque))
(libraries (core_kernel))
(modules_without_implementation (libtarget))))
$ cat libtarget.js/jbuild
(jbuild_version 1)
(library
((name libtarget_js)
(wrapped false)
(libraries (core_kernel js_of_ocaml))
(flags (-warn-error (+A) -no-keep-locs))
(js_of_ocaml
((flags (+nat.js
--opt=3
+core_kernel/runtime.js
--setenv FORCE_DROP_INLINE_TEST=true
--disable=debugger
--runtime-only))
(javascript_files (libtarget.js))))))
(rule (copy# ${lib:libtarget:libtarget.mli} libtarget.mli))