This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-03-19
Channels
- # announcements (52)
- # asami (83)
- # atom-editor (1)
- # babashka (143)
- # beginners (123)
- # calva (18)
- # chlorine-clover (21)
- # cider (7)
- # clj-kondo (57)
- # cljs-dev (4)
- # clojure (209)
- # clojure-boston (1)
- # clojure-europe (27)
- # clojure-germany (12)
- # clojure-italy (17)
- # clojure-nl (3)
- # clojure-serbia (6)
- # clojure-spec (1)
- # clojure-uk (59)
- # clojurescript (82)
- # conjure (9)
- # core-async (6)
- # cursive (20)
- # data-science (1)
- # datahike (1)
- # datascript (1)
- # datomic (86)
- # duct (5)
- # emacs (6)
- # events (6)
- # figwheel-main (4)
- # fulcro (27)
- # graalvm (19)
- # leiningen (14)
- # lsp (30)
- # malli (48)
- # meander (3)
- # off-topic (6)
- # pedestal (2)
- # practicalli (1)
- # rewrite-clj (21)
- # shadow-cljs (18)
- # sql (15)
- # tools-deps (9)
- # vim (3)
- # wasm (3)
- # xtdb (18)
@lilactown await
would just make the surrounding function return a Promise and you would still have the same problem?
Could you just shim cljs.test/async
on the clj side or something:
(defmacro async [done & body] `@(do [email protected]))
Maybe there should be a proper implementation in clojure.test
thoughI would need to detect whether I'm in a CLJS or CLJ context when emitting code, since macros are defined in Clojure. Or continue to split my CLJS and CLJ test files
Yes I thought that would be an issue but you can actually do (:require #?(:clj [my.async-shim :refer [async]])
in the tests
Has anyone tried the http://hamsters.io library for multithreading js? Would you recommend it, or suggest alternatives?
Would it be recommended to be used in a e.g. react application to boost performance?
The only possible recommendation with such a vague description could only be to first measure what exactly degrades the performance. I.e. browser profiling. Only then you can start think of proper solutions.
Also, in browsers there's no backend-like multithreading. Regardless of what library you choose, it will use web workers. Web workers have a bunch of limitations so it's actually very likely that you will see performance degradation and not improvement when using such a library for some scenarios.
for curious, I've made compiler extension a while ago that adds async/await
specials https://github.com/roman01la/cljs-async-await
not something one would want to use of course, also doesn't remove potential breakage because of intermediate IIFEs generated by the compiler

I think there must be something I’m not understanding about the code splitting feature in cljs. I have two builds sharing much of the same code. After optimization, build A is 900k and build B is 800k. I introduced modules, and now mA is 80k, mB is 40k, but cljs_base is 1080k. How can the shared code (intersection of) A and B be larger than either?
it may be larger because the module loader adds a bit of code you otherwise might not have used
You could have some code that is called once from A and once from B and can be inlined and then shrunken by optimizations in the separate builds https://www.cs.princeton.edu/~appel/papers/shrink.pdf
Is there hope that I might see different/better results with shadow-cljs, @thheller, or is it the same underlying mechanism at play?
impossible to say without knowing what your code does. results will vary if the modules use different npm packages. if its purely CLJS code there likely won't be a big difference
but you will get build reports that will give you a much better picture about what is in your modules 😉 https://shadow-cljs.github.io/docs/UsersGuide.html#build-report
@magnars no matter what you do have to build an understanding of how code splitting works to get the best results
it's not a magical thing - it works best if you have plan around your dependencies and you know where you don't want the heavy stuff to load
in general if I'm building something simple, ClojureScript and basic Google Closure Library is all you need
Good points, for sure. I guess I was hoping it would be just a little magical. 🙃 What surprised me was that “extracting common code” would result in more code than either source.
but if your dependency graph wasn't planned for the split, nothing interesting is going to happen
but starting out with an actual plan is better - the results are quite obvious if you manage your deps and play around w/ it for a bit
Thanks, that’s helpful. 👍 It’s good to know that I can get better results by reorganizing my code to better align with how the code splitter works.
for Closure stuff and ClojureScript stuff it can broken apart, but you also have to realize common ClojureScript stuff is always gonna end up in the base
i.e. login page written ClojureScript but you take care to only use JS objects and arrays
the hello-world compile test size we have in ClojureScript which seems artificial is useful for confirming that this style of planning can be done
so it's not magical, but if you understand it - it can be wielded w/ surgical precision
Any reading material on the topic to suggest? I guess I can use thheller’s build report to find some culprits and experiment from there.
@magnars I see you commented on the loader regression, will take a look at that later
Thanks for the link! I’ll add it to the GitHub issue for those who wondered where to look (like me). 👍
To summarize what I understood today: Given two builds A and B, in a perfect world the size of (module A + base) = size of A, and the size of (module B + base) = size of B. However, we don’t have a perfect (magical) code splitter. To get a good split, the code needs to be organized (via namespaces) along the same lines as the modules. Better alignment yields better splits.
technically closure is able to split namespaces as well and move things wherever they are needed but certain things prevent that from working (eg. defmethod
can't be moved)
Hi There, I had a quick question, I am trying to disable a HTML button using ClojureScript
(def zoom-in-button (-> js/document (.getElementsByClassName "mapboxgl-ctrl-zoom-in")))
(if (= max-zoom (:zoom viewport))
((first zoom-in-button)(.setAttribute "disabled" "disabled")))
Trying to do
<button class="mapboxgl-ctrl-zoom-in" type="button" title="Zoom In" disabled =""></button>
But keep on getting this error Uncaught TypeError: "disable".setAttribute is not a function
In JavaScript
let ZoomIn = document.getElementsByClassName("mapboxgl-ctrl-zoom-in")[0];
ZoomIn.setAttribute("disabled","disabled")
((first zoom-in-button)(.setAttribute "disabled" "disabled")))
this is the equivalent JS:
ZoomIn[0]("disabled".setAttribute("disabled"))
no, it's calling .setAttribute
on the string "disabled"
, like your error message says
if we break it down piece by piece,
(.setAttribute "disabled" "disabled")
literally translates to JS:
"disabled".setAttribute("disabled")
CLJS:
(.setAttribute button "disabled" "disabled")
will be the same as JS:
button.setAttribute("disabled", "disabled")
does that help?Ohhh I get it Thank you @lilactown