[ClojureScript] Re: Deployment Best Practice - Advanced mode vs multiple js files.

2016-11-23 Thread Thomas Heller
Hey,

I have done quite a few experiments over the years and these would be my 
general recommendations.

TL;DR: Embrace :advanced fully, keep non-cljs/closure out of your build, mind 
your dependencies, use closure modules to split code. 

Most things really depend on your app and your general audience. Say you have 
mostly new users that spend some time on your site but only once every few 
days/weeks at most. Their cache will very likely be empty most of the time. So 
having a "larger but re-usable" framework.js is just worse since they have to 
download it anyways. Only because you say "cache forever" does not mean the 
browser will do so, some (especially mobile) Browsers will purge on their own 
terms (LRU, LFU) anyways to save space.

You can use things like React via a public CDN to increase the chances of the 
user having the thing cached. I have no statistics here but in theory this is a 
good idea (and fairly common).

You want to keep things like React and Material-UI completely out of your CLJS 
build anyways since the Closure compiler doesn't unterstand them and can't do 
much. If you get Material-UI via CLJSJS for example it is one huge JS file, 
even the min is 150kb gzip'd + 100kb for the icons. If you only use 3 out of 
the 40 or so Components they provide you are better off with JS tools to handle 
this. Webpack or Rollup are supposed to be good and will most likely provide 
better results until Closure fully understands this.

CLJS/Closure code should always go through :advanced though as the potential 
savings are huge and you get better performance for some things on top for free.

If you have a large site with different sections (ie. landing pages, signup, 
logged-in only, etc) it is best to split the code using closure modules so the 
initial download is smaller/faster and only loading the other stuff when you 
need it. Closure does very good work here to optimize the splits.

There are many more micro tweaks you can do (preloading, async loading, etc) 
but not downloading/evaling code you don't use is probably the single best 
thing you can do. If you say your :advanced build is too large I'm willing to 
bet that probably 75% or more are due to foreign dependencies. Optimize those 
first, even if you just put them in a framework.js. Don't sacrifice :advanced 
though.

HTH,
/thomas



On Wednesday, November 23, 2016 at 8:00:31 PM UTC+1, Scott Klarenbach wrote:
> I'm curious about Clojurescript deployment best practices.
> 
> Even in advanced compilation mode, I'm finding the size my js to be pretty 
> large.  But my application code is quite a small fraction of the total.  The 
> rest is the Clojurescript runtime, React, Datascript, Material-UI components, 
> etc.
> 
> On a daily/weekly deployment basis, only my application code changes.  Yet 
> with the practice of advanced compilation, I have to redeploy a large .js 
> file to the web clients just to update the application code - the majority of 
> the data payload hasn't changed at all.
> 
> What I'm thinking of doing is compiling two .js files in simple mode, not 
> advanced mode.  The first called framework.js would include Clojurescript, 
> React, Datascript, etc.  The second called app.js would just be my 
> application code.
> 
> Now on a daily basis I only have to cache-invalidate a relatively small .js 
> file in order to update the web app.  The framework.js file only needs to 
> update every couple months when I want to bump the library versions.  
> 
> I feel the benefits of no longer re-deploying the Clojurescript runtime over 
> and over outway the limitations of not using advanced compilation mode.
> 
> Am I missing something that makes this a bad idea?  Is anyone else doing 
> something similar?
> 
> Thanks for your help.
> 
> -- 
> Regards,
> 
> Scott Klarenbach
> Invisible Robot Technologies
> invisiblerobot.io
> 
> 604-537-1856
> sc...@invisiblerobot.io
> 
> #515 - 207 West Hastings Street
> Vancouver, BC, V6B1H7
> 
> ___
> To iterate is human; to recur, divine

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at https://groups.google.com/group/clojurescript.


Re: [ClojureScript] Comparing maps and records

2016-11-23 Thread Juan Facorro
David,

Issue created: CLJS-1859.

Thank you for your work on ClojureScript.

Cheers,
Juan

On Monday, November 21, 2016 at 6:55:30 PM UTC+1, David Nolen wrote:
> Just a bug. File an issue in JIRA.
> 
> 
> Thanks!
> 
> 
> David
> 
> 
> On Sun, Nov 20, 2016 at 10:58 AM, Juan Facorro  wrote:
> Hi all,
> 
> 
> 
> (This might have been asked before, but I couldn't find anything through a 
> search in the group history or google.)
> 
> 
> 
> First of all, Clojure/ClojureScript are awesome!
> 
> 
> 
> I found the result of comparing a map and a record is different based on the 
> order of the arguments to =:
> 
> 
> 
> To quit, type: :cljs/quit
> 
> cljs.user=> (defrecord R [])
> 
> cljs.user/R
> 
> cljs.user=> (= {} (R.))
> 
> true
> 
> cljs.user=> (= (R.) {})
> 
> false
> 
> 
> 
> I tried the code above with tags r1.7.228, r1.8.34 and 1.9.293.
> 
> 
> 
> Is this expected behavior?
> 
> 
> 
> This seems to be rooted in the fact that when a map is the first argument the 
> function used to make the comparison is the implementation of "equiv" from 
> the map. But when a record is the first argument the implementation used is 
> the one from the record, which checks if the types of both arguments are 
> equal.
> 
> 
> 
> The behavior is Clojure (JVM) is consistent:
> 
> 
> 
> user=> (defrecord R [])
> 
> user.R
> 
> user=> (= {} (R.))
> 
> true
> 
> user=> (= (R.) {})
> 
> false
> 
> 
> 
> I suspect this works consistenly since the implementation of "equiv" in 
> "clojure.lang.APersistentMap" checks for the marker interface 
> "MapEquivalence".
> 
> 
> 
> Kind regards,
> 
> Juan
> 
> 
> 
> --
> 
> Note that posts from new members are moderated - please be patient with your 
> first post.
> 
> ---
> 
> You received this message because you are subscribed to the Google Groups 
> "ClojureScript" group.
> 
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to clojurescrip...@googlegroups.com.
> 
> To post to this group, send email to clojur...@googlegroups.com.
> 
> Visit this group at https://groups.google.com/group/clojurescript.

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at https://groups.google.com/group/clojurescript.


[ClojureScript] Deployment Best Practice - Advanced mode vs multiple js files.

2016-11-23 Thread Scott Klarenbach
I'm curious about Clojurescript deployment best practices.

Even in advanced compilation mode, I'm finding the size my js to be pretty 
large.  But my application code is quite a small fraction of the total.  The 
rest is the Clojurescript runtime, React, Datascript, Material-UI components, 
etc.

On a daily/weekly deployment basis, only my application code changes.  Yet with 
the practice of advanced compilation, I have to redeploy a large .js file to 
the web clients just to update the application code - the majority of the data 
payload hasn't changed at all.

What I'm thinking of doing is compiling two .js files in simple mode, not 
advanced mode.  The first called framework.js would include Clojurescript, 
React, Datascript, etc.  The second called app.js would just be my application 
code.

Now on a daily basis I only have to cache-invalidate a relatively small .js 
file in order to update the web app.  The framework.js file only needs to 
update every couple months when I want to bump the library versions.  

I feel the benefits of no longer re-deploying the Clojurescript runtime over 
and over outway the limitations of not using advanced compilation mode.

Am I missing something that makes this a bad idea?  Is anyone else doing 
something similar?

Thanks for your help.

-- 
Regards,

Scott Klarenbach
Invisible Robot Technologies
invisiblerobot.io

604-537-1856
sc...@invisiblerobot.io

#515 - 207 West Hastings Street
Vancouver, BC, V6B1H7

___
To iterate is human; to recur, divine

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at https://groups.google.com/group/clojurescript.