Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-12-02 Thread Howard M. Lewis Ship


On Wednesday, 27 November 2013 11:11:56 UTC-8, Magnar Sveen wrote:


 On Wednesday, November 27, 2013 1:08:34 PM UTC+1, Stefan Kamphausen wrote:
  

 Howard has quite some experience with this and I'd expect he put a great 
 deal of that into the new library. :-)

  
 Indeed. There's certainly a lot of care that's been put into the features 
 that are in Twixt now. :-)


I'd say that Optimus has a lot of great features, and so does Twixt.  

w.r.t. gzip; for assets, which are effectively static, it is silly to burn 
CPU to compress them on each request, so the gzip is at that level to 
support caching of the gzipped content.  You will certainly want gzip 
support for dynamic content.

Of course, in an AngularJS app, all your templates are static content 
(assets) as well, so you just want to gzip your JSON or EDN responses.

From a cursory view of the Optimus readme, there's just differences in 
priorities of certain features; also  Twixt serves assets from 
META-INF/assets, not from a disk folder. That was actually the reason to 
move off of Dieter; that was not possible, and we had restrictions in our 
deployment model that required it.

Twixt is more interested in providing a development-time work cycle where 
changed assets are recompiled and otherwise reconstituted.  I don't want to 
have to bounce my app just because a stylesheet changed ... but in 
production, I don't want to burn cycles checking to see if files that will 
never change, have changed.



 - Magnar


-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-12-02 Thread Howard M. Lewis Ship


On Monday, 25 November 2013 18:12:28 UTC-8, Paul Biggar wrote:

 [FYI: I'm the author/forker of stefon]

 These libraries aren't bad, but to be honest, I think we've done it all 
 wrong. We're just all scratching our own itches, not writing reusable 
 components (unlike most of the rest of the clojure web ecosystem).

 If you look at stefon, you get a set of non-composable functions, designed 
 for my exact use case. Optimus, cornet, and dieter all suffer from the same 
 problems.

 Cornet, supports compilation (with different compiler and versions from 
 stefon), serving assets, and configuring itself from a JVM command line. It 
 also has :dev and :prod modes (though these mean dont minify and do 
 minify. It does split out the functions in a slightly composable way (you 
 can have `(wrap-lesscss-processor loader :mode :dev)`), but those still use 
 :mode.

 Stefon supports: concatenating JS and CSS, compiling less, coffeescript, 
 hamlcoffee, minification using Closure compiler (currently broken), some 
 trivial css minification, cache-busting and expiry headers, and asset 
 references (eg data-uri to put the contents of one asset in another). It 
 also supports caching compilation and clj-v8 for speed, and expiration 
 headers and cache busting. It has precompilation for production use with a 
 CDN).

 Dieter is basically like stefon, but older and less maintained, and some 
 different choices around precompilation.

 Optimus supports concatenating, minification, cache busting, expiry 
 headers, and something angular specific. Also assets dont have to be files 
 on disk, and a there's a list of a dozen or so other features that contrast 
 it to stefon or cornet in a neutral way (neither decision is right or 
 wrong, just different).

 So basically stefon supports all high level use cases, optimus support all 
 of them except compilation, cornet supports most of it but not cache 
 busting. But where we do support the same things, we do it in many 
 different ways.

 So my problem here is that we've each chosen to couple everything 
 together. If you want to use stefon's CDN feature in production, with 
 optimus' dev asset serving, with cornet's minification, you're out of luck.

 Weavejester made a critique of stefon on reddit [1] a while back. He made 
 the point why isn't this just middleware, by which I believe he means 
 why cant this all be split up into composable functions?

 He's right. We should, IMO, stop doing what we're doing, and rebuild our 
 projects into a set of composable components that play well together:

 - a choice of caching middlewares
 - a choice of minifying middlewares
 - a choice of asset compilers (including different versions and 
 implementations) (also some way for them to interact to support a pipeline)
 - a choice of precompilation/CDN and compiling on the server
 - composable optimizations (caching compilations)
 - a choice of how to concatenate assets

 I don't really know how to do this though, just that they should be 
 different libraries, and that all orthogonal feature sets should be 
 composable. I'd love to hear people's thoughts on how we can accomplish 
 this.

 [1] 
 http://www.reddit.com/r/Clojure/comments/1n1n0p/circlecistefon_asset_pipeline_for_clojure_closely/ccexi3a


I got some feedback along these lines for Twixt, from technomancy.

I rewrote most of the code and was pleased with the result.

The approach I took was to have an asset pipeline that was used by Twixt; 
it was built by the application (there's a default for most cases). The 
asset pipeline works much like the Ring request pipeline, you can add 
middleware to it.

Even the default pipeline understands production mode vs. development mode, 
which is (currently) mostly a question of what gets cached and when the 
cache is checked to see if it is dirty, if at all.

 


 On Monday, 25 November 2013 11:10:54 UTC-8, Magnar Sveen wrote:

 Hi Jason! 

 Magnar, could you talk a little about how your project is better 
 than/different from Stefon/dieter and cornet? I feel like we have a lot of 
 these projects now, all doing mostly the same thing.


 Thanks for asking. I'll try to shed some light on the differences as I 
 see them, and hopefully the people behind Dieter/Stefon (they're very 
 similar) can add some details into their thinking. I haven't seen Comet, 
 and google didn't help much either. Can you share a link?

 As for Optimus vs Stefon: First of all it's a difference in focus. Stefon 
 focuses on being an asset pipeline modelled after Sprockets in Rails. It 
 lets you write LESS, CoffeeScript, Haml - turning it into CSS and 
 JavaScript. Optimus is not about transpiling from other languages, but 
 about frontend optimization. As such, it rewrites your urls to include 
 cache busters and serves your assets with far-future expires headers, so 
 they can be cached aggressively in production. As I add more features to 
 optimus, they too will focus around better frontend performance - 

Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-27 Thread Magnar Sveen
I think it would be best if the author chimed in, but it looks like there 
has been done some good work on optimizing the development workflow when 
you're working with languages that need to be transpiled. There isn't much 
front-end optimization, but looks like it's on the todo-list. There's also 
the slightly misguided inclusion of gzip at this point in the stack. You 
want gzip for all your text content - including dynamically generated html 
and json - so adding it to the static assets here would either be not 
enough, or redundant work.

On Tuesday, November 26, 2013 1:34:35 PM UTC+1, Stefan Kamphausen wrote:

 Hi,

 I'd be very interested in learning, how Twixt[1] compares to Optimus and 
 the other solutions cited.

 [1] https://github.com/AvisoNovate/twixt/


 Regards,
 stefan



-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-27 Thread Stefan Kamphausen


On Wednesday, November 27, 2013 11:11:27 AM UTC+1, Magnar Sveen wrote:

 I think it would be best if the author chimed in,


me too
 

 but it looks like there has been done some good work on optimizing the 
 development workflow when you're working with languages that need to be 
 transpiled. There isn't much front-end optimization, but looks like it's on 
 the todo-list. There's also the slightly misguided inclusion of gzip at 
 this point in the stack. You want gzip for all your text content - 
 including dynamically generated html and json - so adding it to the static 
 assets here would either be not enough, or redundant work.


Howard has quite some experience with this and I'd expect he put a great 
deal of that into the new library. :-)

Best,
stefan

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-27 Thread Magnar Sveen

On Wednesday, November 27, 2013 1:08:34 PM UTC+1, Stefan Kamphausen wrote:
 

 Howard has quite some experience with this and I'd expect he put a great 
 deal of that into the new library. :-)

 
Indeed. There's certainly a lot of care that's been put into the features 
that are in Twixt now. :-)

- Magnar

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-26 Thread Magnar Sveen
Hi Paul! Thanks for chiming in.

I set out to create a suite of middlewares for frontend optimization. The 
first was Catenate, which concerned itself with concatenation into bundles. 
So I certainly agree with your points. You'd be hard pressed to think 
otherwise in the Clojure community, I think, with its focus on 
decomplecting. The reason I gave up on that idea is two-fold:

- The different optimizations are not orthogonal.
- Assets aren't first class in the Ring middleware stack.

Some examples:

- When you bundle files together, your HTML has to reference either the 
bundle URL (in prod) or all the individual files (in dev). There has to be 
some sort of lookup from the bundle ID to a list of URLs, and this is 
dependent on your asset-serving strategy.
 
- When you add cache-busters to URLs, you need some sort of lookup from the 
original URL to the cache-busted URL, so you can link to them with a known 
name.

In other words, both the bundle middleware and the cache-busting middleware 
either needs to own the list of assets, or it needs to rest on a first 
class asset concept in the stack.

Now add the ability to serve WebP images to browsers that support it. Not 
only do you have to change the image URLs, but you also have to serve a 
different set of CSS to use these new images. So this middleware would have 
to know which CSS files reference which files, and rewrite them. 

All of these could be fixed with a well-thought out Asset concept in the 
ring middleware stack. Which is what Optimus is an attempt at. It adds a 
list of assets to the request, with enough information for the linking 
functions to figure out which versions of which files to link.

But then there's the orthogonality:

   - You can't add cache-busters first, and then bundle assets together, 
   since you wouldn't get cache buster URLs on your bundles.
   - If you minify first, then bundle, you'll get suboptimal minification 
   results in production. If you bundle first, then minify, you won't know 
   which file is to blame for errors in development.
   - You should never add far-future expires headers unless the asset has a 
   cache-buster URL.

So ordering matters. You can't just throw in another middleware, you have 
to order it just so-and-so. I started writing documentation for this in 
Catenate. It would say If you're also using cache-busting middleware, make 
sure to place it after Catenate. After writing a few of those sentences, I 
came to the conclusion that they were not entirely separate things. Since 
they're so dependent on each other, they should live together.

There's also the case of *when* to optimize. In production you want to 
optimize once - either as a build step, or when starting the application. 
In development you don't want any optimization (unless you're debugging), 
but you still need to create the list of assets so you're able to link to 
it. This is something all the optimization middlewares would have to tackle 
on their own - basically each layer freezing their optimized assets on 
server start, and all but the last one doing so in vain.

Optimus solves this by creating a separate middleware stack for 
optimizations, that work on assets (not requests), and that can be done at 
different times by different asset-serving strategies.

So, in conclusion: If we can agree on a data format for assets - the one in 
Optimus has been through quite a few iterations 
(https://github.com/magnars/optimus#what-are-these-assets-anyway-they-seem-magical-to-me)
 
- then we could build on that to create separate middlewares. But not 
middlewares for the Ring stack. It would have to be Asset-specific 
middlewares.

For instance, even tho Optimus doesn't do transpiling, building a 
transpiler to fit in the Optimus asset middleware stack is pretty nice. You 
let :original-url be the original styles.less, so the linking features 
can find it, replace the :contents with CSS, and serve it under the :path 
styles.css. If your package takes a list of assets, and returns a list of 
assets with all .less files changed like this, you can plug it in with no 
modifications to Optimus. 

- Magnar


On Tuesday, November 26, 2013 3:12:28 AM UTC+1, Paul Biggar wrote:

 [FYI: I'm the author/forker of stefon]

 These libraries aren't bad, but to be honest, I think we've done it all 
 wrong. We're just all scratching our own itches, not writing reusable 
 components (unlike most of the rest of the clojure web ecosystem).

 If you look at stefon, you get a set of non-composable functions, designed 
 for my exact use case. Optimus, cornet, and dieter all suffer from the same 
 problems.

 Cornet, supports compilation (with different compiler and versions from 
 stefon), serving assets, and configuring itself from a JVM command line. It 
 also has :dev and :prod modes (though these mean dont minify and do 
 minify. It does split out the functions in a slightly composable way (you 
 can have `(wrap-lesscss-processor loader :mode 

Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-26 Thread Stefan Kamphausen
Hi,

I'd be very interested in learning, how Twixt[1] compares to Optimus and 
the other solutions cited.

[1] https://github.com/AvisoNovate/twixt/


Regards,
stefan

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-25 Thread Murtaza Husain
Magnar,

Thanks for the project ! Nicely fills up a void.

Thanks,
Murtaza

On Monday, November 25, 2013 3:30:10 AM UTC+5:30, Magnar Sveen wrote:

 I just open sourced optimus. README and code here: 
 https://github.com/magnars/optimushttps://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fmagnars%2Foptimussa=Dsntz=1usg=AFQjCNHVew3Ey2Bh409AV3mEhpEipbxGzQ

 Optimus is a Ring middleware for frontend performance optimization.

 It serves your static assets:

- in production: as optimized bundles
- in development: as unchanged, individual files

 In other words: Develop with ease. Optimize in production.

 *Features*

 Depending on how you use it, optimus:

- concatenates your JavaScript and CSS files into bundles.
- minifies your JavaScript with UglifyJS 
 2https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fmishoo%2FUglifyJS2sa=Dsntz=1usg=AFQjCNGjUWtc9t6OLfeCSFD67Qiv1YJHuA
- minifies your CSS with 
 CSSOhttp://www.google.com/url?q=http%3A%2F%2Fbem.info%2Ftools%2Foptimizers%2Fcsso%2Fsa=Dsntz=1usg=AFQjCNHFxxUFir_vcxqI79FeEYI-2xijmQ
- adds cache-busters to your static asset URLs
- adds far future Expires 
 headershttp://www.google.com/url?q=http%3A%2F%2Fdeveloper.yahoo.com%2Fperformance%2Frules.html%23expiressa=Dsntz=1usg=AFQjCNFc3zu6wMgQIthHxVHy4AoHDyPdQw

 Also, if you're using Angular.JS:

- prepopulates the Angular template 
 cachehttp://www.google.com/url?q=http%3A%2F%2Fdocs.angularjs.org%2Fapi%2Fng.%2524templateCachesa=Dsntz=1usg=AFQjCNE8i4GlTWl0r4u9fKoAyEipcMYAlw
  with 
your HTML templates.



 https://github.com/magnars/optimushttps://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fmagnars%2Foptimussa=Dsntz=1usg=AFQjCNHVew3Ey2Bh409AV3mEhpEipbxGzQ


-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-25 Thread Jason Bennett
Magnar, could you talk a little about how your project is better 
than/different from Stefon/dieter and cornet? I feel like we have a lot of 
these projects now, all doing mostly the same thing.

I also don't totally understand why they're all done as Ring middleware 
instead of lein/maven plugins. Maybe this is my Java background talking, 
but that seems to me to be the logical place to put this sort of thing.

jason 

On Sunday, November 24, 2013 2:00:10 PM UTC-8, Magnar Sveen wrote:

 I just open sourced optimus. README and code here: 
 https://github.com/magnars/optimushttps://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fmagnars%2Foptimussa=Dsntz=1usg=AFQjCNHVew3Ey2Bh409AV3mEhpEipbxGzQ

 Optimus is a Ring middleware for frontend performance optimization.

 It serves your static assets:

- in production: as optimized bundles
- in development: as unchanged, individual files

 In other words: Develop with ease. Optimize in production.

 *Features*

 Depending on how you use it, optimus:

- concatenates your JavaScript and CSS files into bundles.
- minifies your JavaScript with UglifyJS 
 2https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fmishoo%2FUglifyJS2sa=Dsntz=1usg=AFQjCNGjUWtc9t6OLfeCSFD67Qiv1YJHuA
- minifies your CSS with 
 CSSOhttp://www.google.com/url?q=http%3A%2F%2Fbem.info%2Ftools%2Foptimizers%2Fcsso%2Fsa=Dsntz=1usg=AFQjCNHFxxUFir_vcxqI79FeEYI-2xijmQ
- adds cache-busters to your static asset URLs
- adds far future Expires 
 headershttp://www.google.com/url?q=http%3A%2F%2Fdeveloper.yahoo.com%2Fperformance%2Frules.html%23expiressa=Dsntz=1usg=AFQjCNFc3zu6wMgQIthHxVHy4AoHDyPdQw

 Also, if you're using Angular.JS:

- prepopulates the Angular template 
 cachehttp://www.google.com/url?q=http%3A%2F%2Fdocs.angularjs.org%2Fapi%2Fng.%2524templateCachesa=Dsntz=1usg=AFQjCNE8i4GlTWl0r4u9fKoAyEipcMYAlw
  with 
your HTML templates.



 https://github.com/magnars/optimushttps://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fmagnars%2Foptimussa=Dsntz=1usg=AFQjCNHVew3Ey2Bh409AV3mEhpEipbxGzQ


-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-25 Thread Magnar Sveen
Hi Jason! 

Magnar, could you talk a little about how your project is better 
 than/different from Stefon/dieter and cornet? I feel like we have a lot of 
 these projects now, all doing mostly the same thing.


Thanks for asking. I'll try to shed some light on the differences as I see 
them, and hopefully the people behind Dieter/Stefon (they're very similar) 
can add some details into their thinking. I haven't seen Comet, and google 
didn't help much either. Can you share a link?

As for Optimus vs Stefon: First of all it's a difference in focus. Stefon 
focuses on being an asset pipeline modelled after Sprockets in Rails. It 
lets you write LESS, CoffeeScript, Haml - turning it into CSS and 
JavaScript. Optimus is not about transpiling from other languages, but 
about frontend optimization. As such, it rewrites your urls to include 
cache busters and serves your assets with far-future expires headers, so 
they can be cached aggressively in production. As I add more features to 
optimus, they too will focus around better frontend performance - and not 
more languages to be transpiled.

While this is the main point in my mind, there are also other differences 
that aren't just details that everyone will agree on. :-) These two come to 
mind:

1. Stefon serves assets live in development, but requires a build step in 
production to precompile the files. Optimus does not require a build step, 
but compiles your asset when the server starts. 

2. Stefon creates bundles by having custom .stefon files with edn-flavored 
lists of files in your directories of static assets. Optimus also needs a 
list of bundles, but does so using Clojure in your program. I would think 
that Stefons' approach is better if your frontend developers are not 
comfortable editing the Clojure code, while Optimus' approach allows more 
programatic control.

I hope I haven't misrepresented Stefon in any way - these are my 
impressions. Since I'm a front-end optimization nut, these arguments were 
enough to sway me to create a different package. It would be several major 
breaking changes to Dieter and Stefon's architectures and APIs, and I 
didn't think I would get anywhere fighting for these changes in github 
issues.

 

 I also don't totally understand why they're all done as Ring middleware 
 instead of lein/maven plugins. Maybe this is my Java background talking, 
 but that seems to me to be the logical place to put this sort of thing.


Front-end development with a compilation step is pretty horrible. There's 
also the case that the URL to a static asset and its location on disk is 
entirely different after optimization.

Hope that answers your questions somewhat decently. And if it didn't, maybe 
you'll be swayed by the argument that a little competition is a good thing 
for the community. :)

- Magnar

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-25 Thread Jason Bennett
Ok, thanks for the reply. Cornet is at https://github.com/cosmi/cornet, 
it's similar to stefon.

I believe there are some existing middlewares for ring that do similar 
things (like wrap-not-modified). Do you replace this or work with it?

jason

On Monday, November 25, 2013 11:10:54 AM UTC-8, Magnar Sveen wrote:

 Hi Jason! 

 Magnar, could you talk a little about how your project is better 
 than/different from Stefon/dieter and cornet? I feel like we have a lot of 
 these projects now, all doing mostly the same thing.


 Thanks for asking. I'll try to shed some light on the differences as I see 
 them, and hopefully the people behind Dieter/Stefon (they're very similar) 
 can add some details into their thinking. I haven't seen Comet, and google 
 didn't help much either. Can you share a link?

 As for Optimus vs Stefon: First of all it's a difference in focus. Stefon 
 focuses on being an asset pipeline modelled after Sprockets in Rails. It 
 lets you write LESS, CoffeeScript, Haml - turning it into CSS and 
 JavaScript. Optimus is not about transpiling from other languages, but 
 about frontend optimization. As such, it rewrites your urls to include 
 cache busters and serves your assets with far-future expires headers, so 
 they can be cached aggressively in production. As I add more features to 
 optimus, they too will focus around better frontend performance - and not 
 more languages to be transpiled.

 While this is the main point in my mind, there are also other differences 
 that aren't just details that everyone will agree on. :-) These two come to 
 mind:

 1. Stefon serves assets live in development, but requires a build step in 
 production to precompile the files. Optimus does not require a build step, 
 but compiles your asset when the server starts. 

 2. Stefon creates bundles by having custom .stefon files with edn-flavored 
 lists of files in your directories of static assets. Optimus also needs a 
 list of bundles, but does so using Clojure in your program. I would think 
 that Stefons' approach is better if your frontend developers are not 
 comfortable editing the Clojure code, while Optimus' approach allows more 
 programatic control.

 I hope I haven't misrepresented Stefon in any way - these are my 
 impressions. Since I'm a front-end optimization nut, these arguments were 
 enough to sway me to create a different package. It would be several major 
 breaking changes to Dieter and Stefon's architectures and APIs, and I 
 didn't think I would get anywhere fighting for these changes in github 
 issues.

  

 I also don't totally understand why they're all done as Ring middleware 
 instead of lein/maven plugins. Maybe this is my Java background talking, 
 but that seems to me to be the logical place to put this sort of thing.


 Front-end development with a compilation step is pretty horrible. There's 
 also the case that the URL to a static asset and its location on disk is 
 entirely different after optimization.

 Hope that answers your questions somewhat decently. And if it didn't, 
 maybe you'll be swayed by the argument that a little competition is a good 
 thing for the community. :)

 - Magnar


-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-25 Thread Magnar Sveen
Thanks for the link to cornet. Must be the kerning on my font, since I read 
comet. :-) I'll definitely check it out. At first glance it looks like a 
replacement for Dieter/Stefon, more focused on transpiling than 
optimization. I can't see any mention of it tackling problems like cache 
busting, and the issues that come with it. For instance how the cache 
busters on CSS files need to be a cascade of the assets they link to.

As for basic ring middlewares, I try not to reimplement them. So you would 
use wrap-content-type, for instance. As for wrap-not-modified, that's an 
interesting thought - especially since we know the asset hasn't changed, or 
it would be under another name. I'll have to look into that further. Nice 
tip, thanks.

- Magnar

On Monday, November 25, 2013 10:56:33 PM UTC+1, Jason Bennett wrote:

 Ok, thanks for the reply. Cornet is at 
 https://github.com/cosmi/cornethttps://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fcosmi%2Fcornetsa=Dsntz=1usg=AFQjCNGTDwnsbtlpY6VpnA2Xpg3UKB19Sg,
  
 it's similar to stefon.

 I believe there are some existing middlewares for ring that do similar 
 things (like wrap-not-modified). Do you replace this or work with it?

 jason

 On Monday, November 25, 2013 11:10:54 AM UTC-8, Magnar Sveen wrote:

 Hi Jason! 

 Magnar, could you talk a little about how your project is better 
 than/different from Stefon/dieter and cornet? I feel like we have a lot of 
 these projects now, all doing mostly the same thing.


 Thanks for asking. I'll try to shed some light on the differences as I 
 see them, and hopefully the people behind Dieter/Stefon (they're very 
 similar) can add some details into their thinking. I haven't seen Comet, 
 and google didn't help much either. Can you share a link?

 As for Optimus vs Stefon: First of all it's a difference in focus. Stefon 
 focuses on being an asset pipeline modelled after Sprockets in Rails. It 
 lets you write LESS, CoffeeScript, Haml - turning it into CSS and 
 JavaScript. Optimus is not about transpiling from other languages, but 
 about frontend optimization. As such, it rewrites your urls to include 
 cache busters and serves your assets with far-future expires headers, so 
 they can be cached aggressively in production. As I add more features to 
 optimus, they too will focus around better frontend performance - and not 
 more languages to be transpiled.

 While this is the main point in my mind, there are also other differences 
 that aren't just details that everyone will agree on. :-) These two come to 
 mind:

 1. Stefon serves assets live in development, but requires a build step in 
 production to precompile the files. Optimus does not require a build step, 
 but compiles your asset when the server starts. 

 2. Stefon creates bundles by having custom .stefon files with 
 edn-flavored lists of files in your directories of static assets. Optimus 
 also needs a list of bundles, but does so using Clojure in your program. I 
 would think that Stefons' approach is better if your frontend developers 
 are not comfortable editing the Clojure code, while Optimus' approach 
 allows more programatic control.

 I hope I haven't misrepresented Stefon in any way - these are my 
 impressions. Since I'm a front-end optimization nut, these arguments were 
 enough to sway me to create a different package. It would be several major 
 breaking changes to Dieter and Stefon's architectures and APIs, and I 
 didn't think I would get anywhere fighting for these changes in github 
 issues.

  

 I also don't totally understand why they're all done as Ring middleware 
 instead of lein/maven plugins. Maybe this is my Java background talking, 
 but that seems to me to be the logical place to put this sort of thing.


 Front-end development with a compilation step is pretty horrible. There's 
 also the case that the URL to a static asset and its location on disk is 
 entirely different after optimization.

 Hope that answers your questions somewhat decently. And if it didn't, 
 maybe you'll be swayed by the argument that a little competition is a good 
 thing for the community. :)

 - Magnar



-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-25 Thread Paul Biggar
[FYI: I'm the author/forker of stefon]

These libraries aren't bad, but to be honest, I think we've done it all 
wrong. We're just all scratching our own itches, not writing reusable 
components (unlike most of the rest of the clojure web ecosystem).

If you look at stefon, you get a set of non-composable functions, designed 
for my exact use case. Optimus, cornet, and dieter all suffer from the same 
problems.

Cornet, supports compilation (with different compiler and versions from 
stefon), serving assets, and configuring itself from a JVM command line. It 
also has :dev and :prod modes (though these mean dont minify and do 
minify. It does split out the functions in a slightly composable way (you 
can have `(wrap-lesscss-processor loader :mode :dev)`), but those still use 
:mode.

Stefon supports: concatenating JS and CSS, compiling less, coffeescript, 
hamlcoffee, minification using Closure compiler (currently broken), some 
trivial css minification, cache-busting and expiry headers, and asset 
references (eg data-uri to put the contents of one asset in another). It 
also supports caching compilation and clj-v8 for speed, and expiration 
headers and cache busting. It has precompilation for production use with a 
CDN).

Dieter is basically like stefon, but older and less maintained, and some 
different choices around precompilation.

Optimus supports concatenating, minification, cache busting, expiry 
headers, and something angular specific. Also assets dont have to be files 
on disk, and a there's a list of a dozen or so other features that contrast 
it to stefon or cornet in a neutral way (neither decision is right or 
wrong, just different).

So basically stefon supports all high level use cases, optimus support all 
of them except compilation, cornet supports most of it but not cache 
busting. But where we do support the same things, we do it in many 
different ways.

So my problem here is that we've each chosen to couple everything together. 
If you want to use stefon's CDN feature in production, with optimus' dev 
asset serving, with cornet's minification, you're out of luck.

Weavejester made a critique of stefon on reddit [1] a while back. He made 
the point why isn't this just middleware, by which I believe he means 
why cant this all be split up into composable functions?

He's right. We should, IMO, stop doing what we're doing, and rebuild our 
projects into a set of composable components that play well together:

- a choice of caching middlewares
- a choice of minifying middlewares
- a choice of asset compilers (including different versions and 
implementations) (also some way for them to interact to support a pipeline)
- a choice of precompilation/CDN and compiling on the server
- composable optimizations (caching compilations)
- a choice of how to concatenate assets

I don't really know how to do this though, just that they should be 
different libraries, and that all orthogonal feature sets should be 
composable. I'd love to hear people's thoughts on how we can accomplish 
this.

[1] 
http://www.reddit.com/r/Clojure/comments/1n1n0p/circlecistefon_asset_pipeline_for_clojure_closely/ccexi3a

On Monday, 25 November 2013 11:10:54 UTC-8, Magnar Sveen wrote:

 Hi Jason! 

 Magnar, could you talk a little about how your project is better 
 than/different from Stefon/dieter and cornet? I feel like we have a lot of 
 these projects now, all doing mostly the same thing.


 Thanks for asking. I'll try to shed some light on the differences as I see 
 them, and hopefully the people behind Dieter/Stefon (they're very similar) 
 can add some details into their thinking. I haven't seen Comet, and google 
 didn't help much either. Can you share a link?

 As for Optimus vs Stefon: First of all it's a difference in focus. Stefon 
 focuses on being an asset pipeline modelled after Sprockets in Rails. It 
 lets you write LESS, CoffeeScript, Haml - turning it into CSS and 
 JavaScript. Optimus is not about transpiling from other languages, but 
 about frontend optimization. As such, it rewrites your urls to include 
 cache busters and serves your assets with far-future expires headers, so 
 they can be cached aggressively in production. As I add more features to 
 optimus, they too will focus around better frontend performance - and not 
 more languages to be transpiled.

 While this is the main point in my mind, there are also other differences 
 that aren't just details that everyone will agree on. :-) These two come to 
 mind:

 1. Stefon serves assets live in development, but requires a build step in 
 production to precompile the files. Optimus does not require a build step, 
 but compiles your asset when the server starts. 

 2. Stefon creates bundles by having custom .stefon files with edn-flavored 
 lists of files in your directories of static assets. Optimus also needs a 
 list of bundles, but does so using Clojure in your program. I would think 
 that Stefons' approach is better if your frontend 

[ANN] Optimus - a Ring middleware for frontend performance optimization.

2013-11-24 Thread Magnar Sveen
I just open sourced optimus. README and code 
here: https://github.com/magnars/optimus

Optimus is a Ring middleware for frontend performance optimization.

It serves your static assets:

   - in production: as optimized bundles
   - in development: as unchanged, individual files

In other words: Develop with ease. Optimize in production.

*Features*

Depending on how you use it, optimus:

   - concatenates your JavaScript and CSS files into bundles.
   - minifies your JavaScript with UglifyJS 
2https://github.com/mishoo/UglifyJS2
   - minifies your CSS with CSSO http://bem.info/tools/optimizers/csso/
   - adds cache-busters to your static asset URLs
   - adds far future Expires 
headershttp://developer.yahoo.com/performance/rules.html#expires

Also, if you're using Angular.JS:

   - prepopulates the Angular template 
cachehttp://docs.angularjs.org/api/ng.%24templateCache with 
   your HTML templates.



https://github.com/magnars/optimus

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.