JavaScript contra gigabytes: como o navegador processa Big Data

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Quando o navegador não é um brinquedo, mas um data center

\n\n

Estamos acostumados que o JavaScript vive na sandbox do navegador: animações, cliques, formulários. Mas e se eu disser que com JS puro é possível processar um arquivo CSV de 500 MB, construir um gráfico com 100.000 pontos e não travar a aba? Isso não é fantasia, mas sim o uso inteligente do processamento de grandes dados em JavaScript.

\n

Neste artigo, mostrarei como trabalhar com grandes volumes de dados diretamente no navegador — sem backend, sem Python, sem copiar gigabytes para o servidor. Você aprenderá sobre streaming, Web Workers, otimização de memória e bibliotecas que transformam o navegador em um mini processador de dados. Vamos lá!

\n\n

Por que o processamento "ingênuo" de dados mata a performance

\n

Imagine: você carrega um arquivo CSV de 300 MB e escreve:

\n
const data = await response.json(); // ❌ Erro fatal
\n

O que acontece? O JS tenta analisar o arquivo inteiro na memória RAM. Se o usuário tiver 4 GB de RAM — o navegador trava. Mesmo em um PC potente, o coletor de lixo começa a "engasgar" e a interface congela por um minuto.

\n

Regra nº1: não carregue tudo de uma vez. Grandes dados em JavaScript exigem processamento em fluxo (streaming) e divisão em chunks.

\n\n

Streaming de dados: lendo o arquivo em pedaços

\n

A API do navegador FileReader permite ler o arquivo em partes. Mas ainda mais conveniente é o ReadableStream. Exemplo: processamento de um grande arquivo JSON linha por linha.

\n\n

Exemplo: streaming de JSON com NDJSON

\n

O formato NDJSON (cada linha é um objeto JSON separado) é ideal para grandes dados. Veja como lê-lo em fluxo:

\n
async function* streamJSON(file) {\n  const stream = file.stream();\n  const reader = stream.getReader();\n  const decoder = new TextDecoder();\n  let buffer = '';\n\n  while (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n    buffer += decoder.decode(value, { stream: true });\n    const lines = buffer.split('\\n');\n    buffer = lines.pop(); // resto no buffer\n    for (const line of lines) {\n      if (line.trim()) yield JSON.parse(line);\n    }\n  }\n}\n\n// Uso\nfor await (const obj of streamJSON(selectedFile)) {\n  processRow(obj); // processa um objeto por vez\n}\n
\n

A memória quase não cresce — mantemos apenas uma linha na memória. Essa abordagem é a base do processamento de grandes dados em JavaScript em projetos reais.

\n\n

Web Workers: não travando a interface

\n

Mesmo o streaming é executado na thread principal. Se os cálculos forem complexos — a UI congela. Solução: Web Workers. É uma thread separada onde é possível processar gigabytes sem lag.

\n\n

Criando um Worker para processar CSV

\n

Código do worker (worker.js):

\n
self.onmessage = async function(e) {\n  const { file, chunkSize } = e.data;\n  const reader = new FileReaderSync(); // leitura síncrona — permitido no worker\n  let offset = 0;\n  const results = [];\n\n  while (offset < file.size) {\n    const blob = file.slice(offset, offset + chunkSize);\n    const text = reader.readAsText(blob);\n    const lines = text.split('\\n');\n    for (const line of lines) {\n      if (line.trim()) results.push(parseCSVLine(line));\n    }\n    offset += chunkSize;\n    // Envia resultado intermediário\n    self.postMessage({ type: 'chunk', data: results.splice(0, results.length) });\n  }\n  self.postMessage({ type: 'done' });\n};\n\nfunction parseCSVLine(line) {\n  const [name, age, city] = line.split(',');\n  return { name, age: parseInt(age), city };\n}\n
\n

Thread principal:

\n
const worker = new Worker('worker.js');\nworker.postMessage({ file: csvFile, chunkSize: 1024 * 1024 }); // chunks de 1 MB\n\nworker.onmessage = (e) => {\n  if (e.data.type === 'chunk') {\n    updateUI(e.data.data); // atualiza tabela/gráfico suavemente\n  }\n};\n
\n

Agora a interface permanece responsiva, mesmo processando 2 GB de dados. Essa é a técnica chave para b

Blogs

Book Recommendations