Opa pessoal, hoje vou trazer uma dica de otimização bacana que podemos usar em certos cenários que trazem uma performance relevante pra nossa aplicação com poucas mudanças.
Sabe aquelas leituras de arquivos onde carregamos uma config, log, historico, aqueles que carregamos e mantemos em cache no servidor ou que são usado em workers e etc?
Então, sabia que podemos otimizar essas leituras desses arquivos em 16x? ficou curioso pra entender como isso é possível? Xô te expliar:
O módulo fs (File System)
é a espinha dorsal para a manipulação de arquivos. Uma escolha comum que os desenvolvedores enfrentam é entre usar fs.readFile
ou fs.readFileSync
para ler arquivos. Através de um benckmark simples, podemos observar uma disparidade significativa de desempenho entre estas duas funções.
const fs = require( "fs" );
console.time('readFile');
console.time('readFileSync');
fs.readFile( "./package-lock.txt", function (err, data) {
if (err) cb( err );
console.timeEnd('readFile');
});
var data = fs.readFileSync( "./package-lock.txt" );
console.timeEnd('readFileSync');
Resultado:
readFileSync: 0.536ms
readFile: 8.517ms
Análise de Desempenho
O fs.readFileSync
mostrou-se significativamente mais rápido em comparação com o fs.readFile
. Essa diferença de desempenho é atribuída à natureza síncrona de fs.readFileSync
e à natureza assíncrona de fs.readFile
.
Funcionamento Interno
Síncrono (
fs.readFileSync
):O
fs.readFileSync
é uma operação síncrona que bloqueia o event loop até que a leitura do arquivo seja concluída.Este método retorna o conteúdo do arquivo, permitindo que o código subsequente seja executado com os dados disponíveis imediatamente.
Assíncrono (
fs.readFile
):O
fs.readFile
, por outro lado, é uma operação assíncrona que não bloqueia o event loop.Este método aceita uma função de callback que será executada uma vez que a leitura do arquivo seja concluída, permitindo que outras operações sejam processadas em paralelo.
Quando usar um e quando usar o outro.
fs.readFileSync
:Ideal para situações em que a leitura do arquivo precisa ser concluída antes que outras operações possam ser executadas, como na inicialização de um aplicativo ou em scripts de configuração.
fs.readFile
:Mais adequado para ambientes de servidor, ali dentro das requests onde a leitura de arquivos não deve bloquear o processamento de outras requisições, contribuindo para a escalabilidade e responsividade do aplicativo.
Novidades:
Depois que o bun chegou na sua versão 1.0, o time do node está muito focado na performance do runtime, falando especificamente do modulo fs, da uma olhada nessa melhoria que está por vir https://github.com/nodejs/node/pull/49884
Conclusão
A escolha entre fs.readFile
e fs.readFileSync
não deve ser feita apenas com base no desempenho. Embora fs.readFileSync
seja mais rápido, seu uso pode levar a uma aplicação menos responsiva em cenários de alta concorrência. Por outro lado, fs.readFile
, apesar de ser mais lento, oferece um modelo de I/O não bloqueante que pode ser crucial para manter a aplicação ágil e responsiva. Portanto, a escolha apropriada dependerá do contexto específico e das necessidades de desempenho do seu projeto.