
Taming Advanced Compilation bugs in ClojureScript projects - k1ll3rf0x
https://dev.solita.fi/2020/06/25/taming-cljs-advanced-compilation.html
======
djtango
Oof that XR bug was a rough one to run into. If you're a small startup trying
to move fast with CLJS, these kinds of impedance mismatches between
GCC/CLJS/browser versions can be both hard to track down and a time killer to
fix.

I really like CLJS, when it works it really feels like you have superpowers -
immutable data structures and higher order functions being idiomatic in
Clojure makes Reagent more ergonomic than React in vanilla JS.

Additionally the Clojure philosophy of embracing the host makes interop feel
quite ergonomic when you do need to duck down into JS.

That said, I wouldn't say that the CLJS->JS compilation is watertight
(especially with advanced compilation turned on) and in any non-trivial
project you will run into issues as outlined in this blog post. Once you are
familiar with the stack most the problems fall into a set of predictable
buckets (like the ones mentioned in this article) but debugging them for the
first time can be gnarly.

CLJS is not a tool you can use blindly without knowing how it works IMO. But
maybe that is true of the modern JS stack itself as there is a lot of churn in
JS too.

That said for server-side CLJS we had success turning off advance Closure
compilation as package size isn't as much of an issue

~~~
hellofunk
> we had success turning off advance Closure compilation as package size isn't
> as much of an issue

I always thought that package size was just one of the benefits of advanced
compilation. It also does other nifty things, like automatically unrolling
loops, inlining functions, etc. Those have actual benefits on runtime
performance don’t they?

~~~
sjrd
It depends. GCC (the Google Closure Compiler) indeed does some transformations
that will improve run-time performance, but it is not its forte, and
definitely not its primary goal.

In the benchmarks of Scala.js [1], another compiler that uses GCC behind the
scenes, we have shown that:

* the GCC optimizer alone often introduces performance improvements (not always, and sometimes it _worsens_ performance)

* our optimizer does better than GCC on its own

* the combination of both does not improve over using only our own optimizer

Scala.js uses GCC essentially for its code size improvements, not for its
impact on run-time performance.

[1] [https://www.scala-
js.org/doc/internals/performance.html#in-p...](https://www.scala-
js.org/doc/internals/performance.html#in-production-mode-fullopt)

------
amgreg
Have you tried shadowcljs? Its default (:shadow) option is to use advanced
optimizations only on your code; it will not run advanced optimizations in
libraries but will include them minified. For me, this has struck a good
balance and delivers consistently small and dependable bundles.

