Tricks to make Clojure(startup time) faster?


let try~

 "dependencies": {
  "left-pad": "1.2.0"

npm install


cljs.user=> (require '[left-pad :as lp])
cljs.user=> (lp "foo" 5)
"  foo"

seems nice!



=>> lumo
Lumo 1.7.0
ClojureScript 1.9.908
Node.js v8.4.0
 Docs: (doc function-name-here)
       (find-doc "part-of-name-here")
 Source: (source function-name-here)
 Exit: Control+D or :cljs/quit or exit

cljs.user=> (require '["md5" :as md5])
cljs.user=> md5


Yup, that syntax is standard Clojurescript now, it should be supported no matter which tool you’re using.


Where did that happen? Last time I saw it, it was still in debate?


seems like 1.9.854


Here’s the blog post that introduced that


FWIW, I didn’t take this as negativity, but rather pointing out an issue (the elephant in the room). I think we should pay attention to this issue. I use Clojure for lots of things and while I’m very happy with server code performance, developing could definitely use speed improvements. cider-jack-in takes so long that I often go and get coffee, and if ClojureScript compilation were faster, I’d be much happier, too.

I understand there are good reasons for why it is slow, but this doesn’t mean we shouldn’t pretend it isn’t. Progress is being made and things are getting faster.


The startup time is especially painful for me when I’m doing something like formatting code with cljfmt. I’m using these Boot tasks to integrate cljfmt with Boot and running boot fmt takes over 24 seconds to run on one one-line file. Am I “doing it wrong”? Should I be running this workflow from a REPL somehow instead?


FWIW there’s a nodejs version of cljfmt on npm that starts up much faster. :slight_smile:


I came across that before but I guess I wrote it off because there had been an “update dependencies” PR open for six months. But thank you for the link :slightly_smiling_face:

In general, though, is “find a ClojureScript version” the go-to advice for any kind of tooling where a 20-second startup time is unacceptable?


I tend to do most things using a long-lived JVM process controlled from within emacs.


I wish I had a better answer but yeah I think at this point in time that’s often the most feasible approach.


Can you share some more details about this workflow ?

I’m a bit confused.
Is this the jvm started by the build tools eg. boot repl and reloading deps or controlling another jvm process?


lein repl in a project, connect to it from emacs using cider-connect. One of things that makes this work well is having something like alembic in your main lein config so that you can pull in any deps you need without restarting.


What I still ask myself is why ClojureScript doesn’t suffer from having to load, compile and init all namespaces in start-up?

If the culprit is Clojure and not the JVM, does ClojureScript bootstraps in a different way which solves exponentially the slow start-up times?

Or is it indirectly the JVM’s fault, in that load, compile and init are exponentially slower on the JVM then they are on V8?

One thought I had is, what if Clojure fns shared a class per namespace? Would this be doable? Would it speed up start-up and lower overall memory footprint?


Just to be clear, is Clojure startup time allways high or just for big projects or during development? I mean, a compiled small program will take that long to startup too?


JVM Clojure programs typically take a long time to start, though by “a long time” we mean a few seconds. Compiled ClojureScript programs running in Node start much faster (~100ms).


And that is the reason why I chose cljs for scripting, but I wanted to know how much does it take on clojure, because if it is one second vs 100ms I can live with it.


Clojure doesn’t take longer than a second to start. If it takes longer than a second to run a simple script that almost always means you’re using some other thing that’s adding significant overhead - lein, boot, etc.


Small scripts should start in around 1 second. There are cases where Clojure starts faster then ClojureScript. And if your script does a lot of CPU work, the speedup in execution time you get from Clojure can supersede the startup overhead, meaning the total execution time could still be faster in Clojure.

Take a look at this comparison:

This is for a command line tool, and Clojure ends up being faster.