At a glance they seem to be pretty much the same solution to the same problem, but Jammit must have some key difference or improvement that I haven't picked up on, or its author would have just used asset_packager. :-)
Can anyone enlighten me?
Sure. Here's some of the main differences:
Instead of using simple Ruby-based CSS and JS minifiers, Jammit makes it easy to use either the YUI Compressor or the new Google Closure Compiler to compress your assets.
Instead of having to specify each file individually, Jammit uses an ordered list of directory globs to define an asset package. This means you can say things like: give me jQuery first, then everything in vendor, then all my models, then all my UI...
workspace:
vendor/jquery.js
vendor/*.js
models/**/*.js
view/workspace/*.js
Jammit supports JavaScript Templates, so whether you're using Prototype or Mustache or Underscore templates, you can maintain your JavaScript views right alongside your Rails views, and have them bundled into a single package, available in the browser.
Jammit supports image embedding, using Data-URIs for browsers that support them, and MHTML for IE7 and below. Enabling it allows you to embed all of your UI chrome and small icons right into your CSS, so that instead of 50 HTTP requests, your browser makes just one.
When you install the gem, Jammit includes the jammit command-line utility, which you can use to prebuild all of your assets and pre-gzip them at the highest compression level. Gzipping at --9 gives us about a 30% reduction in size for our assets, over the default gzip --2 (which is closer to what you'll get by default if you're gzipping on-the-fly). You should be using both, but only gzipping on-demand for dynamic requests.
Hope that helps with the differences -- for everything else, there's http://documentcloud.github.com/jammit/
Related
I want to add frameworks like AngularJS, Bootstrap and polymer JS into my rails app. Problem with the gems is they are unstable with new versions and they even stop developing gems(which leads to failing of one gem which depends on another)
So I just want to add those frameworks directly into the application root html file via CDN(offered by the vendor). Is that a good practice? Will it cause any future problems in production environment?
Yes, if you are using reliable CDN's (and those offered my vendors can be treat as one) it may even bring you some improvements in the production enviromnent, e.g.:
those assets will be often already cached on your user's machines
it circumvents browsers limit the number of concurrent connections from the same domain (as your app)
On the flip side, on your dev enviromnent you'll have to wait a liiitle bit more for the website to load those assets comparing it to loading them from localhost ;)
if you dont use CDN,you have much control over the assets ,as they might change/update or sometimes the url can be down :( in worst case scenario..so i suggest using local assets if there is large dependency and for small dependency ...you may use cdn. :)
use this to set up polymer js onlocal.
So that I could take advantage of all the already well developed front-end tools like requirejs, bower and grunt... It's just that so many of them somehow get crippled going with rails.
Primary advantages:
It is easier to load third party scripts this way. It is always possible and sometimes easy to put these through the asset pipeline, but it is also often tedious and you lose bower.
Scripts in public will not be digested, so they can be loaded by non-rails pages easily. For example, you use a javascript file on your site, and also need to load it on another, e.g., PHP site, or need to allow other people to load your script for an embedded API, etc... then you'll need to serve from public.
Primary disadvantages:
Because you're not using the asset pipeline you lose:
Asset combining and compression. Asset pipeline CSS and Javascript will be loaded in a single HTTP request each, and the content can be minified. This makes first page load on your site faster, especially if you have lots of client code or a site that needs to be super snappy for occasional visitors.
Digesting. The asset pipeline protects you 100% from cache vagaries and potentially having different users seeing your site with different version of your assets. Once you deploy, every visitor will get the new assets.
Relatively automatic etagging. Once those visitors get the new assets, their clients will generally cache them for a long time. Rails can afford to let assets cache essentially forever because digesting ensures you're not punished for this later.
So there are pros and const both ways and neither is right or wrong.
It's just that so many of them somehow get crippled going with rails
Pipeline
The reason is you're not meant to use the likes of Grunt etc with Rails. Rails' asset pipeline is only meant to contain the files which can be precompiled & used directly in your application:
The asset pipeline provides a framework to concatenate and minify or
compress JavaScript and CSS assets. It also adds the ability to write
these assets in other languages and pre-processors such as
CoffeeScript, Sass and ERB.
This will typically mean compiled third party JS/CSS files, and your own application JS/CSS files. I don't see how something like Grunt would provide any benefit to this? All it does it create a way for you to manage dependencies, versioning & source of particular assets?
--
Public
Using the files in your public folder isn't such a big deal. One of the most prominent things it does do is to exclude those particular files from the file digest processs, allowing you to use the likes of endpoints (scripts) which can be accessed by other services (outside the scope of routes.rb)
A good example of this is when we created an analytics system, and put the analytics.js into the public folder, so all the widgets could access it. This allowed other sites to access this file, regardless of the state of the asset pre-compilation.
One caveat to this would be you could perhaps have some way to store a "pseudo" file in the public folder, with it routing dynamically (with ERB) to the precompiled equivalent, but I've got no experience with this
--
Pipeline
The benefits of keeping your assets inside the asset pipeline, as stated by gwcoffey, are:
They will be compiled as you design (I.E primarily into application.js, but also into any other files you define too)
You don't need to worry about versioning (every precompile is basically a way to better the version without worrying about grunt etc)
You can include as many dependencies as you want - meaning you're able to create a totally modular set of assets which can be used throughout your app; rather than single scripts which will have their own dependency base
Recommendation
Unless you maintain third-party scripts which need dependencies to run, I would not recommend using Grunt for Rails. If you develop your own JQuery / Javascript scripts, by all means run them through Grunt etc; but for use in your app, I'd steer clear
Hope that helps!
I'm going to start a rich client-side web application with Ruby on Rails 3.2. I intended to use RequireJS, but it seems to collide with the Asset Pipeline. As far as I know, what the latter basically does is concatenating dependent assets, minifiying and compressing them (correct me if I'm wrong), which does not seem very compatible with loading JavaScript files asychronously.
At a first glance, the Asset Pipeline seems to have much better performance. However, RequireJS lets you organize the JavaScript code in modules easy to reuse and mange its dependencies.
Is there any way to combine both of them? In case there isn't, which one would you choose?
You might want to have a look at this gem https://github.com/jwhitley/requirejs-rails/
Seems to be doing what you want - which is to use requirejs for loading client side while still taking advantage of some of the asset pipeline.
I would be tempted to suggest that I guess that in most cases the asset pipeline would be much faster as it loads a single minified js resource. The dependency management isn't as good though, so it would very much depend on the app.
I would suggest to download the RequireJS library and toss it to vendor/assets/javascripts. Then in your application.js file :
//= require require
(funny , yes?) , and that should be enough.
This is the easiest way to combine the asset-pipeline and a modular js library . I am not aware of any additional settings this particular library needs , but you can take a look at this Railscast , which describes something similar.
I am interested in the pros and cons of the different tools for managing assets in Rails 3.0.x (especially on Heroku).
There are already some older questions regarding this topic, but in the meanwhile there are some new tools available.
I am especially interested in these tools:
Jammit
AssetHat
Rack PageSpeed
Jammit seems to can do everything that AssetHat can do and is also longer available. So where does AssetHat fit in?
Rack PageSpeed seems to do everything on the fly by directly working on the server response. Did you experience any performance issues by doing that? Would you recommend it over the other two solutions?
Hey there, I'm the author of AssetHat. Minification and concatenation are among the easiest performance boosts to implement; these features are common to Jammit, AssetHat, and rack-pagespeed. Rails has supported concatenation for a long time now (though it's done at runtime, rather than during deployment), and it's no surprise that Rails 3.1 supports both minification and concatenation during deployment.
The remaining features are what make each of these asset managers interesting. For example, Jammit is useful if you want to embed images and font files directly into your stylesheets. rack-pagespeed is also handy if you want to keep all your optimizations in a completely separate layer.
Inlining assets into CSS is great for static pages where stylesheets change infrequently. However, if your site is under active development, and the stylesheet changes even a tiny bit, the user's browser has to re-download the whole thing—including inline images and fonts that probably didn't change. It depends on the nature of your project.
If your assets are too big to inline or concatenate, AssetHat helps optimize for CDNs and parallel loading:
It takes great advantage of CDNs, whether it's Google's CDN, cdnjs (which uses Amazon's servers), or another CDN of your choosing. For example, just add <%= include_js :jquery %> to your layout (and a version number in a config file) to load jQuery from Google's CDN. If you're in dev mode and have a local copy of jQuery, that loads instead—easy offline dev.
AssetHat can rewrite stylesheets' image URLs to use your CDN instead. This reads from your config.action_controller.asset_host setting, and is done at deploy time. Your original CSS is left untouched.
If you have several JS files to load, it's sometimes faster to load them in parallel than to concatenate them (i.e., force them to load serially). You can switch on LABjs mode easily: <%= include_js 'big-file-1', ..., 'big-file-n', :loader => :lab_js %>. If you don't have a copy of LABjs locally, or if you're in production, LABjs loads from Amazon's servers via cdnjs.
By using CDNs like Google's or Amazon's, your users can load more assets in parallel (because there are more hostnames), enjoy greater speed, and sometimes, not even need to download assets at all (e.g., if they already loaded Google's copy of jQuery via someone else's website).
I've used AssetHat on Heroku by setting my deploy script to simply run rake asset_hat:minify (to minify and concatenate CSS/JS), commit those changes to my repository, then do the actual deployment.
In case you haven't seen these already, you might be interested in:
a longer walkthrough of AssetHat's features
the official website
the technical readme
the extensive docs
If you need help setting it up, or have any other questions, feel free to message me on GitHub (rondevera) or Twitter (#ronalddevera).
Jammit won't work out of the box on Heroku as far as I know. One option seems to be to use the Heroku Jammit plugin to manage your assets - https://github.com/chebyte/heroku-jammit.
Alternatively, Jammit can be configured to output to /tmp: http://geekninja.blogspot.com/2011/04/making-jammit-jam-with-heroku.html
Rails 3.1 will include Sprockets to handle asset packaging, I think that's worth considering.
I am currently using jammit on heroku, together with amazon s3, and it works like a charm :)
I can't say much about the others tools because I have not used them.
Which one did you pick, in the end?
Fernando.
I'm currently working on a large, highly trafficked Ruby on Rails website and in order to get our page load times down, we are looking at spriting our background images. There seem to be a lot of tools out there but many are in the early stages of dev and many don't support some of the features we need.
Features which are important to us:
x or y repeating
automation with our rake build
transparency
generates sprite image and css automatically
mature
easy to maintain
open source
If it was written in Ruby, that would be a bonus but is not essential as long as it can integrate with a rake/cap setup.
Are there any css sprite tools out there which fit most(all?) of these criteria?
Rather than spriting images, why not use data-uri? Jammit can generate CSS files with small images compiled in as data-uri objects. This is actually even more performant than sprite sheets, because it means that you only have one HTTP connection for the stylesheet, rather than one for the stylesheet and one for the sprite sheet.
To use it, you just have your small images (icons, repeating backgrounds, etc) referenced with /embed/ in the path somewhere, and it'll generate data-uri, MHTML, and plain versions of your stylesheets for serving to various browsers.
Jammit also does compilation of multiple stylesheets (and Javascripts) into one file (per type), and can make use of some Javascript templating stuff too, if you want to get super-optimized with your AJAX responses.
Downsides are that a) if you reference an image more than once, it gets compiled in for each reference, and b) changing an image results in clients needing to re-download your whole stylesheet. However, since those assets generally change fairly rarely, it can be a solution that results in far faster page loads without adding any additional overhead to your development process.
To mitigate both of those, you could have a separate stylesheet that is just for image references, so you'd have one stylesheet for normal layouts, and then another that all your data-uri resources get compiled into. This would result in two HTTP requests, but it means that you could change your CSS or your embedded images without forcing a re-download of the whole other half of your styling.
One big negative about Chris's suggestion to use data-uri via Jammit, is that it doesn't support IE6/7.
There's this new gem called active_assets that gives you full sprite integration with your rails stack. Check it out at github. The gem let's you define your sprites including the list of images to include in the sprite and then generates the sprite and the corresponding stylesheet. The readme at the above link has all the info.