At work we use clojurescript to implement a front-end with minified and gzipped assets coming in at around 170KB. If I can’t reduce that substantially I’ll probably have to rewrite in javascript. I’m posting to share some ideas I have for reducing the size of the script and to ask for any additional techniques others have used to get smaller scripts.
Things I can do right now: - Measure the impact of every library: I’ve found that transit adds about 12KB gzipped and core.async adds even more (probably variable due to the transformations performed by the go macro). Reagent is surprisingly light - about 4KB. I’m using preact instead of react, so that lib is an almost negligible 3KB. Importantly, I’ve found that some APIs provided by google closure can have surprising impacts on script size. Don’t use goog.xhr - do direct interop for http requests. - Avoid multimethods and other global registries like re-frame. These thwart DCE because there’s no way to know at compile time that a specific method/handler is never used. - Remove unnecessary parts of data structures. If you have a literal vector of maps where each map has a key or two that isn’t used by code (perhaps it’s just information for developers), those unused keys won’t be DCE’d - Make use of goog defines to get rid of code paths that you can determine to be unnecessary at compile time. - Avoid using apply for functions that implement a lot of different arities. The clourescript compiler tends to be really smart about this - if you implement 1, 2, and 3 arity versions of a function and only call the two arity one, the 1 and 3 arity versions can get DCE’d. If you use apply, however, all the arities end up in the script. - Do a second round of minification with uglify or some other minifier. I haven’t tested this in a while, but when I did last time it saved a KB or two. At least it compresses the Math.imul definition at the top of the script. Aside from dropping heavy libraries, those are all incremental changes. In order to get really substantial size savings, I think changes would need to be made to clojurescript. I have no idea about the feasibility of these things. - (ideally) automatically (but probably based on configuration) remove unused methods of type definitions. For example, cljs.core.UUID implements the equiv method of Object. Suppose we know at compile time that we will construct UUIDs but not compare them with anything. It would be great to be able to remove that method’s definition. I doubt this is possible without a static type system, but I wonder whether there is some way to make this configurable that wouldn’t lead to an explosion of configuration options and inscrutable errors. - Some functions implement multiple arities for dispatch performance. I would like to be able to say “I accept the performance hit in exchange for only implementing one arity of this function”. For instance, partial implements multiple arities of its own args and of the function it returns. This could be reduced down to (defn partial [f & more] (fn [& args] (apply f (concat more args)))) if we cared more about script size than runtime performance. Any other ideas? -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojurescript+unsubscr...@googlegroups.com. To post to this group, send email to clojurescript@googlegroups.com. Visit this group at https://groups.google.com/group/clojurescript.