Paginação para resolver problemas de performance - Parte I

Paginação para resolver problemas de performance - Parte I

Quando lidamos com uma grande lista de dados, a melhor forma de encontrarmos perfomance é usando limites e paginação, mas nem sempre o back-end cria essas formas para evitar os problemas e cabe ao front-end resolver isso.

Muitas vezes ao lidarmos com bibliotecas para view, pode ser meio complexo e com baixa performance criar essas listagens, mas ter o conceito de serviço e dados em memória, pode ajudar a resolver esse problema.

Armazenando em memória

O código Javascript está sempre sendo executado em memória, esse conceito é importante relembrar já que ele causa uma grande confusão, principalmente para iniciantes, que ao atualizarem a sua aplicação ou página, perdem todas as informações.

Também ao falarmos de Javascript temos alguns estágios, principalmente em uma biblioteca como React que tem o estágio especifico de renderização. Ambos são importantes, porque você pode armazenar sua lista em memória e exibir de forma paginada as informções.

Construindo a paginação

Antes de construir a paginação, vamos definir um serviço que cuidará desse "cache" da listagem. Usarei classe para facilitar o entendimento das diversas vertentes de desenvolvimento, mas é importante lembrar que class é só um sintax sugar (facilitadores de sintaxe) para funções de alto nível.

class PaginationService {
    constructor(list) {
        this.list = list;
    }
}

Nosso serviço recebe a lista na instancia, ao instanciar esse novo serviço já fica na memória a referencia a lista e também conseguimos usar a paginação em outros serviços.

Para criar a paginação,  primeiro precisa definir a quantidade de itens que tem cada página contém e com isso chegar ao número de páginas. Por exemplo uma lista de 200 itens, em que cada página contem 20 itens, logo teremos 10 páginas.

class PaginationService {
    constructor(list, itensPerPage) {
        this.list = list;
        this.itensPerPage = itensPerPage
        this.totalPages = list.length/itensPerPage;
    }
}

Para chegar esse número, vamos já deixar como uma propriedade de fácil acesso de nossa classe.

Para navegarmos entre os dados precisamos, isolar partes da lista (para a lista o tipo de dados deve ser um array)

Para pegarmos uma página precisamos fazer alguns calculos, para extrair da lista os itens corretos, uma forma é começar por definir a posição final do ultimo item em uma página.

Usando a lista de 200 itens e com 10 páginas, se quisermos pegar a página 5, precisamos multiplicar o itensPerPage (items por página) por 5, que será a posição 100 da nossa lista. Após isso basta subtrairmos o número de itens da página pelo final da lista, assim temos o começo e final da página 5.

Falando em código é algo semelhante ao exemplo abaixo:

class PaginationService {
    constructor(list, itensPerPage) {
        this.list = list;
        this.itensPerPage = itensPerPage;
        this.totalPages = list.length/itensPerPage;
    }
    
    getBeginRange(finalRange) {
        let startRange = finalRange - this.itensPerPage;
        return startRange < 1 ? 0 : startRange;
    }

    getPage(page) {
        const finalRange = this.itensPerPage * page;
        const startRange = this.getBeginRange(finalRange);
        return this.list.slice(startRange, finalRange);
    }
}

Observe que na função getBeginRange temos uma verificação na variável startRange, para iniciar em 0 caso o valor seja zero ou negativo. Isso evita erros e arrays vazios no getPage.

Com isso já temos um serviço para paginação de informações na memória, isso facilita para lidar com grandes listas e para exibi-las com mais performance, principalmente no front-end web onde renderizar pode ser um gargalo, no próximo artigo, vamos usar isso com React em um scroll infinito.


Photo by Plush Design Studio from Pexels