Rails - O uso de parciais torna lenta a renderização de visualizações?

16

Estou tendo problemas de desempenho em um 3.1.0aplicativo Rails , agora fiz alterações de cúpula nas minhas consultas com AR e, portanto, mas as visualizações ainda levam muito tempo para renderizar, dividi as visualizações, loops e assim, em muitas parciais que são renderizados dinamicamente dentro de vistas e dentro de outras parciais.

Portanto, é uma prática ruim ter um grande número de parciais?

Devo reduzir o número de parciais para melhorar o tempo de renderização das visualizações?

obrigado

Mr_Nizzle
fonte

Respostas:

5

Não conheço nenhuma diferença significativa no desempenho de renderização entre muitas parciais e uma única exibição quando você renderiza o mesmo conteúdo.

Obviamente, se você renderizar apenas algumas parciais em alguns casos e outras em outros casos, reduzindo efetivamente o volume de renderização de uma exibição específica, poderá ganhar velocidade.

Por outro lado, sempre considerei abstrações parciais que deveriam ser usadas pelo menos em dois lugares diferentes para justificar sua existência. O outro motivo para usar parciais é quando você deseja renderizar a mesma visualização, mas carregar diferentes parciais com base em alguma lógica comercial que você possui.

ATUALIZAR:

Não posso oferecer uma medida ou alguns números concretos sobre a velocidade de renderização. Se você usar um parcial em uma exibição, para renderizá-lo, chame o método render, para que haja uma segunda chamada de método. Isso, como disse na minha resposta, é quase nada, mas pode ajudar a acelerar um pouco as coisas.

No entanto, eu nunca ouvi falar de um projeto corrigindo seu problema de desempenho removendo parciais. Os parciais são uma boa maneira de oferecer um mecanismo de reutilização às visualizações e, na visão dos programadores, eles devem ser usados ​​para esse escopo. Eles devem ser abstrações para conceitos comuns em visualizações.

Eu trabalhei em um projeto em que parciais eram excessivamente usadas. Não Rails, mas os mesmos princípios MVC. Usar pequenas parciais para tudo o que você pode imaginar torna difícil encontrá-las quando você começa a ter dezenas delas. Onde você procuraria uma entrada a ser modificada? Na visão? Parcialmente? Em qual parcial, existem 4 parciais para essa visualização? ...

Após algumas refatorações rígidas, a cada atualização de uma exibição, removíamos as parciais desnecessárias. Eles não desapareceram completamente, mas o que resta são abstrações bem definidas para o projeto. Eles representam elementos bem compreendidos (como uma árvore para algum tipo de objeto ou um tipo de lista específico) que se repetem de uma forma ou de outra em várias visualizações. Eu sei se vejo uma árvore que existe uma parcial para isso. Eu sei quando vejo certo tipo de lista que existe uma parcial para isso. Eu não tenho que caçá-los.

A legibilidade do código é a coisa mais importante que se pode fazer para uma base de código de software.

Patkos Csaba
fonte
Então, basicamente, se eu realmente não precisar de uma parcial, se esse código não for reutilizado por outro controlador ou recarregado dinamicamente, não devo usar parciais? e isso melhoraria o tempo de renderização das visualizações?
Mr_Nizzle
@ Mr_Nizzle: Eu atualizei minha resposta para cobrir os problemas levantados pelo seu comentário. Espero que essa explicação seja mais compreensível ... Acabei de perceber que meu segundo parágrafo na resposta pode ser mal compreendido.
Patkos Csaba
Obrigado cara Code readability, é disso que se trata.
precisa saber é o seguinte
22

Eu discordo de ambas as respostas. Copiei e colei o código de uma parcial para a posição em que está presente na visualização pai parcial e com 500 iterações, isso leva 600ms enormes do tempo necessário para renderizar a visualização. <% = render xyz%> está na minha opinião muito quebrado.

Exemplo, tempo total para renderizar visualização:

Before:
5759.8ms
5804.2ms
5973.6ms

After:
5268.7ms
5201.6ms
5222.4ms

Diff = 5846 - 5231 = 615 ms

Editado

Acabei desidratando todos os _partials dentro do _model parcial e o reduzi para ~ 2000ms; nesse momento, tentei mover o _model parcial para o índice, mas isso NÃO afetou o tempo de renderização, então acho que é com chamadas para renderização aninhada que faz isso.

AJP
fonte
Descoberta interessante em parcial aninhada. Você quis dizer desidratar uma parcial reduzida em 600 ms e desidratar todas as parciais reduziu em 3800 ms? Você poderia lançar o aplicativo demo para isso?
Lulalala
@lulalala: Sim, exatamente, e desculpe, eu não posso como era para o meu trabalho e agora mudei o Rails para o Django, para que nem estivesse mais em contato com esse código. Olhando para Wyatt Barnett respondeu , agora também não tenho certeza se, na verdade, os parciais estavam fazendo acessos ineficientes ao banco de dados que meu código não-DRY estava evitando de alguma forma.
AJ
1
Eu encontrei a mesma coisa. Tirar o código de parciais e desmontar a exibição me proporcionou um aumento de ~ 450ms no desempenho.
bcackerman
1
Na minha experiência usando o Rails com visualizações HAML, muitas pequenas partes parciais diminuem significativamente a renderização. Parece haver uma sobrecarga fixa para cada parcial, bem como a coleta de lixo sendo iniciada ao renderizar muitas parciais em uma exibição. Inclinar uma parcial usada em uma tabela de 50 itens reduziu a renderização da página em 500 ms.
d4n3
2
Rails 4: Acabei de remover alguns milhares de parciais aninhados em um aplicativo grande e obtive uma grande aceleração. Não possui os números, mas sim, se você estiver com problemas de desempenho, vale a pena remover algumas parciais aninhadas para ver se isso ajuda.
Rick Smith
5

Não é um cara de trilhos, mas as visualizações parciais provavelmente não são o problema em si. Em vez disso, parece que você está fazendo um pouco de SELECT N + 1. Observe as coisas da perspectiva do servidor de banco de dados para garantir que você não esteja perdendo nada.

Wyatt Barnett
fonte
2

Trabalhando em um aplicativo Rails 4.2 no momento, uma ação lenta que levava cerca de 745ms em média.

Quando removo o código das parciais e o coloco no modelo principal, o tempo que leva agora é em média inferior a 25ms.

O número de chamadas para renderizar as parciais foi de apenas 29.

Sammy Larbi
fonte
2

Mesmo se você tiver não nenhum problema n + 1 e todo o banco de dados trabalhar antecipadamente (digamos, com uma CTE recursiva), as partes aninhadas ainda serão muito lentas. Haml e Erb parecem lentos para mim. No Rails 5.1.4, estou vendo alguns milissegundos para cada parcial, além de parciais ocasionais muito piores (provavelmente correspondentes à coleta de lixo).

Percebi que, se renomear a parcial enquanto uma dessas solicitações estiver em execução, recebo imediatamente um erro sobre como o arquivo não foi encontrado. Então, aparentemente, o Rails está lendo o disco parcial, reparando-o e avaliando-o para cada iteração. Não é de admirar que seja lento!

Paul A Jungwirth
fonte
0

Muita lentidão observada em parciais aninhadas ocorre apenas durante o desenvolvimento. Mude para a produção para testar.

Zapaf
fonte
Talvez você possa comentar por que a versão em desenvolvimento é consideravelmente mais lenta e ter mais detalhes sobre quando usar qual modo para quais testes.
Kain0_0
francamente, não conheço todos os detalhes, apenas sei que estava tendo os mesmos problemas e achei que foi muito melhorado quando mudei para a produção. Eu posso supor que, como Paul Jungwirth notou, a releitura da parcial e da nova análise, acontece durante o desenvolvimento quando os arquivos podem ter sido alterados.
Zapaf 27/02/19