Fork me on GitHub
#clojurescript
<
2017-11-21
>
cmal07:11:11

It seems keyword definitions in ClojureScript are not efficient when using advanced compilation. https://clojurians.slack.com/archives/C073DKH9P/p1511250296000174 Is this related to the way that ClojureScript used to define keyword? Can this be improved?

thheller07:11:27

@cmal in :advanced keywords are also only allocated once.

cmal08:11:26

It seems some of my keywords appears twice in the new function of my advanced compiled js file, probably because of the specs I used. So thanks @thheller

thheller08:11:18

the keyword appears once but the keyword constructor uses keyword(ns, name, fully-qualified-name, hashcode) so in case of unqualified keywords the string appears twice.

thheller08:11:06

that could indeed be improved but probably not worth after gzipping and the extra runtime overhead required

cmal08:11:59

learned a lot. Thanks @thheller. That reminds me of the book of closure says the compiler's objective is the minimal size of gzipped file, not minimal size of compiled file.

thheller08:11:23

it might be worth exploring though. keywords really add up, especially in reagent projects.

thheller08:11:04

did a super quick comparison, just generating 200 keywords with the fqn and without

thheller08:11:34

12kb vs 9.9kb “code”

thheller08:11:56

4.4k vs 3.7k after gzip

thheller08:11:45

even at 500 keywords its just about 2kb diff gzip’d and thats with completely random keywords

thheller08:11:02

usually you’ll have some kind of overlap which should make gzip better

thheller08:11:39

so yeah, possible micro optimization but probably not worth since you’ll then have to pay the overhead at runtime to construct the fqn when needed.

rauh08:11:29

@cmal A few years ago the Closure compiler had an option to alias duplicate strings, i.e. create a var and use that. They removed that option since it was found to be no benefit in parsing time and code size after gzip.

rauh08:11:52

Oh, it seems it still has that option.

thheller08:11:46

yeah it does. I tried messing with it a while ago and pretty much got the same result they got.

borkdude10:11:49

It seems that secretary is a bit abandoned, no? https://github.com/gf3/secretary

borkdude10:11:31

How do I add or replace a query parameter to the current browser location (without manual string writing)? Can I use Google Closure for this?

borkdude10:11:16

hmm, of course that doesn’t work because query parameters can have the same keys to represent an array

Roman Liutikov10:11:21

@borkdude have you tried goog.uri.utils ns?

ajs10:11:46

a lot of people use secretary, and it is integrated in lots of popular lein templates, so i don’t think it’s risky to use it

borkdude10:11:56

@roman01la I’ve tried this in the browser console:

uri = new goog.Uri(window.location.href)
x = uri.getQueryData()
x.add("foo",2)
uri.toString()
That kind of works, but doesn’t replace the query parameter yet. I think I’d have to do that manually as query params may have multiple by the same name.

borkdude10:11:28

I could first call x.remove and then add

Roman Liutikov10:11:38

goog.uri.utils.setParam(location.href, 'q' 'search')

borkdude11:11:27

That works, thanks! 🙂

Roman Liutikov11:11:55

it should also handle arrays, at least docs says it should 🙂

Roman Liutikov11:11:04

This works, goog.uri.utils.appendParams(location.href, 'q', ['1', '2', '3']), but not setParam

borkdude11:11:28

don’t need arrays, so setParam it is!

vemv12:11:09

anyone using cljs.test in a 'fail-fast' manner? i.e. one test failure causes the rest of the suite to not be run

vemv12:11:56

I see there's *report-counters*, but while in Clojure that's a real dynamic var, in Clojurescript it's a magic injected var

vemv12:11:00

and I cannot use such vars if I want Figwheel to load my testing ns's into the browser (which is very convenient)

hkjels13:11:43

how come: (let [Initialization (aget ApplicationInsights "Initialization")] (Initialization. conf)) work and: (ApplicationInsights.Initialization. conf) does not?

mfikes13:11:04

@hkjels (ApplicationInsights.Initialization. conf) is not any syntax I recognize (looks like a mixture of JavaScript and ClojureScript). My first reaction would be (new (.-Initialization ApplicationInsights) conf) or something along the lines of what you did, (let [Initialization (.-Initialization ApplicationInsights)] (Initialization. conf)), if you wanted to allow Closure renaming (but that seems more verbose).

hkjels13:11:32

@mfikes your right, thanks.. Ending with a . is supposedly the same as (new x)

mfikes13:11:07

Yep. Dots at the beginning or end of a symbol are just sugar that the macroexpander converts. Try (macroexpand '(x.)) and (macroexpand '(.x y))

tomaas14:11:01

When doing prerender of a single page app in server. Let's say the server computes a reagent component to html, also adds the app.js script. All this gets downloaded by the browser, the prerendered html is put to the dom and then it downloads the app.js, parses it and recomputes+repaints that same component the server returned? If that so, then while the app.js is being downloaded + parsed + evaluated, the dom is still locked. Ok, you see the initial html but it is unusable. With re-frame or reagent you can't even put app.js script with async option as it uses document.write in its code, which makes async option not to work.

Roman Liutikov14:11:29

@tomaas yes. one thing you can do is to render as much interactive elements as possible with links and maybe some CSS. So while waiting for JS to load user can go to another page.

Roman Liutikov14:11:19

but then again you should wait for a bundle to load 😄

tomaas14:11:45

🙂 thanks, i think i'll focus on putting a really nice spinner instead of all this XD

thheller14:11:08

@tomaas did you identify what is doing the document.write? seems like that should be fixed.

Roman Liutikov14:11:55

@tomaas haha, best solution ever! (seriously) you can do all sorts of optimizations like code splitting etc. but not sure if it’s worth it in your case

tomaas14:11:28

@thheller, I didn't. Just seen that there are a few appearances of it in production's (with optimization :advanced option) build.

Roman Liutikov14:11:13

@tomaas could you point to these in Reagent’s code? Just scanned the code base, couldn’t find anything

tomaas14:11:57

I didn't check on reagent, just re-frame (assumed it would be the same, sorry)

tomaas14:11:26

On reagent's build, I can see now only this goog.global.document.write

tomaas14:11:42

anyway, regarding the ultimate user experience I don't see any bad thing about not having anything prerendered on the server, it's just that I noticed that google's pagespeed insights takes away ~20 points for not having the script tag with async option.

tomaas14:11:08

however, http://gtmetrix.com doesn't care about that at all

Roman Liutikov14:11:33

it’s fine unless you are all into “perf matters” Google advocating thing, IMO

tomaas14:11:59

no 🙂 I was just curious

chris_17:11:10

@mikethompson My apologies for dropping off the face of the earth; thank you for the pointer and looking into this; I’ll get it working 🙂 thanks again

qqq19:11:44

anyone know of cljs bindings for https://github.com/numjs/numjs ?

grav19:11:00

Does anyone know, what’s the format that the constructor for https://google.github.io/closure-library/api/goog.i18n.DateTimeFormat.html uses as pattern? Is it some standard?

mfikes19:11:29

@grav Looks like there might be other things like Q for quarter. Seems odd they don’t just document or provide a link. Here’s what I was looking at: https://github.com/google/closure-library/blob/master/closure/goog/i18n/datetimeformat.js#L868

grav19:11:01

@mfikes Thanks for the link! You’re right, there’s more to it than just what I found. But who needs docs when you’ve got the nice Javascript source 😉

honzabrecka21:11:11

I'm trying to :require npm dependency (uuid) in browser through figwheel, but it fails because the dependency is not compiled into single file - it's using "require" function. Anyone could help? 🙂

honzabrecka21:11:57

It's failing with "require is not defined" Reference error.

honzabrecka22:11:36

The problem is that in its package.json is:

"browser": {
    "./lib/rng.js": "./lib/rng-browser.js",
    "./lib/sha1.js": "./lib/sha1-browser.js"
  },
which is ignored by compiler -> ends up with unresolved (untouched) require('./lib/rng').

athomasoriginal22:11:36

RE: boot-cljs-test I am using crisptrutski/boot-cljs-test and it seems to be crashing because I do not have phantomjs installed locally. Is this correct behaviour? I reviewed the README and it does not suggest anything about installing phantomjs for this to work. The next question is, is this the preferred task for cljs tests or are people more commonly writing their own task?

athomasoriginal22:11:10

Interesting. The answer seems to be on the https://github.com/bensu/doo README where it actually tells you that you need to install phantom.