SlideShare une entreprise Scribd logo
1  sur  80
Sprockets
 You’ve got tons of JavaScript.
Time to do something about it.


     Christophe Porteneuve
        JSConf.eu 2009
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!
The problem
The problem

• JavaScript is the next big language…
The problem

• JavaScript is the next big language…
• It’s already getting big, codewise!
The problem

• JavaScript is the next big language…
• It’s already getting big, codewise!
• Many apps have countless JS files
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
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…
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
The solution
The solution

• You want to split your JS code in neat files
  and folders!
The solution

• You want to split your JS code in neat files
  and folders!
• You want some structure, dammit!
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!
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
So many cool things…
So many cool things…

• Use require directives and load paths to
  structure your source
So many cool things…

• Use require directives and load paths to
  structure your source

• Preprocess constants!
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
Getting organized
Getting organized




        …
        //= require "lang"
        //= require "ajax"
        //= require "dom"
Getting organized



        //=   require   "dom/dom"
        //=   require   "dom/selector"
        //=   require   "dom/form"
        //=   require   "dom/event"

        Element.addMethods();



        …
        //= require "lang"
        //= require "ajax"
        //= require "dom"
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"
The load path
Sprockets has a load path, much like C’s or
Ruby’s
The load path
Sprockets has a load path, much like C’s or
Ruby’s

Using the load path:
         //= require <coolobj>
         //= require <coollib/coolobj>
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"
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
Constants for you
Constants for you
Constants for you


        PROTOTYPE_VERSION: 1.6.1_rc3
Constants for you


        PROTOTYPE_VERSION: 1.6.1_rc3




        var Prototype = {
          Version: '<%= PROTOTYPE_VERSION %>',

         Browser: (function(){
           …
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)
I can haz?

• It’s a Ruby gem
• You don’t need to know Ruby though
• You do need Ruby and Rubygems installed
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
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
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
Within Ruby code…
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
As a CGI script…
         Say you have this tree
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
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>
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>
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>
…or use Rails!
…or use Rails!

$ script/plugin install git://github.com/sstephenson/sprockets-rails.git
…or use Rails!

$ script/plugin install git://github.com/sstephenson/sprockets-rails.git




ActionController::Routing::Routes.draw do |map|
  SprocketsApplication.routes(map)
  # ...
end
…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 %>
…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 %>
Hey, like to squeeze?
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)
YUI Compressor
YUI Compressor

• Arguably the best source shrinker out
  there
YUI Compressor

• Arguably the best source shrinker out
  there
• 100% safe yet full of optimizations
YUI Compressor

• Arguably the best source shrinker out
  there
• 100% safe yet full of optimizations
• Better than JSMin, ShrinkSafe, Packer…
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)
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
The gem wrapper
The gem wrapper
$ sudo gem install --remote yui-compressor
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"})();'
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…
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)
So what’s left?
So what’s left?


• Tweak your assets HTTP server: GZip and
  cache the heck on the client side
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
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/
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
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
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
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
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
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
Google Ajax Libraries API
Google Ajax Libraries API

• Google hosts most recent versions of
  Prototype, jQuery, script.aculo.us,
  MooTools, Dojo, Ext Core,YUI…
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
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!
Thank you, Sam.
Thank you, Sam.
•   Sprockets, Sprockets-Rails and
    YUI::Compressor are open-
    source stuff by Sam
    Stephenson, creator of
    Prototype.
Thank you, Sam.
•   Sprockets, Sprockets-Rails and
    YUI::Compressor are open-
    source stuff by Sam
    Stephenson, creator of
    Prototype.

•   http://github.com/sstephenson
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
Thank you!
   Any questions?



 Christophe Porteneuve
  tdd@tddsworld.com
     JSConf.eu 2009

Contenu connexe

Tendances

Nginx Workshop Aftermath
Nginx Workshop AftermathNginx Workshop Aftermath
Nginx Workshop AftermathDenis Zhdanov
 
Intro to Rails
Intro to Rails Intro to Rails
Intro to Rails epiineg1
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientAdam Wiggins
 
Rails Girls: Programming, Web Applications and Ruby on Rails
Rails Girls: Programming, Web Applications and Ruby on RailsRails Girls: Programming, Web Applications and Ruby on Rails
Rails Girls: Programming, Web Applications and Ruby on RailsDonSchado
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Plugin jQuery, Design Patterns
Plugin jQuery, Design PatternsPlugin jQuery, Design Patterns
Plugin jQuery, Design PatternsRobert Casanova
 
With a Mighty Hammer
With a Mighty HammerWith a Mighty Hammer
With a Mighty HammerBen Scofield
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101hendrikvb
 
HTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsHTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsRemy Sharp
 
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupScaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupKacper Gunia
 
A reviravolta do desenvolvimento web
A reviravolta do desenvolvimento webA reviravolta do desenvolvimento web
A reviravolta do desenvolvimento webWallace Reis
 
Rush, a shell that will yield to you
Rush, a shell that will yield to youRush, a shell that will yield to you
Rush, a shell that will yield to youguestdd9d06
 

Tendances (20)

Nginx Workshop Aftermath
Nginx Workshop AftermathNginx Workshop Aftermath
Nginx Workshop Aftermath
 
Intro to Rails
Intro to Rails Intro to Rails
Intro to Rails
 
Your JavaScript Library
Your JavaScript LibraryYour JavaScript Library
Your JavaScript Library
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
Lightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClientLightweight Webservices with Sinatra and RestClient
Lightweight Webservices with Sinatra and RestClient
 
Rails Girls: Programming, Web Applications and Ruby on Rails
Rails Girls: Programming, Web Applications and Ruby on RailsRails Girls: Programming, Web Applications and Ruby on Rails
Rails Girls: Programming, Web Applications and Ruby on Rails
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Plugin jQuery, Design Patterns
Plugin jQuery, Design PatternsPlugin jQuery, Design Patterns
Plugin jQuery, Design Patterns
 
Perl Dancer, FPW 2010
Perl Dancer, FPW 2010Perl Dancer, FPW 2010
Perl Dancer, FPW 2010
 
Troubleshooting Puppet
Troubleshooting PuppetTroubleshooting Puppet
Troubleshooting Puppet
 
With a Mighty Hammer
With a Mighty HammerWith a Mighty Hammer
With a Mighty Hammer
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101
 
HTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsHTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & sockets
 
Mojo as a_client
Mojo as a_clientMojo as a_client
Mojo as a_client
 
Composer
ComposerComposer
Composer
 
Dancing Tutorial
Dancing TutorialDancing Tutorial
Dancing Tutorial
 
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupScaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
 
A reviravolta do desenvolvimento web
A reviravolta do desenvolvimento webA reviravolta do desenvolvimento web
A reviravolta do desenvolvimento web
 
Rush, a shell that will yield to you
Rush, a shell that will yield to youRush, a shell that will yield to you
Rush, a shell that will yield to you
 
JSON and the APInauts
JSON and the APInautsJSON and the APInauts
JSON and the APInauts
 

En vedette

MAKALAH TA'ZIR FIQH JINAYAH PIDANA ISLAM
MAKALAH TA'ZIR FIQH JINAYAH PIDANA ISLAMMAKALAH TA'ZIR FIQH JINAYAH PIDANA ISLAM
MAKALAH TA'ZIR FIQH JINAYAH PIDANA ISLAMDian Oktavia
 
similarities & different between sharia & fiqh
similarities & different between sharia & fiqhsimilarities & different between sharia & fiqh
similarities & different between sharia & fiqhMunirah Najmah
 
Climate Change and the 5 rules of the environment
Climate Change and the 5 rules of the environmentClimate Change and the 5 rules of the environment
Climate Change and the 5 rules of the environmentjschmied
 
Presentation Ob Liana
Presentation Ob LianaPresentation Ob Liana
Presentation Ob Lianaqeqey
 
LWB486 Week 4 Copyright
LWB486 Week 4 CopyrightLWB486 Week 4 Copyright
LWB486 Week 4 CopyrightPeter Black
 
Ignite Paris 2009 - Is World of Warcraft the best leadership training solution?
Ignite Paris 2009 - Is World of Warcraft the best leadership training solution?Ignite Paris 2009 - Is World of Warcraft the best leadership training solution?
Ignite Paris 2009 - Is World of Warcraft the best leadership training solution?Charles Nouyrit
 
Cluetrain Manifesto
Cluetrain ManifestoCluetrain Manifesto
Cluetrain ManifestoRandee Bato
 
7 domande sulla creatività (estratto)
7 domande sulla creatività (estratto)7 domande sulla creatività (estratto)
7 domande sulla creatività (estratto)Giovanni Lucarelli
 
CS65 Presentation
CS65 PresentationCS65 Presentation
CS65 Presentationboyz26
 
Vertsol Theses 15-21 Powerpoint Slides
Vertsol Theses 15-21 Powerpoint SlidesVertsol Theses 15-21 Powerpoint Slides
Vertsol Theses 15-21 Powerpoint SlidesFrancis Guison
 
Build, host and manage your custom API in less than an hour
Build, host and manage your custom API in less than an hourBuild, host and manage your custom API in less than an hour
Build, host and manage your custom API in less than an hourJerome Louvel
 
Seri Sejarah Ekonomi Islam: faktor faktor yang mempengaruhi pemikiran ekonomi...
Seri Sejarah Ekonomi Islam: faktor faktor yang mempengaruhi pemikiran ekonomi...Seri Sejarah Ekonomi Islam: faktor faktor yang mempengaruhi pemikiran ekonomi...
Seri Sejarah Ekonomi Islam: faktor faktor yang mempengaruhi pemikiran ekonomi...Muhammad Jamhuri
 

En vedette (20)

Tafsir ayat qishos
Tafsir ayat qishosTafsir ayat qishos
Tafsir ayat qishos
 
MAKALAH TA'ZIR FIQH JINAYAH PIDANA ISLAM
MAKALAH TA'ZIR FIQH JINAYAH PIDANA ISLAMMAKALAH TA'ZIR FIQH JINAYAH PIDANA ISLAM
MAKALAH TA'ZIR FIQH JINAYAH PIDANA ISLAM
 
Islamic law sharia and fiqh
Islamic law   sharia and fiqhIslamic law   sharia and fiqh
Islamic law sharia and fiqh
 
similarities & different between sharia & fiqh
similarities & different between sharia & fiqhsimilarities & different between sharia & fiqh
similarities & different between sharia & fiqh
 
Climate Change and the 5 rules of the environment
Climate Change and the 5 rules of the environmentClimate Change and the 5 rules of the environment
Climate Change and the 5 rules of the environment
 
Nilai nilai Aqidah
Nilai nilai AqidahNilai nilai Aqidah
Nilai nilai Aqidah
 
Presentation Ob Liana
Presentation Ob LianaPresentation Ob Liana
Presentation Ob Liana
 
LWB486 Week 4 Copyright
LWB486 Week 4 CopyrightLWB486 Week 4 Copyright
LWB486 Week 4 Copyright
 
Ignite Paris 2009 - Is World of Warcraft the best leadership training solution?
Ignite Paris 2009 - Is World of Warcraft the best leadership training solution?Ignite Paris 2009 - Is World of Warcraft the best leadership training solution?
Ignite Paris 2009 - Is World of Warcraft the best leadership training solution?
 
Modern Times
Modern TimesModern Times
Modern Times
 
Smallbizdaily 2016 Hot Slides
Smallbizdaily 2016 Hot SlidesSmallbizdaily 2016 Hot Slides
Smallbizdaily 2016 Hot Slides
 
Cluetrain Manifesto
Cluetrain ManifestoCluetrain Manifesto
Cluetrain Manifesto
 
Manager HR In
Manager HR  InManager HR  In
Manager HR In
 
7 domande sulla creatività (estratto)
7 domande sulla creatività (estratto)7 domande sulla creatività (estratto)
7 domande sulla creatività (estratto)
 
CS65 Presentation
CS65 PresentationCS65 Presentation
CS65 Presentation
 
Gezinsbond
GezinsbondGezinsbond
Gezinsbond
 
Vertsol Theses 15-21 Powerpoint Slides
Vertsol Theses 15-21 Powerpoint SlidesVertsol Theses 15-21 Powerpoint Slides
Vertsol Theses 15-21 Powerpoint Slides
 
Clutrain Ppt
Clutrain PptClutrain Ppt
Clutrain Ppt
 
Build, host and manage your custom API in less than an hour
Build, host and manage your custom API in less than an hourBuild, host and manage your custom API in less than an hour
Build, host and manage your custom API in less than an hour
 
Seri Sejarah Ekonomi Islam: faktor faktor yang mempengaruhi pemikiran ekonomi...
Seri Sejarah Ekonomi Islam: faktor faktor yang mempengaruhi pemikiran ekonomi...Seri Sejarah Ekonomi Islam: faktor faktor yang mempengaruhi pemikiran ekonomi...
Seri Sejarah Ekonomi Islam: faktor faktor yang mempengaruhi pemikiran ekonomi...
 

Similaire à Sprockets

Fisl 11 - Dicas de Desenvolvimento Web com Ruby
Fisl 11 - Dicas de Desenvolvimento Web com RubyFisl 11 - Dicas de Desenvolvimento Web com Ruby
Fisl 11 - Dicas de Desenvolvimento Web com RubyFabio Akita
 
Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!cloudbring
 
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyConsegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyFabio Akita
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreEngineor
 
以Vue開發電子商務網站
架構與眉角
以Vue開發電子商務網站
架構與眉角以Vue開發電子商務網站
架構與眉角
以Vue開發電子商務網站
架構與眉角Mei-yu Chen
 
Socket applications
Socket applicationsSocket applications
Socket applicationsJoão Moura
 
Container (Docker) Orchestration Tools
Container (Docker) Orchestration ToolsContainer (Docker) Orchestration Tools
Container (Docker) Orchestration ToolsDhilipsiva DS
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVCAlive Kuo
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers StealBen Scofield
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principlesPerl Careers
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
Build Your Own CMS with Apache Sling
Build Your Own CMS with Apache SlingBuild Your Own CMS with Apache Sling
Build Your Own CMS with Apache SlingBob Paulin
 
Single Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle StorySingle Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle StoryKon Soulianidis
 

Similaire à Sprockets (20)

Fisl 11 - Dicas de Desenvolvimento Web com Ruby
Fisl 11 - Dicas de Desenvolvimento Web com RubyFisl 11 - Dicas de Desenvolvimento Web com Ruby
Fisl 11 - Dicas de Desenvolvimento Web com Ruby
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!
 
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyConsegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack Encore
 
以Vue開發電子商務網站
架構與眉角
以Vue開發電子商務網站
架構與眉角以Vue開發電子商務網站
架構與眉角
以Vue開發電子商務網站
架構與眉角
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
Container (Docker) Orchestration Tools
Container (Docker) Orchestration ToolsContainer (Docker) Orchestration Tools
Container (Docker) Orchestration Tools
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
 
Great Developers Steal
Great Developers StealGreat Developers Steal
Great Developers Steal
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Death of a Themer
Death of a ThemerDeath of a Themer
Death of a Themer
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principles
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 
Git::Hooks
Git::HooksGit::Hooks
Git::Hooks
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
infra-as-code
infra-as-codeinfra-as-code
infra-as-code
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
Build Your Own CMS with Apache Sling
Build Your Own CMS with Apache SlingBuild Your Own CMS with Apache Sling
Build Your Own CMS with Apache Sling
 
Single Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle StorySingle Page JavaScript WebApps... A Gradle Story
Single Page JavaScript WebApps... A Gradle Story
 

Dernier

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 

Dernier (20)

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 

Sprockets

  • 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!
  • 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
  • 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
  • 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
  • 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
  • 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>
  • 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)
  • 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
  • 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)
  • 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
  • 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!
  • 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.
  • 80. Thank you! Any questions? Christophe Porteneuve tdd@tddsworld.com JSConf.eu 2009