Utilizando Cache em suas Views para Melhorar o Desempenho de seus Módulos PrestaShop

Neste artigo falarei sobre um assunto de grande importância no desenvolvimento de módulos PrestaShop: a utilização de cache para melhorar a performance dos mesmos. A importância desse assunto é maior ainda quando falamos de módulos que são utilizados no Front-Office da loja, pois uma simples um módulo mal escrito pode comprometer seriamente o tempo de carregamento da loja. A boa notícia é que é bastante simples de se utilizar o cache interno do PrestaShop.

Como você já deve saber, todo o HTML da loja é (ou deveria ser) gerado através de alguma linguagem de template (smarty por padrão). Por se tratar de uma linguagem de template, ela deve ser compilada para a obtenção do HTML que será enviado ao navegador. Assim, se nenhum cache for utilizado, toda vez que uma página da loja for acessada, diversos arquivos de template devem ser compilados, mesmo que o resultado da compilação seja exatamente o mesmo que foi produzido na última vez que a loja foi acessada. Além de isso ser um desperdício de recursos do servidor, também faz com que o usuário espere mais tempo do que é necessário para que a página seja carregada. A situação é ainda pior quando o banco de dados precisa ser utilizado para obter os dados a serem utilizados no template.

Mas, conforme já foi dito, o sistema de cache do PrestaShop é bastante simples de ser utilizado, e você só precisará adicionar algumas poucas linhas de código ao seu módulo. Suponhamos que o seu módulo gere algum conteúdo a ser exibido no Front-Office da loja no hook displayShoppingCartFooter. Assim, o seu hook será algo como

Quando esta função for executada, se houver alguma versão do template ‘mytemplate.tpl’ em cache, o PrestaShop automaticamente utilizará essa versão, ao invés de recompilar o template. Se o nosso template não dependesse da variável $data, não precisaríamos fazer nada além disso para utilizar o sistema de cache do PrestaShop. Contudo, conforme o valor do carrinho de compras muda, o HTML produzido por esse template pode ser diferente. Isso faz com que precisemos de versões diferentes em cache desse mesmo template, que possam ser identificadas a partir do valor do carrinho de compras.

Isso pode ser feito utilizando o terceiro argumento do método Module::display(), denominado $cache_id, da seguinte forma:

Assim, o PrestaShop se encarregará de utilizar a versão em cache do template mytemplate.tpl associada ao cache $cache_id. Uma boa prática é utilizar o método Module::getCacheId(), que já gera uma string contendo as seguintes informações:

  • A loja foi acessada utilizando conexão segura ou não;
  • ID da loja acessada (no caso de multilojas);
  • ID do grupo de cliente a que o usuário que acessou a loja pertence;
  • Idioma utilizado pelo cliente no acesso à loja;
  • Moeda utilizada pelo cliente;
  • País selecionado pelo cliente.

Assim, um cache_id bastante interessante pode ser obtido como a seguir

Agora, observe que, caso o template esteja em cache e não precise ser recompilado, o objeto $data$ não será utilizado. Assim, podemos otimizar a nossa função verificando se há algum cache válido para o nosso template antes de chamar o método MyModel::getSomeDbData().

Por fim, a invalidação do cache pode ser feita através do método Module::_clearCache(). Caso desejemos limpar todos os caches associados ao nosso template sempre que sempre que qualquer objeto da classe MyModel for modificado, podemos utilizar o hook actionObjectMyModelUpdateAfter. Esse hook é invocado automaticamente pelo PrestaShop sempre que o método update() for executado com sucesso em um objeto da classe MyModel (que deve extender a classe ObjectModel do PrestaShop).

O método Module::_clearCache() também suporta o parâmetro $cache_id, para que possamos limpar o cache de apenas uma das versões do template.

Salvando suas views em Cache utilizando Redis e o Framework Express

Olá novamente. Nesse post, mostrarei como utilizar o pacote express-redis-cache para salvar suas views em cache, reduzindo, assim, o tempo de carregamento das páginas.

O pacote é bastante simples de ser utilizado, mas também é bastante completo. Utilizando-o no blog, não senti falta de nenhum recurso adicional. Seu desempenho também é bastante satisfatório, visto que os caches são armazenados num servidor Redis.

Instalação e Configuração

Para instalá-lo, adicione o pacote express-redis-cache às dependências de seu arquivopackage.json, ou digite

Neste tutorial assumirei que a versão do pacote express-redis-cache instalada é a mais recente até o momento (0.1.7).

Para utilizá-lo, devemos informar os parâmetros de conexão do servidor Redis.

O parâmetro prefix é utilizado para formar as string que identificarão cada uma das páginas armazenadas em cache.

Se você já tiver uma conexão Redis estabelecida, pode utilizar o parâmetro {client : redis_client} na inicialização, omitindo host, port e auth_pass. Se for necessário a utilização de senha para a conexão ser realizada, essa é, até o momento, a única forma de isso ser feito.

Utilização Básica

Para utilizar o pacote, devemos adicionar seu middleware a todas as rotas em que desejamos utilizá-lo.

Isso pedirá ao pacote para verificar se há alguma entrada de nome APP_NAME + '/' armazenada em cache. Em caso negativo, a função home será executada, e enviará a string ‘Welcome to my app’ como resposta à requisição.

Essa resposta será automaticamente salva em cache, com a entrada APP_NAME + '/'. Enquanto esse cache não expirar, a função home() não será mais executada.

Alterando o nome das Entradas

Você pode alterar o nome de uma entrada como a seguir.

ou fazendo

ou, ainda,

Decidindo Utilizar (ou não) Cache

Você pode escolher não utilizar a resposta armazenada em cache, mesmo se ela ainda não tiver expirado. Para isso, faça

Sobrescrevendo o parâmetro expire

Para alterar a vida útil padrão do cache, utilize

Excluindo entradas do cache

Você pode excluir entradas do cache, mesmo que elas ainda não tenham expirado.

Se você possui paginação em sua home, com cada página salva com as entradas home.page.0,home.page.1, e assim por diante, você pode excluir todas as entradas numa única chamada à função del().

Debugando

Várias mensagens de log são enviadas pelo pacote utilizado. Para escutá-las, faça

E é isso! Para aplicações de médio/grande porte, salvar as views em cache trará um ganho considerável de performance. Contudo, deve-se tomar cuidado para remover o cache sempre que o conteúdo do site for alterado. Afinal Você não quer uma página com um html antigo incluindo um javascript modificado, quer?