niedziela, 22 maja 2011

Get faster rails development environment for Rails 3.0.7 in few seconds

I would like to describe two techniques for speeding up your Rails development environment.

Faster rendering



All credits for mentioning this goes to Eric.

This will only be helpful if your view renders lot of small partials. Ex. you render a big table and every cell is rendered by the same partial.



Faster code reloading



Rails "forgets" your code after every request so that next time the code is loaded again using autoloading. However this is totally unnecessary if you don't change the code between requests. Let's reload the code before every request if the code changes between them.

We use 'config/environments/development.rb' to execute watchr script for observing files. We only want to observer them when 'rails server' command was executed. In 'rails console' mode we use the 'reload!' command for manual code reloading.


The watchr script is going to update modification time of '.watchr' file and notify us about it if we want. You can enable this functionality by creating 'config/watchr.notify' file. Simple remove the file to disable it. Obviously you might need to change it a little bit to work under OS X.


Add the 'config/watchr.nofity' file to .gitignore so every member of your team can have its own settings:


Create the empty '.watchr' file which is needed only for reading and updating its mtime.


Change your 'Gemfile' to include watchr gem and point rails to my branch which contains commit that changes code reloading to be executed before request:


As you can see in the mentioned commit the mtime of '.watchr' file is used to discover whether changes occurred or not:


Your application code won't reload faster but it will only reload when it is necessary. It means the if you have big application which takes 15 seconds to reload then it is done only once after a change and subsequent requests won't trigger code reloading until next change occurs. I believe that this is still useful because usually people make at least few clicks after every code change.

Known caveats





  • :-( Biggest problem: New files not automatically watched. I would really appreciate some help.



  • This code assumes that 'lib/' directory is not added to your autoload_path.



  • You must change the file to reflect database changes.



  • fork() is used to spawn watchr script. This won't work on some systems (windows?) or ruby implementations (jruby?). However you can still execute the script manually (just don't forget to do it or you code wont' reload at all!) or use some other technique to do it automatically. Also it might be necessary to run 'bundle exec watchr' instead of just runnning 'watchr'.



I would love to see the idea implemented in Rails with all those caveats fixed.