O conteúdo deste site foi traduzido usando inteligência artificial (IA) ou tecnologia de tradução automática e pode conter erros.

Skip to content

Melhorando o uso de memória do front-end em 30 vezes no carregamento do carrossel

No segundo trimestre de 2020, realizamos uma refatoração técnica na página de experiências, reescrevendo-a em React e utilizando a API REST. Mas, durante a implementação, encontramos um problema interessante.

Existem cerca de 20 carrosséis na página de experiências, cada um com pelo menos 60 blocos. Assim, a página renderizará mais de 1.200 experiências, incluindo informações relevantes como título, avaliação do usuário, usuários simultâneos e miniatura. Em cada carrossel, clicar na barra de rolagem à direita enviará uma solicitação para carregar o próximo lote de experiências, caso haja mais. Em seguida, os novos dados resultantes da solicitação serão anexados ao carrossel, o que significa mais nós adicionados ao DOM e mais miniaturas sendo renderizadas no navegador. O uso de memória dentro do navegador aumentará à medida que os usuários rolarem a tela para solicitar mais dados, e então a experiência do usuário ficará mais lenta e começará a apresentar atrasos.

Perfil de memória

Podemos usar as Ferramentas do desenvolvedor do Chrome para analisar esse problema. O primeiro instantâneo é capturado quando a página é carregada inicialmente, e o segundo é capturado depois que o usuário clica 12 vezes no botão de rolagem seguinte em um carrossel. Observamos um aumento de quase 9,7 MB no uso de memória devido a mais de 100 nós de string e ao aumento na renderização de miniaturas.

Solução

Quando o carrossel rola, os usuários visualizam apenas os itens da janela do carrossel. Por exemplo, em um laptop com resolução de 1920×1080, no modo de tela cheia do navegador, haverá apenas cerca de 9 itens visíveis por vez. Portanto, não é necessário renderizar todos os nós e miniaturas invisíveis juntos nem transportar mais dados retornados da solicitação para o DOM.

Então, eis a ideia: depois de buscarmos os dados brutos da solicitação da API pela primeira vez, construímos uma matriz com o mesmo comprimento, preparando-a para renderização no DOM. Dentro da matriz de renderização, podemos preencher apenas dados suficientes para preencher a tela e avançar para a próxima. O restante da matriz será preenchido apenas quando a janela de exibição for rolada para perto dela. Vamos definir dois índices para registrar o intervalo dos dados de renderização: renderingStartIndex e renderingEndIndex. Configuramos um cursor para indicar qual posição inicial na lista está visível. Ao rolar a tela, precisamos atualizar continuamente o cursor para o índice do primeiro item visível. Antes que a animação de rolagem termine, precisaremos verificar se o próximo cursor está dentro da matriz de dados de renderização. De acordo com o tamanho da janela do carrossel e o tamanho dos cartões, podemos facilmente determinar quantos itens visíveis caberão na janela de exibição. Em seguida, precisamos garantir que os itens da janela atual e da próxima janela estejam dentro do intervalo da matriz de dados de renderização. Caso contrário, pegamos itens dos dados brutos para preencher a lista vazia, ao mesmo tempo em que limpamos os dados anteriores à posição do cursor. Isso se aplica quando os usuários rolam para a direita ou para a esquerda. Quando os usuários rolam para a direita, ao buscar mais dados em segundo plano, preencheremos os dados brutos a cada vez que recebermos novos dados. No entanto, os dados brutos não serão incluídos na renderização da página.

Veja como fica com a melhoria:

Perfil de memória

Vamos dar uma olhada nas Ferramentas do Desenvolvedor do Chrome novamente. Como antes, o primeiro instantâneo é capturado no momento da inicialização e o segundo é capturado após rolar a tela para a direita 12 vezes. Agora, carregar mais de 100 itens custa apenas 0,3 MB de aumento de memória, em comparação com os 9,7 MB anteriores.

O que vem a seguir?

Além de melhorar o componente carrossel para lidar com janelas de dados grandes, quando refatoramos um recurso/página, precisamos adicionar mais benchmarks para capturar as informações de desempenho.

Embora a pilha de aplicativos web modernos tenha se deslocado para o front-end, capturar e melhorar a telemetria do front-end é tão importante quanto a telemetria tradicional do back-end.

Ying Jiang é engenheira de software front-end sênior na Roblox. Como a primeira engenheira de front-end da Roblox, ela trabalha para introduzir uma pilha de tecnologias front-end modernas na Roblox e melhorar o pipeline de desenvolvimento e implantação. Ela também trabalhou em recursos em tempo real, como chat, fluxo de notificações e voz.

Nem a Roblox Corporation nem este blog endossam ou apoiam qualquer empresa ou serviço. Além disso, não são feitas garantias ou promessas quanto à precisão, confiabilidade ou integridade das informações contidas neste blog.