ClojureScript

Optimize cljs.core dump

Details

  • Type: Enhancement Enhancement
  • Status: Open Open
  • Priority: Minor Minor
  • Resolution: Unresolved
  • Affects Version/s: 1.7.228
  • Fix Version/s: None
  • Component/s: None
  • Labels:
  • Patch:
    Code

Description

When building cljs source that uses cljs.js namespace the final js file is quite huge: 6.4M. As described in wiki: https://github.com/clojure/clojurescript/wiki/Optional-Self-hosting it mostly consists of analysis cache of the cljs.core namespace. As a workaround, the wiki article suggests dumping cache to a separate file and load it at runtime instead of bundling in js binary. I think it is possible to have something in between that doesn't require additional efforts from a user and also optimizes the size of the js file. The idea that instead of dumping cache as raw clojure data-structure it is serialized to string. This way compiler won't compile cache into js (which adds a lot of code) and leave it a string. At runtime, this string will be parsed back to clojure using tools.reader.

Here is the proposal: https://gist.github.com/nbeloglazov/0bf163fb62fa4b61d446

Checking locally it reduces the size of js file from 6.4M to 2.7M which I think quite good. The downside is that now js has to do more work on runtime (parse huge string) when today it simply read js code and evaluates it. But I don't think if it's a big concern. If it is desired to keep all behavior a new option can be added for :dump-core compiler setting, something like :dump-core :string that enables string serialization of the cache.

Does it sound reasonable?

  1. CLJS-1601.patch
    29/Mar/16 12:16 AM
    2 kB
    Nikita Beloglazov
  2. CLJS-1601.patch
    27/Mar/16 8:54 PM
    2 kB
    Nikita Beloglazov

Activity

Hide
Nikita Beloglazov added a comment -

Attaching suggested fix. Analysis cache is serialized to string and read back to clojure datastructure when cljs.js is initialized.

Show
Nikita Beloglazov added a comment - Attaching suggested fix. Analysis cache is serialized to string and read back to clojure datastructure when cljs.js is initialized.
Hide
David Nolen added a comment -

Please change the patch so this optional as you've suggested.

Show
David Nolen added a comment - Please change the patch so this optional as you've suggested.
Hide
David Nolen added a comment -

Also have you submitted your Clojure CA yet?

Show
David Nolen added a comment - Also have you submitted your Clojure CA yet?
Hide
Nikita Beloglazov added a comment -

Will do. Yes, I've submitted CA. I used my official name, Mikita Belahlazau there.

Show
Nikita Beloglazov added a comment - Will do. Yes, I've submitted CA. I used my official name, Mikita Belahlazau there.
Hide
Nikita Beloglazov added a comment -

Updated patch that adds option to serialize core analysis cache as string. Possible values of :dump-core are :raw, :string, :none. Old true/false values supported for backward compatibility.

As for default, current patch uses :raw, but I think it makes more sense to use :string. Saving extra few mb of final js is quite good. I think most devs won't go deep into figuring out why js is big and just leave it as it is. Additional one-time parsing performance hit :string introduces acceptable: when :string is used, page loads in 1s while with :raw the time is ~800ms.

Show
Nikita Beloglazov added a comment - Updated patch that adds option to serialize core analysis cache as string. Possible values of :dump-core are :raw, :string, :none. Old true/false values supported for backward compatibility. As for default, current patch uses :raw, but I think it makes more sense to use :string. Saving extra few mb of final js is quite good. I think most devs won't go deep into figuring out why js is big and just leave it as it is. Additional one-time parsing performance hit :string introduces acceptable: when :string is used, page loads in 1s while with :raw the time is ~800ms.
Hide
David Nolen added a comment - - edited

I'm questioning whether this actual valuable? It seems to me if you're serious about code size you would just use Transit and them load the analysis asynchronously?

Show
David Nolen added a comment - - edited I'm questioning whether this actual valuable? It seems to me if you're serious about code size you would just use Transit and them load the analysis asynchronously?
Hide
Nikita Beloglazov added a comment -

Yes, if size is critical then there are better ways to hand-tune the way of loading analysis. At the same time having 3m vs 6m file for local/simple development is a nice win. The only downside is speed, but I feel like big reduction in size is better than small speed penalty.

Show
Nikita Beloglazov added a comment - Yes, if size is critical then there are better ways to hand-tune the way of loading analysis. At the same time having 3m vs 6m file for local/simple development is a nice win. The only downside is speed, but I feel like big reduction in size is better than small speed penalty.
Hide
Mike Fikes added a comment -

Patch no longer applies.

Show
Mike Fikes added a comment - Patch no longer applies.

People

Vote (2)
Watch (2)

Dates

  • Created:
    Updated: