Ah, mi tema favorito… los componentes.
Mi impresion es que es un aspecto completamente incomprendido y
comunmente confundido de rails. Cuando DHH empezo a decir que los
componentes eran malos, se referia a Componentes con C mayuscula; a
piezas reusables entre aplicaciones, empleando el subdirectorio
“components” e intentando abstraer funciones complejas. Un componente
de blog, o de comentarios, o cosas por el estilo.
En esa misma epoca, la implementacion de render_component era
bastante lenta. Principalmente porque duplicaba los objetos de
request, session, response y controller indiscriminadamente. Pero
esto es algo que ya ha sido solventado. Si se fijan en las
revisiones, el comentario sobre la lentitud de los componentes
precede a los checkins que optimizaron el rendimiento, y nunca fue
modificado. No me sorprenderia que el mismo DHH dejara el comentario
alli para que la gente evitara hacer Componentes (de nuevo, con C).
Y para poner el ultimo clavo en el ataud. Tambien en esos mismo dias,
muchas instalaciones de Typo, el sistema de blog, empezaron a
quejarse por el performance y el culpable era la gran cantidad de
componentes por pagina que usaba la aplicacion.
El problema que se quiere resolver es muy sencillo: Desde una vista,
invocar otro fragmento arbitrario de HTML (un parcial, generalmente)
cuando este fragmento arbitrario requiere datos adicionales.
Las solucines que proponen incluyen hacer before_filters y usar
parciales; o encapsular la logica del componente en un Proc que es
evaluado en el parcial. O simplemente poner la logica en el parcial
mismo. Y una larga lista de soluciones similares.
Pero es que no hay nada mas simple para resolver eso que un
render_component que invoque una nueva accion, y que esta a su vez
decida que view emplear.
Ezra Zygmuntowicz incluso ha creado un sistema llamado “cells” que
no es mas que components sin usar components. Pero tiene la
desventaja que tus metodos no pueden aprovechar nada de lo que tienes
en los controladores.
En streeteasy empleamos componentes extensivamente. Hemos hecho
pruebas de rendimiento y nuestras conclusiones es que el impacto de
usar componentes es 2 a 3 veces el impacto de emplear parciales, pero
que en ambos casos es generalmente despreciable al compararlo con el
procesamiento real de la accion. Es decir, con un ejemplo: la
ejecucion de un componente dura 10 segundos, de los cuales 1 segundo
corresponde al costo de render_component y 9 segundos corresponden a
la accion. La misma solucion empleando parciales dura 9.5 segundos.
Ese costo se justifica plenamente al mantener una arquitectura mas
simple, donde la logica de una accion esta bien encapsulada y
asociada al view correspondente. Donde queda claro quien hace que, y
no hay que preocuparse de incluir los before_filter apropiados, solo
por si acaso el view decide incluir un parcial que no habias
previsto, etc, etc.
Y es que eso es lo que mas me hace hervir la sangre cuando discuto
sobre componentes. No entiendo como la gente intenta evitar a toda
costa la solucion mas elegante y limpia poniendo como justificacion
el rendimiento de la aplicacion.
Hay rumores de que Rails 2.0 no va a incluir componentes. Yo ya me he
ofrecido a mantener un plugin que ofrezca esa misma funcionalidad. De
hecho, ya tengo un plugin que agrega ciertas ventajas a los
componentes, incluyendo caching (en mi opinion, fragment caching es
completamente inutil si no usas componentes) y alguno que otro
helper. El que este interesado que me deje una nota.
En fin, usen componentes, no les tengan miedo. Y si alguien les
reclama, pues diganle que venga a hablar conmigo.
Saludos,
Sebastian