Fork me on GitHub
#cljs-dev
<
2022-03-31
>
niwinz07:03:46

we have implemented for penpot, high performance uuidv4 and pseudo uuidv1 here: https://github.com/penpot/penpot/blob/develop/common/src/app/common/uuid_impl.js#L97, if it can work as inspiration, (it is implemented in JS for the same reason, performance)

👍 2
borkdude10:03:24

Any reason defn type hints aren't accepted on arg vecs like suggest by the CLJ docs? https://clojure.org/reference/java_interop#typehints More context: https://clojurians.slack.com/archives/C06E3HYPR/p1648720725216029

dnolen14:03:55

@borkdude just an artifact of history, but type hints also serve a a slightly different purpose in ClojureScript

dnolen14:03:53

we should accept them on the vector - mostly for portability since I don't think it serves much of a purpose

isak17:03:03

I noticed for keywords, the emitted javascript can have long strings that are repeated. For example:

(def b :my.extremely.long.out.of.control.keyword/thing)
=>
cljs.user.b = new cljs.core.Keyword("my.extremely.long.out.of.control.keyword","thing","my.extremely.long.out.of.control.keyword/thing",(3471023));
Closure advanced doesn't do anything about that either besides renaming the constructor. Would it make sense to move to a constructor that only needs 1-2 strings instead of 3?

thheller18:03:47

in shadow-cljs you can set :compiler-options {:shadow-keywords true} which optimizes this specific thing

👀 2
thheller18:03:39

got somewhat less useful when closure removed aliasable strings but can still be beneficial

thheller18:03:12

well it used to allow supplying a list of strings it should alias

thheller18:03:33

so shadow-cljs supplied all cljs namespaces

thheller18:03:08

so shadow$keyword("foo", "bar") became shadow$keyword(a, "bar") which can substantially reduce code size if you have a lot of namespaced keywords

isak18:03:19

Oh I see

thheller18:03:43

definitely useful but they removed that feature so ...

isak18:03:39

My fat bundle went from 3200 KB (uncompressed) to 2959 KB with the shadow-maps on, seems worth it to leave on for me. (I probably still need to do something about the size)

thheller18:03:49

you are trading a very very tiny bit of performance for this but in my tests that never was noticable. the default keyword construction precomputes the hash, the :shadow-keywords delay that until the keyword is first hashed

1
thheller18:03:18

but that is cheap enough either way to not matter

thheller18:03:26

definitely compare gzip sizes too

thheller18:03:48

should be better percentage wise since the precomputed hash numbers don't compress well

isak18:03:11

Just checked, gzipped (checking build-report) went from 900.36 kb -> 835.99 kb

👍 1
isak19:03:17

I want to try a trick to compress even further - just reusing keyword instances. I'm testing this with esprima now, to just process the bundle after advanced minification. The nasty part is having to find what the keyword constructor got renamed to.

thheller19:03:11

what do you mean reusing keyword instances? they are only constructed once in release builds

💯 1
thheller19:03:55

shadow-cljs generates a .shadow-cljs/builds/<your-build-id>/release/closure.variable.map file. just a text file that contains the names of renamed properties. eg.

shadow$keyword:K
shadow$keyword_fqn:N

thheller19:03:44

(those are the functions used by :shadow-keywords, not using the constructor anymore

isak19:03:53

Oh wow, I see

dnolen17:03:23

@isak I don't think so, unless you have some kind evidence that such a thing would have a significant benefit

dnolen17:03:51

nothing stops anyone from using the constructor so changes here are also bring on other undesirable issues

isak17:03:49

Ok. No, haven't tested it

niwinz20:03:41

Right now, when you call a function passed as callback or stored as field on deftype, the compiler generates the following code:

// with :fn-invoke-direct true
(self__.selector.cljs$core$IFn$_invoke$arity$1
   ? self__.selector.cljs$core$IFn$_invoke$arity$1(new_source_value)
   : self__.selector(new_source_value))
Is there a way to avoid this check and do direct call to the self__.selector(new_source_value) ? I know that this callback is a javascript function and it will never have the cljs$core$IFn$_invoke$arity$1

thheller05:04:13

if you are using shadow-cljs I introduced a ^function typhint for this

👀 1
niwinz07:04:48

thanks it worked, i'have tried with ^fn and ^js previously without success

dnolen23:03:27

I think you can hint the function as ^js ?