Your SlideShare is downloading. ×
Sprockets
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

Sprockets

10,160
views

Published on

Sprockets is an easy solution to managing large JavaScript codebases by letting you structure it, bundle it with related assets, and consolidate it as one single file, with pre-baked command-line …

Sprockets is an easy solution to managing large JavaScript codebases by letting you structure it, bundle it with related assets, and consolidate it as one single file, with pre-baked command-line tooling, CGI front and Rails plugin. It's a framework-agnostic open-source solution that makes for great serving performance while helping you structure and manage your codebase better.

Published in: Technology

0 Comments
18 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
10,160
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
92
Comments
0
Likes
18
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • Transcript

    • 1. Sprockets You’ve got tons of JavaScript. Time to do something about it. Christophe Porteneuve JSConf.eu 2009
    • 2. Hi, I’m Christophe • I’m 32 and I live in Paris, France • I use Rails all day at work • I’m a Prototype Core member • I wrote Prototype and script.aculo.us (“The Bungee Book”) • I’m glad to be here!
    • 3. The problem
    • 4. The problem • JavaScript is the next big language…
    • 5. The problem • JavaScript is the next big language… • It’s already getting big, codewise!
    • 6. The problem • JavaScript is the next big language… • It’s already getting big, codewise! • Many apps have countless JS files
    • 7. The problem • JavaScript is the next big language… • It’s already getting big, codewise! • Many apps have countless JS files • Loading → lots of requests → latence
    • 8. The problem • JavaScript is the next big language… • It’s already getting big, codewise! • Many apps have countless JS files • Loading → lots of requests → latence • Or you could maintain one big file…
    • 9. The problem • JavaScript is the next big language… • It’s already getting big, codewise! • Many apps have countless JS files • Loading → lots of requests → latence • Or you could maintain one big file… • …which sucks
    • 10. The solution
    • 11. The solution • You want to split your JS code in neat files and folders!
    • 12. The solution • You want to split your JS code in neat files and folders! • You want some structure, dammit!
    • 13. The solution • You want to split your JS code in neat files and folders! • You want some structure, dammit! • But you want to serve just one file!
    • 14. The solution • You want to split your JS code in neat files and folders! • You want some structure, dammit! • But you want to serve just one file! • Enter Sprockets
    • 15. So many cool things…
    • 16. So many cool things… • Use require directives and load paths to structure your source
    • 17. So many cool things… • Use require directives and load paths to structure your source • Preprocess constants!
    • 18. So many cool things… • Use require directives and load paths to structure your source • Preprocess constants! • Create “JS plugins,” complete with related CSS/image assets, bundle them and distribute them easily
    • 19. Getting organized
    • 20. Getting organized … //= require "lang" //= require "ajax" //= require "dom"
    • 21. Getting organized //= require "dom/dom" //= require "dom/selector" //= require "dom/form" //= require "dom/event" Element.addMethods(); … //= require "lang" //= require "ajax" //= require "dom"
    • 22. Getting organized //= require "ajax/ajax" //= require "ajax/responders" //= require "ajax/base" //= require "ajax/request" //= require "ajax/response" //= require "ajax/updater" //= require "ajax/periodical_updater" //= require "dom/dom" //= require "dom/selector" //= require "dom/form" //= require "dom/event" Element.addMethods(); … //= require "lang" //= require "ajax" //= require "dom"
    • 23. The load path Sprockets has a load path, much like C’s or Ruby’s
    • 24. The load path Sprockets has a load path, much like C’s or Ruby’s Using the load path: //= require <coolobj> //= require <coollib/coolobj>
    • 25. The load path Sprockets has a load path, much like C’s or Ruby’s Using the load path: //= require <coolobj> //= require <coollib/coolobj> Using paths relative to the current file: //= require "coolobj" //= require "subdir/coolobj"
    • 26. Constants FTW! Put a constants.yml file somewhere in your load path • It’s a YAML file • Heard of YAML, right? • Super simple yet powerful
    • 27. Constants for you
    • 28. Constants for you
    • 29. Constants for you PROTOTYPE_VERSION: 1.6.1_rc3
    • 30. Constants for you PROTOTYPE_VERSION: 1.6.1_rc3 var Prototype = { Version: '<%= PROTOTYPE_VERSION %>', Browser: (function(){ …
    • 31. Bundling assets //= require "color" //= provide "../assets" Because you require <color_picker>, Sprockets can copy the assets to your asset root (somewhere inside your document root)
    • 32. I can haz? • It’s a Ruby gem • You don’t need to know Ruby though • You do need Ruby and Rubygems installed
    • 33. I can haz? • It’s a Ruby gem • You don’t need to know Ruby though • You do need Ruby and Rubygems installed $ sudo gem install --remote sprockets
    • 34. As a command-line tool… $ sprocketize Usage: sprocketize [options] filename [filename ...] -C, --directory=DIRECTORY Change to DIRECTORY before doing anything -I, --include-dir=DIRECTORY Adds the directory to the Sprockets load path -a, --asset-root=DIRECTORY Copy provided assets into DIRECTORY … -h, --help Shows this help message -v, --version Shows version
    • 35. As a command-line tool… $ sprocketize Usage: sprocketize [options] filename [filename ...] -C, --directory=DIRECTORY Change to DIRECTORY before doing anything -I, --include-dir=DIRECTORY Adds the directory to the Sprockets load path -a, --asset-root=DIRECTORY Copy provided assets into DIRECTORY … -h, --help Shows this help message -v, --version Shows version $ sprocketize -I src -a dist src/application.js > dist/javascripts/application.js
    • 36. Within Ruby code…
    • 37. Within Ruby code… require 'rubygems' require 'sprockets' secretary = Sprockets::Secretary.new( :asset_root => "public", :load_path => ["vendor/sprockets/*/src", "vendor/plugins/*/javascripts"], :source_files => ["app/javascripts/application.js", "app/javascripts/**/*.js"] ) concatenation = secretary.concatenation concatenation.save_to("public/sprockets.js") secretary.install_assets
    • 38. As a CGI script… Say you have this tree
    • 39. As a CGI script… Say you have this tree :load_path: - javascripts - vendor/sprockets/*/src :source_files: - javascripts/mysite.js - javascripts/*.js :output_file: public/sprockets.js So you write this sprockets.yml
    • 40. As a CGI script… <VirtualHost *:80> ServerName www.sprocketsrule.com DocumentRoot "/var/webapps/sprocketsrule/public" <Directory "/var/webapps/sprocketsrule/public"> Options +ExecCGI +FollowSymLinks AddHandler cgi-script .cgi RewriteEngine on RewriteCond /sprockets.js !-f RewriteRule ^sprockets.js /nph-sprockets.cgi [P,L] SetEnv sprockets_generate_output_file true </Directory> </VirtualHost> <script type="text/javascript" src="/sprockets.js"></script>
    • 41. As a CGI script… <VirtualHost *:80> ServerName www.sprocketsrule.com DocumentRoot "/var/webapps/sprocketsrule/public" <Directory "/var/webapps/sprocketsrule/public"> Options +ExecCGI +FollowSymLinks Provided in the ext/ AddHandler cgi-script .cgi directory of Sprockets RewriteEngine on RewriteCond /sprockets.js !-f RewriteRule ^sprockets.js /nph-sprockets.cgi [P,L] SetEnv sprockets_generate_output_file true </Directory> </VirtualHost> <script type="text/javascript" src="/sprockets.js"></script>
    • 42. As a CGI script… <VirtualHost *:80> T ServerName www.sprocketsrule.com A DocumentRoot "/var/webapps/sprocketsrule/public" N E <Directory "/var/webapps/sprocketsrule/public"> Options +ExecCGI +FollowSymLinks Provided in the ext/ AddHandler cgi-script .cgi directory of Sprockets RewriteEngine on RewriteCond /sprockets.js !-f RewriteRule ^sprockets.js /nph-sprockets.cgi [P,L] SetEnv sprockets_generate_output_file true </Directory> </VirtualHost> <script type="text/javascript" src="/sprockets.js"></script>
    • 43. …or use Rails!
    • 44. …or use Rails! $ script/plugin install git://github.com/sstephenson/sprockets-rails.git
    • 45. …or use Rails! $ script/plugin install git://github.com/sstephenson/sprockets-rails.git ActionController::Routing::Routes.draw do |map| SprocketsApplication.routes(map) # ... end
    • 46. …or use Rails! $ script/plugin install git://github.com/sstephenson/sprockets-rails.git ActionController::Routing::Routes.draw do |map| SprocketsApplication.routes(map) # ... end <%= sprockets_include_tag %>
    • 47. …or use Rails! O M E S $ script/plugin install git://github.com/sstephenson/sprockets-rails.git A W E ActionController::Routing::Routes.draw do |map| SprocketsApplication.routes(map) # ... end <%= sprockets_include_tag %>
    • 48. Hey, like to squeeze?
    • 49. Hey, like to squeeze? Just because it’s one big file doesn’t mean it’s one small file (that didn’t come out right)
    • 50. YUI Compressor
    • 51. YUI Compressor • Arguably the best source shrinker out there
    • 52. YUI Compressor • Arguably the best source shrinker out there • 100% safe yet full of optimizations
    • 53. YUI Compressor • Arguably the best source shrinker out there • 100% safe yet full of optimizations • Better than JSMin, ShrinkSafe, Packer…
    • 54. YUI Compressor • Arguably the best source shrinker out there • 100% safe yet full of optimizations • Better than JSMin, ShrinkSafe, Packer… • Does not obfuscate (which is good)
    • 55. YUI Compressor • Arguably the best source shrinker out there • 100% safe yet full of optimizations • Better than JSMin, ShrinkSafe, Packer… • Does not obfuscate (which is good) • Distributed as a JAR file
    • 56. The gem wrapper
    • 57. The gem wrapper $ sudo gem install --remote yui-compressor
    • 58. The gem wrapper $ sudo gem install --remote yui-compressor compressor = YUI::JavaScriptCompressor.new(:munge => true) compressor.compress('(function () { var foo = {}; foo["bar"] = "baz"; })()') # => '(function(){var a={};a.bar="baz"})();'
    • 59. The gem wrapper $ sudo gem install --remote yui-compressor compressor = YUI::JavaScriptCompressor.new(:munge => true) compressor.compress('(function () { var foo = {}; foo["bar"] = "baz"; })()') # => '(function(){var a={};a.bar="baz"})();' YUI::JavaScriptCompressor.new( :java => "/usr/bin/java", :jar_file => "/path/to/my/yuicompressor-2.4.2.jar" ) Full compressor support: CSS too, options aplenty…
    • 60. A match made in heaven # config/sprockets.yml :asset_root: public :load_path: - app/javascripts - vendor/sprockets/*/src - vendor/plugins/*/javascripts :source_files: - app/javascripts/application.js - app/javascripts/**/*.js :compress: :munge: true Warning: not in master gems yet. See my forks. (incidentally, in production use at http://letsfreckle.com)
    • 61. So what’s left?
    • 62. So what’s left? • Tweak your assets HTTP server: GZip and cache the heck on the client side
    • 63. So what’s left? • Tweak your assets HTTP server: GZip and cache the heck on the client side • If necessary, offload mainstream libs serving to Google
    • 64. Apache config you’ll love LoadModule deflate_module /usr/lib/apache2/modules/mod_deflate.so LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so LoadModule expires_module /usr/lib/apache2/modules/mod_expires.so AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml ↪application/xhtml+xml text/javascript text/css application/x-javascript ExpiresActive On ExpiresByType image/gif "access plus 5 years" ExpiresByType image/png "access plus 5 years" ExpiresByType image/jpeg "access plus 5 years" ExpiresByType text/javascript "access plus 5 years" ExpiresByType application/x-javascript "access plus 5 years" ExpiresByType text/css "access plus 5 years" Header unset ETag FileETag None Header add Cache-Control "public" http://javascriptrocks.com/performance/
    • 65. Numbers! No opti. All opti. Bytes 292.520 30.919 HTTP requests 3 / 38* 1 Load time (unprimed) 1900+456ms 400+43ms Load time (primed) 1900+76ms 1+41ms * monolithic vendor scripts / structured source
    • 66. Numbers! No opti. All opti. Bytes 292.520 30.919 HTTP requests 3 / 38* 1 Load time (unprimed) 1900+456ms 400+43ms Load time (primed) 1900+76ms 1+41ms * monolithic vendor scripts / structured source
    • 67. Numbers! No opti. All opti. Bytes 292.520 30.919 HTTP requests 3 / 38* 1 Load time (unprimed) 1900+456ms 400+43ms Load time (primed) 1900+76ms 1+41ms * monolithic vendor scripts / structured source
    • 68. Numbers! No opti. All opti. Bytes 292.520 30.919 HTTP requests 3 / 38* 1 Load time (unprimed) 1900+456ms 400+43ms Load time (primed) 1900+76ms 1+41ms * monolithic vendor scripts / structured source
    • 69. Numbers! No opti. All opti. Bytes 292.520 30.919 HTTP requests 3 / 38* 1 Load time (unprimed) 1900+456ms 400+43ms Load time (primed) 1900+76ms 1+41ms * monolithic vendor scripts / structured source
    • 70. Numbers! V No opti. All opti. Bytes Y M HTTP requests Load time (unprimed) M 292.520 3 / 38* 1900+456ms 30.919 400+43ms 1 Load time (primed) 1900+76ms 1+41ms * monolithic vendor scripts / structured source
    • 71. Google Ajax Libraries API
    • 72. Google Ajax Libraries API • Google hosts most recent versions of Prototype, jQuery, script.aculo.us, MooTools, Dojo, Ext Core,YUI…
    • 73. Google Ajax Libraries API • Google hosts most recent versions of Prototype, jQuery, script.aculo.us, MooTools, Dojo, Ext Core,YUI… • Top-notch serving (e.g. cache-related headers + GZipping) + CDN
    • 74. Google Ajax Libraries API • Google hosts most recent versions of Prototype, jQuery, script.aculo.us, MooTools, Dojo, Ext Core,YUI… • Top-notch serving (e.g. cache-related headers + GZipping) + CDN • Bonus: if another site loaded it already, your user doesn’t have to load it for your site!
    • 75. Thank you, Sam.
    • 76. Thank you, Sam. • Sprockets, Sprockets-Rails and YUI::Compressor are open- source stuff by Sam Stephenson, creator of Prototype.
    • 77. Thank you, Sam. • Sprockets, Sprockets-Rails and YUI::Compressor are open- source stuff by Sam Stephenson, creator of Prototype. • http://github.com/sstephenson
    • 78. Thank you, Sam. • Sprockets, Sprockets-Rails and YUI::Compressor are open- source stuff by Sam Stephenson, creator of Prototype. • http://github.com/sstephenson • http://github.com/tdd
    • 79. Thank you! Any questions? Christophe Porteneuve tdd@tddsworld.com JSConf.eu 2009