Rails: ¿el uso de parciales retrasa la representación de vistas?

16

Tengo problemas de rendimiento en una 3.1.0aplicación de Rails , ahora he realizado cambios de domo en mis consultas con AR y, por lo tanto, las vistas aún requieren demasiado tiempo para procesarse, he dividido las vistas, los bucles, etc., en muchos parciales que se representan dinámicamente dentro de las vistas y dentro de otros parciales.

¿Entonces es una mala práctica tener una gran cantidad de parciales?

¿Debería reducir el número de parciales para mejorar el tiempo de representación de las vistas?

Gracias

Mr_Nizzle
fuente

Respuestas:

5

No conozco ninguna diferencia de rendimiento de representación significativa entre muchos parciales y una sola vista cuando representa el mismo contenido.

Obviamente, si renderiza solo algunos parciales en algunos casos y otros en otros casos, reduciendo efectivamente el volumen de representación de una vista específica, entonces puede ganar algo de velocidad.

Por otro lado, siempre consideré las abstracciones parciales que deberían usarse al menos desde 2 lugares diferentes para justificar su existencia. La otra razón para usar parciales es cuando desea renderizar la misma vista pero cargar parciales diferentes según la lógica de negocios que tenga.

ACTUALIZAR:

No puedo ofrecer una medida o algunos números concretos sobre la velocidad de renderizado. Si usa un parcial en una vista, para representarlo llama al método de representación, por lo que hay una segunda llamada al método. Esto, como dije en mi respuesta, no es casi nada, pero puede ayudar a acelerar las cosas un poco.

Sin embargo, nunca escuché de un proyecto que solucione su problema de rendimiento eliminando parciales. Los parciales son una buena manera de ofrecer un mecanismo de reutilización a las vistas y, desde la vista de los programadores, deberían usarse para ese alcance. Deben ser abstractizaciones para conceptos comunes en vistas.

Trabajé en un proyecto donde los parciales se usaban en exceso. No Rails, sino los mismos principios MVC. Usar pequeños parciales para todo lo que puedas imaginar los hace difíciles de encontrar cuando comienzas a tener docenas de ellos. ¿Dónde buscaría una entrada para modificar? En la vista? En un parcial? ¿En qué parcial, hay 4 parciales para esta vista? ...

Después de algunas refactorizaciones difíciles, con cada actualización de una vista, eliminamos los parciales innecesarios. No desaparecieron por completo, pero lo que queda son abstracciones bien definidas para el proyecto. Representan elementos bien entendidos (como un árbol para algún tipo de objetos o un tipo de lista específico) que se repiten de una forma u otra en varias vistas. Sé que si veo un árbol hay un parcial para eso. Sé cuando veo cierto tipo de lista que hay un parcial para eso. No los he cazado.

La legibilidad del código es lo más importante que se puede hacer para una base de código de software.

Patkos Csaba
fuente
Entonces, básicamente, si realmente no necesito un parcial, si ese código no será reutilizado por otro controlador o recargado dinámicamente, ¿no debería usar parciales? y esto mejoraría el tiempo de representación de las vistas?
Mr_Nizzle
@ Mr_Nizzle: Actualicé mi respuesta para cubrir los problemas surgidos por su comentario. Espero que esta explicación gastada sea más comprensible ... Me acabo de dar cuenta de que mi segundo párrafo en la respuesta puede ser mal entendido.
Patkos Csaba
Gracias hombre Code readability, de eso se trata.
Mr_Nizzle
22

No estoy de acuerdo con ambas respuestas. He copiado y pegado el código de forma parcial en la posición que está presente en la vista primaria parcial y con 500 iteraciones, esto toma unos 600 ms del tiempo que se tarda en representar la vista. <% = render xyz%> en mi opinión está muy roto.

Ejemplo, tiempo total para representar la vista:

Before:
5759.8ms
5804.2ms
5973.6ms

After:
5268.7ms
5201.6ms
5222.4ms

Diff = 5846 - 5231 = 615 ms

Editado

Terminé desempolvando todos los _partiales dentro del _modelo parcial y lo bajé a ~ 2000 ms, en cuyo punto intenté mover el _modelo parcial al índice, sin embargo, esto NO tuvo ningún efecto en los tiempos de renderizado, así que supongo que es con llamadas a renderizado anidado que lo hace.

AJP
fuente
Interesante hallazgo en parcial anidado. ¿Querías decir que DESHIDRATAR un parcial se redujo 600 ms y que DESHIDRATAR todos los parciales se redujo 3800 ms? ¿Podría lanzar la aplicación de demostración para eso?
lulalala
@lulalala sí exactamente, y lo siento, no puedo, ya que era por mi trabajo y ahora lo cambié de Rails a Django, así que ya no estoy en contacto con ese código. Mirando a Wyatt Barnett ha respondido , ahora tampoco estoy seguro de si en realidad los parciales estaban haciendo accesos ineficientes a la base de datos que mi código sin DRY estaba evitando de alguna manera.
AJP
1
He encontrado lo mismo. Eliminar el código de los parciales y descomprimir la vista también me dio un aumento de rendimiento de ~ 450 ms.
bcackerman
1
En mi experiencia al usar Rails con vistas HAML, muchos parciales pequeños ralentizan significativamente el renderizado. Parece que hay una sobrecarga fija para cada parcial, así como la recolección de basura que se activa cuando se muestran muchos parciales en una vista. Al incluir un parcial usado en una tabla de 50 elementos, se redujo la representación de la página en 500 ms.
d4n3
2
Rieles 4: acabo de eliminar algunos miles de parciales anidados en una gran aplicación y obtuve una gran aceleración. No tengo los números, pero sí, si tiene problemas de rendimiento, valdría la pena eliminar algunos parciales anidados para ver si ayuda.
Rick Smith
5

No es un tipo de rieles, pero las vistas parciales probablemente no sean el problema per se. Más bien, parece que estás haciendo un poco de SELECT N + 1. Mire las cosas desde la perspectiva del servidor de base de datos para asegurarse de que no lo está superando.

Wyatt Barnett
fuente
2

Trabajando en una aplicación Rails 4.2 en este momento, una acción lenta que tomaba alrededor de 745 ms en promedio.

Cuando elimino el código de los parciales y lo coloco en la plantilla principal, el tiempo que toma ahora es en promedio menos de 25 ms.

El número de llamadas para representar los parciales fue de solo 29.

Sammy Larbi
fuente
2

Incluso si no tiene un problema n + 1 y hace que toda la base de datos funcione por adelantado (digamos con un CTE recursivo), los parciales anidados siguen siendo muy lentos. Haml y Erb me parecen lentos. On Rails 5.1.4 Estoy viendo unos pocos milisegundos por cada parcial, además de parciales ocasionales que son mucho peores (probablemente correspondientes a la recolección de basura).

Noté que si cambio el nombre del parcial mientras se ejecuta una de estas solicitudes, inmediatamente recibo un error sobre cómo no se encuentra el archivo. Entonces, aparentemente Rails está leyendo el disco parcial, volviéndolo a analizar y evaluándolo para cada iteración. ¡No es de extrañar que sea lento!

Paul A Jungwirth
fuente
0

Mucha de la lentitud que se ve en parciales anidados ocurre solo durante el desarrollo. Cambie a producción para probar.

Zapaf
fuente
Tal vez podría comentar por qué la versión de desarrollo es apreciablemente más lenta y tener más detalles sobre cuándo usar qué modo para qué prueba.
Kain0_0
francamente no conozco todos los detalles, solo sé que estaba teniendo los mismos problemas y descubrí que había mejorado mucho cuando cambié a producción. Puedo adivinar que, como notó Paul Jungwirth, la relectura de lo parcial y el análisis ocurre durante el desarrollo cuando los archivos pueden haber cambiado.
Zapaf