<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Robby on Rails: Tag yslow</title>
    <link>http://www.robbyonrails.com/articles/tag/yslow</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>thoughts.sort_by{|t| t[:topic]}.collect </description>
    <item>
      <title>YSlow and Rails performance: Getting UJS and AssetPackager to play nice  </title>
      <description>&lt;p&gt;Yesterday, I started to dig deeper into &lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow&lt;/a&gt; and decided to pick an application that we recently launched for a client. The performance grade that I saw at first was an F, which wasn&amp;#8217;t surprising to me because we knew that there was going to be some fine tuning in the near future.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://myskitch.com/robbyrussell/30elm___assets-20070727-100946.jpg" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;There is a lot of JavaScript in this application and we have several files to break up stuff to make it more maintainable. However, in production, we really don&amp;#8217;t need to send the client (browser) 19 different JS files. We&amp;#8217;ve been using mod_deflate to compress these files, but it doesn&amp;#8217;t solve the problem of having several connections opening to download all the necessary JavaScript. The same is true for our &lt;span class="caps"&gt;CSS&lt;/span&gt; files.&lt;/p&gt;


	&lt;p&gt;At RailsConf, &lt;span class="caps"&gt;DHH&lt;/span&gt; announced that an upcoming version of Rails would bundle all the stylesheet and javascript files into one file and compress it. We&amp;#8217;re running on 1.2.x for this application and decided to look at the &lt;a href="http://synthesis.sbecker.net/pages/asset_packager"&gt;AssetPackager plugin&lt;/a&gt; as a good solution to this problem.&lt;/p&gt;


	&lt;p&gt;I installed the plugin via &lt;a href="http://piston.rubyforge.org/"&gt;piston&lt;/a&gt; and ran the following task, which is provided by AssetPackager.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;rake asset:packager:create_yml&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This went ahead and created &lt;code&gt;config/assets_packager.yml&lt;/code&gt;. I then went ahead and updated our capistrano configuration to call the rake task after updating the code on the server when deploying.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
desc "all of our other tasks/commands to run after updating the code" 
task :after_update_code do
  #
  # all of our other tasks/commands
  #
  run "cd #{release_path} &amp;#38;&amp;#38; rake RAILS_ENV=production asset:packager:build_all" 
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The first thing that I noticed was that the yml file that gets generated will not make any assumption as to what order the javascript libraries should be loaded. So, immediately, line 1 of our compressed javascript file was causing an error as the code was trying to reference a library that hadn&amp;#8217;t been defined yet (showed up later in the file). So, when you do this, you&amp;#8217;ll need to organize the yml file to load things in order that they are needed. This was also a good opportunity for us to say, &amp;#8220;oh, we&amp;#8217;re not using that one anymore. Let&amp;#8217;s remove it.&amp;#8221;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
--- 
javascripts: 
- base: 
  - prototype  
  - effects
  - scriptaculous
  - controls
  - dragdrop
  - application
  - slider
  - pngfix
  - nav
  - lowpro
  - lightbox
  - folder
  - builder
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Great, so we re-dployed and everything at first glance seemed fine&amp;#8230; &lt;em&gt;or so we thought!&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;We used the &lt;a href="http://www.ujs4rails.com/"&gt;unobtrusive javascript plugin&lt;/a&gt; for this project and it seems that we couldn&amp;#8217;t just compress every single file. Each page has a behaviors javascript file and since everything was being compressed into one file (and cached), &lt;span class="caps"&gt;RJS&lt;/span&gt; calls quickly broke throughout the site. &lt;strong&gt;&lt;span class="caps"&gt;OH NO&lt;/span&gt;!&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;So, I opted to merge all of the other javascript files and use the standard way of including unobtrusive javascript in the application layout.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
&amp;lt;%= javascript_include_merged :base %&amp;gt;
&amp;lt;%= javascript_include_tag :unobtrusive %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;We also removed &lt;code&gt;lowpro&lt;/code&gt; from the list of javascript files to compress since the ujs plugin is currently including this when we call &lt;code&gt;&amp;lt;%= javascript_include_tag :unobtrusive %&amp;gt;&lt;/code&gt;. I plan to look into modifying this so we it&amp;#8217;ll only include the page-specific behaviors and not load the lowpro javascript file (so we can compress that as well).&lt;/p&gt;


	&lt;p&gt;Once this was re-deployed, we saw that the &lt;span class="caps"&gt;RJS&lt;/span&gt; issues were resolved and everything felt to be loading quicker. But, let&amp;#8217;s look at YSlow again for step 1 in improving the performance of the application.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;side note:&lt;/strong&gt; the following grading was also after making some other adjustments that were suggested by YSlow, which I&amp;#8217;ll discuss in another blog post soon.&lt;/p&gt;


	&lt;p&gt;So, where we once had a grade F, we now have an D&amp;#8230; which is due to the client having us add several (four) external javascript files for mint, google analytics, etc. We&amp;#8217;re only loading 3 javascript files for the application, when we were originally loading many more.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://myskitch.com/robbyrussell/30elm___your_address_for_home_design-20070727-114427.jpg" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Obviously, there is some more tuning to be done, but we went from a grading of 43 to 74 in about three hours of time spent reading the YSlow documentation, adding asset_packager, and making various tweaks to our web servers (as suggested by YSlow).&lt;/p&gt;


	&lt;p&gt;Until next time&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Related Posts:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.robbyonrails.com/articles/2007/01/16/every-second-counts-with-a-piston-in-your-trunk"&gt;Every Second Counts with a Piston in your Trunk&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
</description>
      <pubDate>Fri, 27 Jul 2007 13:40:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:e47a0bfa-0fff-42da-90a6-0c95701cdcc3</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2007/07/27/yslow-and-rails-performance-getting-ujs-and-assetpackager-to-play-nice</link>
      <category>Ruby on Rails</category>
      <category>Ruby</category>
      <category>Programming</category>
      <category>assets</category>
      <category>javascript</category>
      <category>rails</category>
      <category>performance</category>
      <category>yslow</category>
      <category>rubyonrails</category>
      <category>deployment</category>
      <category>capistrano</category>
      <category>compression</category>
      <category>hosting</category>
    </item>
  </channel>
</rss>
