# Reducing the size of js\_of\_ocaml output

**URL:** https://discuss.ocaml.org/t/reducing-the-size-of-js-of-ocaml-output/2538
**Category:** Learning
**Created:** [September 10, 2018, 2:23am UTC](https://discuss.ocaml.org/t/reducing-the-size-of-js-of-ocaml-output/2538 "2018-09-10T02:23:56Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![pbiggar](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/pbiggar/32/313_2.png) [@pbiggar](https://discuss.ocaml.org/u/pbiggar)
#### Post date: [September 10, 2018, 2:23am UTC](https://discuss.ocaml.org/t/reducing-the-size-of-js-of-ocaml-output/2538/1 "2018-09-10T02:23:56Z")

</div>

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:

```auto
$ 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))

```

---

<div class="post-metadata">

### Author: ![Yaron\_Minsky](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yaron_minsky/32/11_2.png) [@Yaron\_Minsky](https://discuss.ocaml.org/u/Yaron_Minsky)
#### Post date: [September 10, 2018, 3:23am UTC](https://discuss.ocaml.org/t/reducing-the-size-of-js-of-ocaml-output/2538/2 "2018-09-10T03:23:02Z")

</div>

Have you tried using Base instead of Core\_kernel?

y

---

<div class="post-metadata">

### Author: ![pbiggar](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/pbiggar/32/313_2.png) [@pbiggar](https://discuss.ocaml.org/u/pbiggar)
#### Post date: [September 10, 2018, 3:27am UTC](https://discuss.ocaml.org/t/reducing-the-size-of-js-of-ocaml-output/2538/3 "2018-09-10T03:27:30Z")

</div>

Haven’t tried switching to Base. I thought of it, but given we use quite a few things in Core\_kernel, I’m reluctant to try that one right now.

---

<div class="post-metadata">

### Author: ![emillon](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/emillon/32/1206_2.png) [@emillon](https://discuss.ocaml.org/u/emillon)
#### Post date: [September 10, 2018, 7:03am UTC](https://discuss.ocaml.org/t/reducing-the-size-of-js-of-ocaml-output/2538/4 "2018-09-10T07:03:34Z")

</div>

Hi,

There are some parts that can cause problems in your `jbuild` file:

> ```
> (flags (-warn-error (+A) -opaque))
> 
> ```

`-opaque` will prevent any cross-module optimization, so removing it is likely to improve the situation. Note that recent versions of `dune` will automatically add it in `dev` mode (so that the build is quicker) and omit it in `release` (so that the production binary is more optimized).

> (libraries (… ppx\_deriving\_yojson ppx\_deriving\_yojson.runtime))))

That’s a likely culprit. This will pull `ppx_deriving_yojson` at runtime, including parts of the compiler (`compiler-libs`). You can safely remove `ppx_deriving_yojson` here and `.runtime` is supposed to be added automatically, but in the case of `ppx_deriving_yojson` I think that some parts are not released yet so you might have to keep that part.

Hope that helps!

---

<div class="post-metadata">

### Author: ![darrenldl](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/darrenldl/32/291_2.png) [@darrenldl](https://discuss.ocaml.org/u/darrenldl)
#### Post date: [September 10, 2018, 11:16am UTC](https://discuss.ocaml.org/t/reducing-the-size-of-js-of-ocaml-output/2538/5 "2018-09-10T11:16:57Z")

</div>

I’m gonna ask a likely stupid question, but just in case, are you building with release profile?

---

<div class="post-metadata">

### Author: ![Yaron\_Minsky](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yaron_minsky/32/11_2.png) [@Yaron\_Minsky](https://discuss.ocaml.org/u/Yaron_Minsky)
#### Post date: [September 10, 2018, 11:36am UTC](https://discuss.ocaml.org/t/reducing-the-size-of-js-of-ocaml-output/2538/6 "2018-09-10T11:36:03Z")

</div>

This may be obvious, but for the avoidance of doubt: Base has the most important bits of Core\_kernel included in it. So the key question is whether you’re using things that are in Core\_kernel but not in Base.

---

<div class="post-metadata">

### Author: ![pbiggar](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/pbiggar/32/313_2.png) [@pbiggar](https://discuss.ocaml.org/u/pbiggar)
#### Post date: [September 10, 2018, 4:01pm UTC](https://discuss.ocaml.org/t/reducing-the-size-of-js-of-ocaml-output/2538/7 "2018-09-10T16:01:49Z")

</div>

Yes, and I’m even using it in `--profile release` in dev because it never finishes compiling when I don’t.

---

<div class="post-metadata">

### Author: ![pbiggar](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/pbiggar/32/313_2.png) [@pbiggar](https://discuss.ocaml.org/u/pbiggar)
#### Post date: [September 10, 2018, 4:58pm UTC](https://discuss.ocaml.org/t/reducing-the-size-of-js-of-ocaml-output/2538/8 "2018-09-10T16:58:19Z")

</div>

Yes, this was a big win! It looks like the biggest thing was that I was compiling in ppx\_deriving\_yojson. Removing that dropped 2.5MB -\> 800KB.

I think also this means when I removed derivers earlier, I was actually removing the deriver itself, and not the runtime.

I tried removing opaque and it didnt make a difference to jsoo, but my natively compiled binaries grew slightly (presumably they’ll be faster now, so I’ll leave it).

---

<div class="post-metadata">

### Author: ![pbiggar](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/pbiggar/32/313_2.png) [@pbiggar](https://discuss.ocaml.org/u/pbiggar)
#### Post date: [September 10, 2018, 5:01pm UTC](https://discuss.ocaml.org/t/reducing-the-size-of-js-of-ocaml-output/2538/9 "2018-09-10T17:01:00Z")

</div>

I gave it a quick shot. First thing was String.slice was missing, second thing was that my show derivers complained about Format being missing or deprecated.

I’ve got it down to 800k after the derivers got pulled out, so I’m gonna let gzip handle the rest for now. I’ll give switching to Base a go at some point again – thanks for the suggestion!
