It depends.
When Haml compiles the filter, it checks to see if the filter text contains any interpolation ( #{...} ). If not, then there will be the same text for conversion for each request, so the conversion is performed once at compile time and the result is included in the template.
If there is interpolation in the filter text, then the actual text for the conversion will change for each request, so Coffeescript will need to be compiled every time.
Here is an example. First without interpolation:
:coffeescript $ -> alert "No semicolons! Awesome"
This generates code (use haml -d to see the generated Ruby code):
_hamlout.buffer << "<script>\n (function() {\n $(function() {\n return alert(\"No semicolons! Awesome\");\n });\n \n }).call(this);\n</script>\n";
This code simply adds a line to the buffer, so Coffeescript is not recompiled.
Now with interpolation:
- word = "Awesome." :coffeescript $ -> alert "No semicolons! #{word}"
This generates:
word = "Awesome." _hamlout.buffer << "#{ find_and_preserve(Haml::Filters::Coffee.render_with_options( "$ -> alert \"No semicolons! #{word}\"\n", _hamlout.options)) }\n";
Here, since Haml has to wait to find out what the interpolation value is, Coffeescript is recompiled every time.
You can avoid compiling Coffeescript for each request without having interpolation inside the filters :coffeescript .
The :javascript filter behaves similarly, checking if there is any interpolation, but since the :javascript filter only outputs some text to the buffer when it is run, its use is much less. You could combine the filters :javascript and :coffeescript by putting the interpolated data in :javascript and saving :coffeescript static:
- word = "Awesome" :javascript var message = "No semicolons! #{word}"; :coffeescript alert message