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

2016-11-25 Thread Thomas Heller
Hey,

agreed on external libraries as a rarely changing framework.js served 
separately.

While you are still developing you could do :simple but again that needs to be 
done for everything then. You can't do cljs.core as :simple and the rest as 
:advanced. Too much of the cljs internals rely on either everthing running 
through advanced or nothing. You can't just write externs for cljs.core and 
treat it as an external library. Well you maybe could but you might as well 
skip :advanced at that point.

I would recommend to not worry about it too much while prototyping. Once 
everything settles you probably won't deploy that frequently and given the size 
of well optimized CLJS builds we are probably talking about 100kb (gzip'd) 
which shouldn't really be significant for an enterprise user. Enterprise users 
send around Excel/Word files 10x that size much more frequently. ;) 

You could probably try :simple + closure modules to increase the chance of 
cache hits while developing but in the end you are probably optimizing the 
wrong thing. No one notices 100kb on an enterprise network. Everyone notices 
animations not running smoothly or otherwise janky app performance. Everyone 
says React is fast but it really isn't. I would worry much more about the apps 
performance while running not while downloading. Even :adcanced only buys you 
maybe 5% here.

/thomas



On Thursday, November 24, 2016 at 6:48:41 PM UTC+1, Scott Klarenbach wrote:
> Thanks a lot for the response Thomas.  I think we are on the same page, I 
> just wasn't using the correct terminology.
> 
> I can use :advanced mode for my own code so long as I include an externs file 
> for jquery, material-ui, etc.  
> 
> Not including the external libraries as part of the build (my framework.js) 
> is what you're proposing, and the same goal I was after.  Even with cljsjs, I 
> was including those in the build, and therefore redeploying a 500k+ js file 
> every time a tiny part of my application code changed.  If I remove all non 
> cljs/closure code from the build and just use a cdn and externs, much of my 
> code base doesn't have to be redeployed when my application changes, which is 
> my goal.
> 
> For context, I'm building heavyweight web apps, for a small number of 
> enterprise users.  The code changes rapidly in the beginning due to the 
> prototyping process.  Most traffic is from existing users, not new visitors 
> to a website.  I just wanted a way to return 304s for most of the javascript 
> and only send my app.js code when it changes.
> 
> My instinct is that even the cljs/closure runtime could be deployed to my 
> clients once, and only updated a few times a year.  Hence the idea of simple 
> optimizations.  I think you're saying that I should just resend all the 
> cljs/closure each time with :advanced optimizations.  It just seems to me 
> that in my situation I *could* treat the cljs/closure core runtimes the same 
> way I do jquery - deploy a :simple version once to the client, and rarely 
> have to send again.  Even in :advanced mode, a lot of redundant cljs/closure 
> code is resent to the client each time any tiny part of my app.js changes.
> 
> Thanks,
> Scott.
> 
> On Wednesday, November 23, 2016 at 5:12:15 PM UTC-8, Thomas Heller wrote:
> > 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 

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

2016-11-24 Thread Scott Klarenbach
Thanks a lot for the response Thomas.  I think we are on the same page, I just 
wasn't using the correct terminology.

I can use :advanced mode for my own code so long as I include an externs file 
for jquery, material-ui, etc.  

Not including the external libraries as part of the build (my framework.js) is 
what you're proposing, and the same goal I was after.  Even with cljsjs, I was 
including those in the build, and therefore redeploying a 500k+ js file every 
time a tiny part of my application code changed.  If I remove all non 
cljs/closure code from the build and just use a cdn and externs, much of my 
code base doesn't have to be redeployed when my application changes, which is 
my goal.

For context, I'm building heavyweight web apps, for a small number of 
enterprise users.  The code changes rapidly in the beginning due to the 
prototyping process.  Most traffic is from existing users, not new visitors to 
a website.  I just wanted a way to return 304s for most of the javascript and 
only send my app.js code when it changes.

My instinct is that even the cljs/closure runtime could be deployed to my 
clients once, and only updated a few times a year.  Hence the idea of simple 
optimizations.  I think you're saying that I should just resend all the 
cljs/closure each time with :advanced optimizations.  It just seems to me that 
in my situation I *could* treat the cljs/closure core runtimes the same way I 
do jquery - deploy a :simple version once to the client, and rarely have to 
send again.  Even in :advanced mode, a lot of redundant cljs/closure code is 
resent to the client each time any tiny part of my app.js changes.

Thanks,
Scott.

On Wednesday, November 23, 2016 at 5:12:15 PM UTC-8, Thomas Heller wrote:
> 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.  

[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.