This site is dedicated to further knowledge about creating Ruby on Rails applications professionaly. We discuss Ruby on Rails features from a performance angle, discuss Ruby on Rails performance analysis methods, provide information on Ruby on Rails scaling and benchmark Ruby on Rails performance for each release. We discuss best practices for selecting Ruby on Rails session containers, fragment and page caching and optimizing database queries.

Trim your output

Posted 06 Dec 2005

The 0.14 Rails series includes a new option setting for template rendering, which allows for reducing the number of newlines generated by template processing. It's a string valued class attribute for ActionView, called erb_trim_mode. Its value is passed to the ERB compiler when a template gets compiled, with a default value of "-".

Some documentation for possible settings is part of the ERB class doc.

However, the doc is incomplete, as it doesn't mention Rails' default setting "-".

erb_trim_mode affects the way template processing handles newline characters in the template. Per default, (when erb_trim_mode is set to nil), processing leaves all newline characters occurring in the template in the generated html code. Which means that many extraneous newlines get inserted into your output.

For example,

<% if expr %>
some text
<% else %>
other text
<% end %>
will generate the following processing code:
if expr ; _erbout.concat("\n")
_erbout.concat("some text\n")
else ; _erbout.concat("\n")
_erbout.concat("other text\n")
end ; _erbout.concat("\n")

With the default setting of erb_trim_mode, you can suppress extraneous newline characters by adding a - before the closing %>:

<% if expr -%>
some text
<% else -%>
other text
<% end -%>
will generate the following template code:
if expr
_erbout.concat("some text\n")
_erbout.concat("other text\n")

This version looks much cleaner, suppresses 2 superfluous newline characters in the generated HTML code and saves 2 function calls when processed. Which is no big deal, unless the above call occurs inside a loop. If the loop body gets executed 100 times, you have already saved 200 characters and, more importantly, 200 function calls.

Manually adding all the minuses to closing %> markup is somewhat tedious. erb_trim_mode comes to rescue: if set to ">", newline characters will be suppressed for <%...%> markup closing a line; if set to "<>", newline characters will be suppressed for <%...%> occurring as a line of its own.

I have measured the relative performance of setting erb_trim_mode to ">". The following table shows that my app's pages receive a performance increase ranging from 1 to 4%.

configuration 1: 12-06.uncached.untrimmed
  requests=1000, options=-bm=uncached -lib=r141 -mysql_session
                         -fast_routes -fast_readers

configuration 2: 12-06.uncached.trimmed
  requests=1000, options=-bm=uncached -lib=r141 -mysql_session
                         -fast_routes -fast_readers -trim

page   c1 real   c2 real  c1 r/s  c2 r/s   c1 ms/r  c2 ms/r  c1/c2
 1:    3.52722   3.47518   283.5   287.8      3.53     3.48   1.01
 2:    4.30330   4.26213   232.4   234.6      4.30     4.26   1.01
 3:    4.49761   4.36027   222.3   229.3      4.50     4.36   1.03
 4:    4.45229   4.27840   224.6   233.7      4.45     4.28   1.04

 1: /rezept/show/713
 2: /rezept/cat/Hauptspeise
 3: /rezept/cat/Hauptspeise?page=5
 4: /rezept/letter/G

Unfortunately, ERB doesn't support combining the "-" and ">" setting. So you'll have to decide which way to go upfront. If you choose on ">", you may find that you have to add empty lines in some places where they weren't needed before.

Posted in performance | Tags rendering


blog comments powered by Disqus