Executando verificação de segurança...
6

Next com SSR - Como renderizar a página antes da api ser chamada

Um dos grandes problemas que tive quando estava começando a usar o Next.js era como melhorar o tempo de carregamento da página utilizando o Server Side Rendering, pois demorava tanto que o Vercel sempre dava timeout no meu site.

O problema

Por algum motivo, a página demorava muito para carregar, mesmo quando eu retornava uma propriedade estática diretamente do getServerSideProps.

A pesquisa

Quando se tem um problema do qual não se tem conhecimento, é preciso saber o que pesquisar para receber uma resposta válida, principalmente quando é um problema pouco explorado. Então, me pus a procurar em vários sites, tanto na documentação, quanto no stack overflow e afins. Vou listar aqui algumas das soluções:

Importar apenas o componente específico

Normalmente utilizamos:

import { input, Box, Typography } from '@mui/material'

Porém esse import carrega toda a pasta @mui/material na página e não apenas os componentes especificados, logo, é recomendado utilizar:

import Input from '@mui/material/Input';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';

Concordo que é meio contraintuitivo, principalmente para iniciantes, mas nem sempre escrever menos código é a melhor escolha, principalmente quando se trabalha em grupo. Além disso, nem sempre é possível importar apenas o componente específico.

Carregar dinamicamente os imports e imagens da página

Aos utilizarmos os imports, todos eles são carregados na página de uma vez, mesmo que ele não seja utilizado ou esteja visível. Para adicionar um pouco mais de velocidade no carregamento da página, podemos utilizar o hook dynamic.

Vamos considerar que o component ProfileImage só é mostrado quando um certo botão é clicado. Invés de importar desta forma:

import ProfileImage from '../components/ProfileImage'

Podemos utilizar o dynamic que é fornecido pelo Next para importarmos dinamicamente nosso componente:

import dynamic from "next/dynamic";

const ProfileImage = dynamic( import("../components/ProfileImage") )

O hook também pode ser personalizado de várias formas, sendo uma delas:

const ProfileImage = dynamic(() => import("../components/ProfileImage"), {
    loading: <LoaderComponent />
})

Carregar a página antes de finalizar o getServerSideProps

Essa foi a que fez mais efeito no meu código, ele basicamente renderiza a página antes do getServerSideProps ser finalizado e após a conclusão, a página renderizada novamente com os novos dados.

Utilizando a propriedade req, que nos é dada pelo próprio Next, é possível fazer isso. Para facilitar o entendimento, utilizarei Typescript para o exemplo, e consideraremos useFetch um hook personalizado que nos retorna [data, loading]:

import { GetServerSideProps } from 'next';
...
const isServerReq = (req: any) => !req.url.startsWith('/_next');
...
export const getServerSideProps: GetServerSideProps = async ({ req  }) => {
    const fetchResponse = isServerReq(req) ? await useFetch(some_url) : [null, true];
    const [data, loading] = fetchResponse;
    
    return {
        props: {
            data,
            loading
        }
    }
}

De maneira simples, a função isServerReq verifica se já foi carregado via SSR, caso não, é como se o SSR fosse desabilitado temporariamente e ligado novamente após a conclusão do carregamento. Link para mais informações: https://github.com/vercel/next.js/issues/13910

Problema resolvido

Graças ao último tópico, consegui fazer meu deploy no Vercel funcionar, mas não é a maneira recomendada de utilizar, porém, caso queiram saber mais sobre otimização irei deixar alguns links como fonte desse artigo.

Carregando publicação patrocinada...
1

muito bom o texto ksksk eu tava dando uma olhada no site da next e vi que o next 13 vai trazer uma grande mudança na forma como podemos componentizar e lidar com esses elementos renderizados pelo lado do servidor..

uma pena ainda estar em beta pq eu tava loco pra poder testar em algumas coisas aqui da empresa kskssksk

se quiser da uma olhada dps eles adicionaram uma pasta chamada APP que vc pode configurar loading tratamentos de erro e layouts para as telas