Alura > Cursos de Front-end > Cursos de React > Conteúdos de React > Primeiras aulas do curso React: otimizando performance e caching com Apollo Client

React: otimizando performance e caching com Apollo Client

Configure subscriptions com Apollo Client - Apresentação

Boas-vindas a mais um curso de React com o Apollo Server, desta vez com foco na performance da aplicação!

Meu nome é Thamiris Adriano, sou instrutora aqui na Alura, coordenadora da pós-graduação de front-end na Postech, na FIAP, e desenvolvedora front-end na Rede Bandeirantes de Televisão.

Audiodescrição: Thamiris se declara uma mulher branca com cabelo cacheado. Veste uma camiseta preta escrito "Postech", da FIAP e Alura. Ao fundo, o estúdio da Alura com iluminação azul e roxa. À direita, uma estante com decorações e um letreiro neon do logotipo da Alura.

Revisamos o projeto.

Revisão do Projeto

localhost:5173

Atualmente, temos um projeto funcional que já permite fazer publicações e visualizar o "Feed" das aplicações criadas.

No entanto, adicionaremos algumas camadas a ele. Inseriremos a parte de login, para que as pessoas possam visualizar os dados apenas se estiverem logadas. Também criaremos uma página de cadastro para que quem ainda não estiver registrado possa se inscrever. Além disso, consideraremos a segurança e a performance.

Pré-requisitos

Para acompanhar este curso, é necessário ter alguma noção de JavaScript para entender as funções que utilizaremos e conhecimento básico de React para rodar o projeto e instalar as dependências.

Esperamos que gostem. Nos vemos no próximo vídeo!

Configure subscriptions com Apollo Client - Erguendo o servidor automaticamente após alterações - Nodemon

Durante o desenvolvimento de aplicações, frequentemente precisamos derrubar e reiniciar o terminal após cada alteração no código. Podemos simplificar esse processo. Embora existam vantagens e desvantagens, que exploraremos a seguir, primeiro vamos entender o que significa reiniciar o terminal.

Iniciando o servidor

Estamos com o projeto aberto,com o arquivo index.js e o package.json. Para que o servidor rode no localhost, iniciamos o terminal com node index.js:

node index.js

Server ready at http: http://localhost:4000/

Está rodando.

Reinício necessário

No entanto, sempre que precisamos fazer alterações, seja em um esquema, uma mutation ou um resolver, é necessário derrubar o terminal teclando "Ctrl + C", limpar o terminal (cls) e reiniciar com o comando node index.js.

Esse processo de reinício é necessário sempre que há uma mudança.

Para evitar a necessidade de reiniciar o terminal e salvar os arquivos manualmente, podemos utilizar a biblioteca nodemon.

Utilizando a biblioteca nodemon

O nodemon monitora continuamente o código e aplica as alterações automaticamente. Assim, ele atualiza o código em tempo real, eliminando a necessidade de reiniciar o terminal a cada modificação.

Se precisarmos agora trocar um valor de String! para number, como no caso do bpm, será necessário salvar o arquivo, parar o terminal e iniciá-lo novamente.

index.js

// código omitido

bpm: number,

// código omitido

Nesse processo, o terminal pode apresentar um erro, mas isso ocorre porque não realizamos todas as modificações necessárias.

Vamos verificar como seria realizar modificações utilizando o nodemon.

Instalando o nodemon

O primeiro passo é instalar o nodemon no projeto. Existem duas formas de fazer isso: podemos instalá-lo globalmente, para todos os projetos, ou localmente, apenas para este projeto específico, que é a abordagem mais comum.

Como discutiremos, cada método tem suas vantagens e desvantagens, e nem tudo é perfeito; sempre há aspectos positivos e negativos a considerar.

Instalação Local vs. Global

Abordaremos a desvantagem de não utilizar o nodemon em todos os projetos. Normalmente, instalamos o nodemon localmente em vez de globalmente. Para instalar o nodemon localmente, utilizamos um comando específico.

Caso fosse necessário instalá-lo globalmente, o comando seria npm install -g nodemon.

Instalação Local

Como mencionado, a instalação global não é a preferida; optamos por instalar localmente. O comando para instalar o nodemon localmente é npm install --save=dev nodemon.

npm install --save-dev nodemon

Com isso, estamos adicionando o nodemon às dependências do projeto.

found 0 vulnerabilities

Até o momento, tudo está conforme o esperado. Analisando na árvore à esquerda, várias alterações e arquivos foram adicionados à estrutura do projeto. No entanto, não precisamos nos preocupar com isso agora, pois são apenas atualizações nas dependências do projeto e não causarão problemas.

O próximo passo é alterar o package.json.

Alterando o package.json

Trecho de código do arquivo package.json

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1"
},

No package.json, localizamos a seção de scripts, onde podemos definir dois aspectos importantes. Primeiro, configuramos o start, que determina como o projeto será iniciado. Em seguida, adicionamos o nodemon a essa configuração para que o projeto utilize o nodemon durante a execução.

Primeiro, vamos configurar o start. Colocamos o start entre aspas e o Visual Studio Code ajuda mostrando o comando correto enquanto digitamos. Podemos usar o comando node index.js, que é o que estávamos fazendo até agora.

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js",
},

Em seguida, adicionamos o nodemon abaixo do start, lembrando de colocar uma vírgula após o start para separar as entradas no script. Se essa fosse a última informação a ser adicionada, não precisaríamos incluir a vírgula.

Estamos adicionando a vírgula porque ainda vamos incluir mais uma configuração. Vamos adicionar o "dev", que usaremos para executar o terminal daqui em diante. O comando para o dev será nodemon index.js.

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js",
    "dev": "nodemon index.js"
},

Salvamento e Verificação

Assim, ao rodar o terminal, não precisaremos digitar nodemon index.js toda vez. Em vez disso, basta usar o comando npm run dev, que substituirá dev por nodemon index.js. Com isso, simplificamos a execução. Agora, salvamos o arquivo e verificamos se tudo está correto.

No terminal, usaremos o comando npm run dev com o nodemon, e ele já está funcionando.

npm run dev

[nodemon] to restart at any time, enter rs

[nodemon] watching path(s): .

[nodemon] watching extensions: js,mjs,cjs,json

[nodemon] starting node index.js

Server ready at http://localhost:4000/

Além de rodar no localhost como antes, o nodemon agora está observando o caminho e as extensões, monitorando tudo o que acontece. Dessa forma, qualquer alteração feita no projeto será detectada automaticamente, eliminando a necessidade de reiniciar o terminal a cada mudança.

Vamos fazer uma alteração visível.

Exemplo de alteração e salvamento automático

No "Server read at ${url}", que exibe a URL do localhost, vamos substituir o texto atual por "Servidor está rodando na porta ${url}".

server.listen().then(({ url }) => {
  console.log(`Servidor está rodando na porta ${url}`);
});

Assim que fazemos essa mudança e pararmos a digitação, o nodemon atualiza automaticamente no terminal.

Qualquer alteração no projeto será detectada e atualizada automaticamente.

Vocês podem verificar que não foi necessário atualizar o arquivo manualmente; o nodemon observou a mudança e atualizou o terminal instantaneamente. Ele monitora continuamente, aguardando qualquer modificação e aplicando-a automaticamente.

Impacto na performance

Como mencionado, nem tudo é perfeito. O motivo pelo qual não utilizamos o nodemon em todos os projetos é que ele está constantemente observando as mudanças no código, o que pode impactar a performance.

Como o foco é otimizar o desempenho, preferimos não usar o nodemon durante as próximas aulas para garantir que o código seja o mais eficiente possível. Embora o impacto não seja significativo, optamos por não utilizá-lo para manter o foco na performance.

O projeto ainda é pequeno, então o impacto do nodemon não seria significativo. Se você preferir usá-lo nas próximas aulas para facilitar as alterações no servidor, sinta-se à vontade. Não há problema algum, e ele não causará nenhum malefício ao projeto.

Configure subscriptions com Apollo Client - Configuração e uso de subscriptions para dados em tempo real

As Subscriptions é uma funcionalidade do apollo server que utiliza WebSockets para que a pessoa cliente receba notificações constantes sobre tudo o que acontece em tela. Essa funcionalidade é especialmente útil para aplicações que requerem atualizações contínuas, como redes sociais, por exemplo.

Importância das atualizações constantes

Sempre que há uma nova foto publicada, uma nova curtida ou um novo comentário, é importante que a pessoa cliente conectada ao servidor receba essa informação de forma constante.

Dessa forma, ela sabe sobre novas atividades a serem realizadas, como mostrar uma nova foto ou exibir uma nova curtida. Por isso, é fundamental utilizarmos WebSockets para manter as informações sempre atualizadas.

No caso do apollo server, utilizamos as subscriptions. No código index.js, já temos as queries, que trazem as atividades, e as mutations, que atualizam as atividades.

index.js

// código omitido

type Query {
  mockActivities(user: String): [Activity]
}
type Mutation {
  addActivity(
    time: String!,
    type: String!,
    distance: String!,
    calories: String!,
     bpm: String!,
     user: String!,
     userImage: String!,
     imageUrl: String!
): Activity

// código omitido

Implementação das subscriptions

Agora, vamos inserir as subscriptions. Sempre que realizamos uma mutation, no caso, estamos apenas adicionando novas informações, como atividades de corrida ou natação. No entanto, a pessoa cliente ainda não recebe essas atualizações.

Inserimos as subscriptions, abrimos no Apollo Playground e observamos como a informação é recebida em tempo real via subscriptions, a partir do que visualizamos no apollo service.

Instalação do apollo-server

Primeiro, instalamos o apollo server com o comando npm install apollo-server.

npm install apollo-server-express express subscriptions-transport-ws graphql

Com isso, adicionamos o express.

Rodamos o projeto com node index.js e acessamos o apollo server clicando no link para visualizar as mutations e as subscriptions.

node index.js

Server ready at http://localhost:4000/graphql

Subscriptions ready at ws://localhost:4000/graphql

Adicionando uma subscription na "Operation"

No apollo server, temos a seção "Operation", o campo de resposta (à direita) e o campo de variáveis (parte inferior), conforme visto em aulas anteriores. Agora, adicionamos uma subscription na "Operation".

subscription {
  activityAdded {
    id
    time
    type
    distance
    calories
    bpm
    user
    userImage
    imageUrl
  }
}

Clicamos em "Run". Observe do lado inferior direito, que há uma mensagem "Listening", significa que ele está escutando tudo o que está acontecendo.

Já conectamos nosso server e configuramos para monitorar tudo o que está acontecendo. Portanto, qualquer mutation realizada será escutada. Isso é importante porque, ao conectar isso no front-end do nosso projeto, conseguimos tomar novas ações sempre que a subscription detectar alguma atividade.

Adicionando uma atividade via mutation

Abrimos uma nova aba no Apollo Playground clicando no ícone de adição na parte superior e colocamos uma mutation para adicionar uma atividade.

Após inserir os dados da mutation, inserimos uma query sem escrever explicitamente a palavra "query". Esperamos que, após a mutation ser inserida e os dados serem adicionados ao servidor, eles retornem confirmando que tudo está certo.

mutation {
  addActivity(
    time: "08:00 AM",
    type: "Running",
    distance: "5 km",
    calories: "300",
    bpm: "120",
     user: "Thamiris",
     userImage: "https://dgalywyr863hv.cloudfront.net/pictures/athletes/26083410/23890190/3/large.jpg",
     imageUrl: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRh-BL5mfltDONZvUCaK7EGl7g0WjyFJrcjKupUZ230Q"
     } {
    id
    time
    type
    distance
    calories
    bpm
    user
    userImage
    imageUrl
  }
}

Verificando dos dados retornados

Executamos o comando clicando em "Run" e os dados retornaram, mostrando as atividades adicionadas. Do lado direito, temos:

{
  "data": {
    "addActivity": {
      "id": "24",
      "time": "08:00 AM",
      "type": "Running",
      "distance": "5 km",
      "calories": "300",
      "bpm": "120",
      "user": "Thamiris"
         "userImage": "https://dgalywyr863hv.cloudfront.net/pictures/athletes/26038488/23890190/3/large.jpg",
         "imageUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRh-BL5mfltDONZvUCaK7EGl7g0WjyFJrcjKupUZ230Q"
            }
    }
}

Já estamos no ID 24, indicando que já foram inseridas 23 atividades no nosso aplicativo, incluindo informações como o nome da pessoa usuária e o número da imagem. A resposta na parte inferior direita indica que houve uma atualização às 14:23:36.

Response received at 14:23:36

A subscription funcionou corretamente, informando a pessoa cliente sobre a nova atividade.

A mutation adicionou a nova informação, e a subscription recebeu e confirmou essa atualização.

Conclusão

Nesta aula, instalamos e configuramos o apollo server para trabalhar com subscriptions usando WebSockets, entendendo sua importância e a relevância para determinados projetos. Até mais!

Sobre o curso React: otimizando performance e caching com Apollo Client

O curso React: otimizando performance e caching com Apollo Client possui 75 minutos de vídeos, em um total de 36 atividades. Gostou? Conheça nossos outros cursos de React em Front-end, ou leia nossos artigos de Front-end.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda React acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas