0% acharam este documento útil (0 voto)
4 visualizações15 páginas

Otimização de Performance em React

banco de dados
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOCX, PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
4 visualizações15 páginas

Otimização de Performance em React

banco de dados
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOCX, PDF, TXT ou leia on-line no Scribd

Roteiro de Atividade Prática

Nome: Turma:
.

Atividade: Otimização de performance em React

Você foi encarregado de otimizar uma aplicação React que exibe uma lista de
usuários e permite adicionar novos. A aplicação está enfrentando problemas de
performance, pois a lista cresce com o tempo e as renderizações estão se
tornando lentas.

Situação fictícia produzida pela SEDUC-SP.

Para resolver isso, aplicaremos as técnicas de Memoization, Pure


Components e Virtualização de Listas. O objetivo é melhorar a experiência
do usuário tornando a aplicação mais eficiente.

Passos Iniciais

1. Instalar o [Link] e npm: se você ainda não tem o [Link] instalado,


precisa baixá-lo e instalá-lo do site oficial (Acesso em: 6 dez. 2024). O
npm é instalado automaticamente com o [Link].

2. Criar um novo projeto React: para iniciar um novo projeto React, ele
pode usar o comando npx create-react-app. No terminal, você deve
executar:
npx create-react-app performance-optimization

3. Navegar para o diretório do projeto:


cd performance-optimization

4. Instalar as dependências necessárias:


O aluno deve instalar a biblioteca react-window para a virtualização da
lista:
npm install react-window

5. Instalar o React Router:


Como a aplicação pode usar o roteamento para diferentes componentes
(Home, About), é necessário instalar react-router-dom:
npm install react-router-dom

6. Estrutura de componentes:

[SIS] [U2] [C3]


1 / 15
O aluno deve criar os componentes [Link] e [Link] dentro de uma
pasta components. Para isso, ele pode criar os arquivos manualmente ou
com os seguintes comandos no terminal:
mkdir src/components

7. Adicionar o código base:


O código fornecido na atividade já está estruturado, mas o aluno precisa
garantir que ele funcione adequadamente e que as dependências (como
React Router e react-window) estejam integradas.

Executar a aplicação
Após seguir os passos anteriores, o aluno deve iniciar o servidor de
desenvolvimento com o comando:
npm start

Aplicação base (No arquivo [Link] em src)


Abaixo está o código de uma aplicação que renderiza uma lista de usuários
e permite adicionar mais usuários. Vamos usá-lo como ponto de partida:

import React, { useState } from 'react';

function App() {
const [users, setUsers] = useState(['Alice', 'Bob', 'Charlie']);
const [newUser, setNewUser] = useState('');

const addUser = () => {


setUsers([...users, newUser]);
setNewUser('');
};

return (
<div>
<h1>Lista de Usuários</h1>
<input
type="text"
value={newUser}
onChange={(e) => setNewUser([Link])}
placeholder="Adicionar usuário"
/>
<button onClick={addUser}>Adicionar</button>

<ul>
{[Link]((user, index) => (
<li key={index}>{user}</li>
))}
</ul>
</div>
);

[SIS] [U2] [C3]


2 / 15
}

export default App;

Problema:
À medida que a lista cresce, a aplicação fica mais lenta, pois a renderização de
toda a lista acontece toda vez que um novo usuário é adicionado, mesmo que
apenas um item mude. Vamos aplicar três técnicas para otimizar essa
aplicação.

Passo 1: Memoization com [Link]()

Objetivo: Evitar renderizações desnecessárias dos itens da lista.

Problema: No código atual, toda vez que o estado da aplicação muda (como
ao adicionar um usuário), todos os itens da lista são renderizados novamente,
mesmo que não tenham mudado.

Solução: Usar [Link]() para memoizar cada item da lista, de modo que
ele só seja re-renderizado quando suas props (o nome do usuário) mudarem.

Implementação:
Primeiro, extraia o item da lista para um componente separado e use o
[Link]().

const UserItem = [Link](({ user }) => {


return <li>{user}</li>;
});

function App() {
const [users, setUsers] = useState(['Alice', 'Bob', 'Charlie']);
const [newUser, setNewUser] = useState('');

const addUser = () => {


setUsers([...users, newUser]);
setNewUser('');
};

return (
<div>
<h1>Lista de Usuários</h1>
<input
type="text"
value={newUser}
onChange={(e) => setNewUser([Link])}
placeholder="Adicionar usuário"
/>

[SIS] [U2] [C3]


3 / 15
<button onClick={addUser}>Adicionar</button>

<ul>
{[Link]((user, index) => (
<UserItem key={index} user={user} />
))}
</ul>
</div>
);
}

Explicação:

 [Link]() faz com que o componente UserItem só seja re-


renderizado quando suas props mudam. Agora, ao adicionar um novo
usuário, apenas o item novo é renderizado, enquanto os outros
permanecem inalterados.

Passo 2: Pure Components

Objetivo: Usar Pure Components para evitar renderizações desnecessárias em


componentes de classe.

Problema: Se tivermos algum componente de classe na aplicação, como o


formulário de adição de usuários, ele pode estar sendo re-renderizado mesmo
quando suas props e estado não mudam.

Solução: Transformar o componente de classe em um Pure Component para


que ele só se re-renderize se houver mudanças nas props ou no estado.

Implementação: Neste exemplo, vamos transformar o botão de adicionar em


um Pure Component.

class AddUserButton extends [Link] {


render() {
return <button onClick={[Link]}>Adicionar</button>;
}
}

function App() {
const [users, setUsers] = useState(['Alice', 'Bob', 'Charlie']);
const [newUser, setNewUser] = useState('');

const addUser = () => {


setUsers([...users, newUser]);
setNewUser('');
};

[SIS] [U2] [C3]


4 / 15
return (
<div>
<h1>Lista de Usuários</h1>
<input
type="text"
value={newUser}
onChange={(e) => setNewUser([Link])}
placeholder="Adicionar usuário"
/>
<AddUserButton onClick={addUser} />

<ul>
{[Link]((user, index) => (
<UserItem key={index} user={user} />
))}
</ul>
</div>
);
}

Explicação:

 [Link] verifica se as props ou o estado do componente


mudaram antes de re-renderizar. Isso impede que o botão seja re-
renderizado toda vez que a lista de usuários for atualizada.

Passo 3: Virtualização de listas com react-window

Objetivo: Melhorar a performance ao renderizar uma lista grande, carregando


apenas os itens visíveis na tela.

Problema: Com muitos usuários na lista, a renderização de todos os itens ao


mesmo tempo pode ser lenta e ineficiente.

Solução: Usar a biblioteca react-window para virtualizar a lista e renderizar


apenas os itens visíveis na tela.

Implementação: Instale a biblioteca react-window: No prompt ou terminal:


npm install react-window

[SIS] [U2] [C3]


5 / 15
Substitua a renderização da lista por um componente virtualizado:
import { FixedSizeList as List } from 'react-window';

const UserItem = [Link](({ user }) => {


return <div>{user}</div>;
});

function App() {
const [users, setUsers] = useState(['Alice', 'Bob', 'Charlie']);
const [newUser, setNewUser] = useState('');

const addUser = () => {


setUsers([...users, newUser]);
setNewUser('');
};

return (
<div>
<h1>Lista de Usuários</h1>
<input
type="text"
value={newUser}
onChange={(e) => setNewUser([Link])}
placeholder="Adicionar usuário"
/>
<AddUserButton onClick={addUser} />

<List
height={150}
itemCount={[Link]}
itemSize={35}
width={300}
>
{({ index, style }) => (
<div style={style}>
<UserItem user={users[index]} />
</div>
)}
</List>
</div>
);
}

Explicação:

 react-window permite renderizar apenas os itens visíveis da lista,


economizando recursos. No exemplo, a lista renderiza apenas os itens

[SIS] [U2] [C3]


6 / 15
que cabem em uma altura de 150px, carregando mais à medida que o
usuário rola a tela.

Não esqueça de entregar e registrar na plataforma:

 Aplicação React otimizada usando [Link](), Pure Components e


react-window.

 Relatório explicando as melhorias de performance observadas antes e


depois das otimizações.

* Instalar o [Link] e npm: Se você ainda não tem o [Link] instalado,


precisa baixá-lo e instalá-lo do site oficial (Acesso em: 6 dez. 2024). O
npm é instalado automaticamente com o [Link].
* Verificação: Para confirmar a instalação, abra o terminal e digite
node -v e npm -v.
* Criar um novo projeto React: Para iniciar um novo projeto React,
utilize o comando npx create-react-app. No terminal, você deve
executar:
npx create-react-app performance-optimization

* Navegar para o diretório do projeto:


cd performance-optimization

* Instalar as dependências necessárias: O aluno deve instalar a


biblioteca react-window para a virtualização da lista:
npm install react-window

* Instalar o React Router: Como a aplicação pode usar o roteamento


para diferentes componentes (Home, About), é necessário instalar
react-router-dom:
npm install react-router-dom

* Observação: Embora o react-router-dom tenha sido mencionado, o


código base fornecido para otimização não o utiliza diretamente. É
importante notar isso para não gerar confusão no aluno sobre sua

[SIS] [U2] [C3]


7 / 15
aplicação imediata nesta atividade específica. No entanto, é uma boa
prática para projetos React mais complexos.
* Estrutura de componentes: O aluno deve criar os componentes
[Link] e [Link] dentro de uma pasta components. Para isso, ele
pode criar os arquivos manualmente ou com os seguintes comandos no
terminal:
mkdir src/components
touch src/components/[Link]
touch src/components/[Link]

* Conteúdo Básico: Para [Link] e [Link], você pode instruir o


aluno a adicionar um código simples para que os componentes sejam
válidos, por exemplo:
// src/components/[Link]
import React from 'react';
const Home = () => <h1>Página Inicial</h1>;
export default Home;

// src/components/[Link]
import React from 'react';
const About = () => <h1>Sobre Nós</h1>;
export default About;

* Adicionar o código base: O código fornecido na atividade já está


estruturado, mas o aluno precisa garantir que ele funcione
adequadamente e que as dependências (como React Router e react-
window) estejam integradas.
* [Link] Inicial: O aluno deve copiar o primeiro bloco de código
fornecido (Aplicação base) para o arquivo src/[Link].
Executar a Aplicação
Após seguir os passos anteriores, o aluno deve iniciar o servidor de
desenvolvimento com o comando:
npm start

Isso abrirá a aplicação no navegador (geralmente em


[Link]
Aplicação Base ([Link] em src)
Abaixo está o código de uma aplicação que renderiza uma lista de
usuários e permite adicionar mais usuários. Vamos usá-lo como ponto
de partida:
import React, { useState } from 'react';

function App() {
const [users, setUsers] = useState(['Alice', 'Bob', 'Charlie']);
const [newUser, setNewUser] = useState('');

const addUser = () => {


setUsers([...users, newUser]);

[SIS] [U2] [C3]


8 / 15
setNewUser('');
};

return (
<div>
<h1>Lista de Usuários</h1>
<input
type="text"
value={newUser}
onChange={(e) => setNewUser([Link])}
placeholder="Adicionar usuário"
/>
<button onClick={addUser}>Adicionar</button>

<ul>
{[Link]((user, index) => (
<li key={index}>{user}</li>
))}
</ul>
</div>
);
}

export default App;

Problema de Performance
À medida que a lista cresce, a aplicação fica mais lenta, pois a
renderização de toda a lista acontece toda vez que um novo usuário é
adicionado, mesmo que apenas um item mude. Vamos aplicar três
técnicas para otimizar essa aplicação.
Passo 1: Memoization com [Link]()
Objetivo: Evitar renderizações desnecessárias dos itens da lista.
Problema: No código atual, toda vez que o estado da aplicação muda
(como ao adicionar um usuário), todos os itens da lista são
renderizados novamente, mesmo que não tenham mudado.
Solução: Usar [Link]() para memoizar cada item da lista, de
modo que ele só seja re-renderizado quando suas props (o nome do
usuário) mudarem.
Implementação:
Primeiro, extraia o item da lista para um componente separado e use o
[Link]().
Crie um novo arquivo src/components/[Link]:
// src/components/[Link]
import React from 'react';

const UserItem = [Link](({ user }) => {


[Link](`Renderizando UserItem: ${user}`); // Para observar a
otimização

[SIS] [U2] [C3]


9 / 15
return <li>{user}</li>;
});

export default UserItem;

Agora, modifique src/[Link]:


import React, { useState } from 'react';
import UserItem from './components/UserItem'; // Importe o UserItem

function App() {
const [users, setUsers] = useState(['Alice', 'Bob', 'Charlie']);
const [newUser, setNewUser] = useState('');

const addUser = () => {


setUsers([...users, newUser]);
setNewUser('');
};

return (
<div>
<h1>Lista de Usuários</h1>
<input
type="text"
value={newUser}
onChange={(e) => setNewUser([Link])}
placeholder="Adicionar usuário"
/>
<button onClick={addUser}>Adicionar</button>

<ul>
{[Link]((user, index) => (
<UserItem key={index} user={user} />
))}
</ul>
</div>
);
}

export default App;

Explicação:
* [Link]() faz com que o componente UserItem só seja re-
renderizado quando suas props mudam. Agora, ao adicionar um novo
usuário, apenas o item novo é renderizado, enquanto os outros
permanecem inalterados.
* Teste: Abra o console do navegador e observe as mensagens de
"Renderizando UserItem" ao adicionar novos usuários. Você verá que
apenas o novo item é logado após a primeira renderização.

[SIS] [U2] [C3]


10 / 15
Passo 2: Pure Components
Objetivo: Usar Pure Components para evitar renderizações
desnecessárias em componentes de classe.
Problema: Se tivermos algum componente de classe na aplicação,
como o formulário de adição de usuários, ele pode estar sendo re-
renderizado mesmo quando suas props e estado não mudam.
Solução: Transformar o componente de classe em um Pure Component
para que ele só se re-renderize se houver mudanças nas props ou no
estado.
Implementação: Neste exemplo, vamos transformar o botão de
adicionar em um Pure Component.
Crie um novo arquivo src/components/[Link]:
// src/components/[Link]
import React from 'react';

class AddUserButton extends [Link] {


render() {
[Link]("Renderizando AddUserButton"); // Para observar a
otimização
return <button onClick={[Link]}>Adicionar</button>;
}
}

export default AddUserButton;

Agora, modifique src/[Link]:


import React, { useState } from 'react';
import UserItem from './components/UserItem';
import AddUserButton from './components/AddUserButton'; // Importe o
AddUserButton

function App() {
const [users, setUsers] = useState(['Alice', 'Bob', 'Charlie']);
const [newUser, setNewUser] = useState('');

const addUser = () => {


setUsers([...users, newUser]);
setNewUser('');
};

return (
<div>
<h1>Lista de Usuários</h1>
<input
type="text"
value={newUser}
onChange={(e) => setNewUser([Link])}
placeholder="Adicionar usuário"

[SIS] [U2] [C3]


11 / 15
/>
<AddUserButton onClick={addUser} /> {/* Use o componente Pure
*/}

<ul>
{[Link]((user, index) => (
<UserItem key={index} user={user} />
))}
</ul>
</div>
);
}

export default App;

Explicação:
* [Link] verifica se as props ou o estado do
componente mudaram antes de re-renderizar. Isso impede que o botão
seja re-renderizado toda vez que a lista de usuários for atualizada, já
que sua onClick prop (que é uma função) permanece a mesma (a
menos que a função addUser seja recriada em cada renderização de
App, o que não acontece aqui).
* Teste: Observe o console. Você verá "Renderizando AddUserButton"
apenas na primeira renderização ou se a onClick prop realmente
mudar.
Passo 3: Virtualização de Listas com react-window
Objetivo: Melhorar a performance ao renderizar uma lista grande,
carregando apenas os itens visíveis na tela.
Problema: Com muitos usuários na lista, a renderização de todos os
itens ao mesmo tempo pode ser lenta e ineficiente.
Solução: Usar a biblioteca react-window para virtualizar a lista e
renderizar apenas os itens visíveis na tela.
Implementação: Instale a biblioteca react-window (já instruído nos
passos iniciais):
npm install react-window

Substitua a renderização da lista por um componente virtualizado em


src/[Link]:
import React, { useState, useCallback } from 'react'; // Adicionado
useCallback
import UserItem from './components/UserItem';
import AddUserButton from './components/AddUserButton';
import { FixedSizeList as List } from 'react-window'; // Importe
FixedSizeList

function App() {
const [users, setUsers] = useState(['Alice', 'Bob', 'Charlie']);
const [newUser, setNewUser] = useState('');

[SIS] [U2] [C3]


12 / 15
// Memoize a função addUser para evitar que ela seja recriada em
cada renderização
// Isso é importante para AddUserButton (PureComponent) e para
evitar renderizações desnecessárias
const addUser = useCallback(() => {
setUsers((prevUsers) => [...prevUsers, newUser]); // Usar callback
para garantir o estado mais recente
setNewUser('');
}, [newUser]); // Dependência: newUser

// Componente de linha para a lista virtualizada


// style é crucial para o posicionamento do item pela react-window
const Row = ({ index, style }) => (
<div style={style}>
<UserItem user={users[index]} />
</div>
);

return (
<div>
<h1>Lista de Usuários</h1>
<input
type="text"
value={newUser}
onChange={(e) => setNewUser([Link])}
placeholder="Adicionar usuário"
/>
<AddUserButton onClick={addUser} />

{/* Substitua <ul> por List da react-window */}


<List
height={300} // Altura visível da lista
itemCount={[Link]} // Número total de itens na lista
itemSize={50} // Altura de cada item em pixels
width={300} // Largura da lista
>
{Row} {/* Passa o componente Row para renderizar cada linha */}
</List>
</div>
);
}

export default App;

Explicação:
* react-window permite renderizar apenas os itens visíveis da lista,
economizando recursos. No exemplo, a lista renderiza apenas os itens

[SIS] [U2] [C3]


13 / 15
que cabem em uma altura de 300px, carregando mais à medida que o
usuário rola a tela.
* height, itemCount, itemSize e width são props essenciais para
configurar a lista virtualizada.
* O componente Row (ou como você preferir chamar a função que
renderiza cada item) recebe index e style como props da react-window.
O style é crucial e deve ser aplicado ao elemento raiz do seu item para
que a virtualização funcione corretamente.
* A inclusão de useCallback para a função addUser é uma boa prática
para otimização quando se trabalha com PureComponent ou
[Link](), pois garante que a função addUser não seja recriada
desnecessariamente a cada renderização do App, o que faria com que
AddUserButton (um Pure Component) sempre re-renderizasse.
Entrega e Registro
Não esqueça de entregar e registrar na plataforma:
* Aplicação React otimizada usando [Link](), Pure Components
e react-window.
* Relatório explicando as melhorias de performance observadas antes
e depois das otimizações.
Dicas para o Relatório:
Para o relatório, o aluno pode fazer os seguintes testes e observações:
* Antes das otimizações (com o [Link] inicial):
* Adicionar muitos usuários (50, 100, 200).
* Observar a fluidez da digitação e da adição.
* Usar as ferramentas de desenvolvedor do navegador (aba
"Performance") para gravar um perfil de renderização ao adicionar
novos usuários. Focar no tempo de renderização e no número de
renderizações de componentes.
* Observar o uso de memória (aba "Memory").
* Depois das otimizações (com o [Link] final):
* Repetir os testes de adição de muitos usuários.
* Observar a melhoria na fluidez.
* Gravar novamente um perfil de performance e comparar com o
anterior. Deve-se notar uma redução significativa no tempo de
renderização e no número de componentes renderizados
(especialmente os UserItems).
* Observar o uso de memória.
O relatório deve descrever as observações, as ferramentas usadas para
medir a performance e como cada técnica (Memoization, Pure
Components, Virtualização) contribuiu para a melhoria.
Este roteiro, com as pequenas adições e ênfases, oferece um guia
completo e prático para o aluno entender e aplicar conceitos cruciais
de otimização em React.

[SIS] [U2] [C3]


14 / 15
[SIS] [U2] [C3]
15 / 15

Você também pode gostar