JavaScript contre gigaoctets : comment le navigateur digère le Big Data

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Quand le navigateur n'est pas un jouet, mais un centre de données

\n\n

Nous avons l'habitude que JavaScript vive dans le bac à sable du navigateur : animations, clics, formulaires. Mais que diriez-vous si je vous disais qu'avec du JS pur, on peut traiter un fichier CSV de 500 Mo, construire un graphique avec 100 000 points et ne pas faire planter l'onglet ? Ce n'est pas de la science-fiction, mais une utilisation judicieuse du traitement des grandes données en JavaScript.

\n

Dans cet article, je vais vous montrer comment travailler avec de grands volumes de données directement dans le navigateur — sans backend, sans Python, sans copier des gigaoctets sur le serveur. Vous découvrirez le streaming, les Web Workers, l'optimisation de la mémoire et les bibliothèques qui transforment le navigateur en mini-processeur de données. C'est parti !

\n\n

Pourquoi le traitement « naïf » des données tue les performances

\n

Imaginez : vous chargez un fichier CSV de 300 Mo et vous écrivez :

\n
const data = await response.json(); // ❌ Erreur fatale
\n

Que se passe-t-il ? JS essaie d'analyser tout le fichier en mémoire vive. Si l'utilisateur a 4 Go de RAM — le navigateur plante. Même sur un PC puissant, le ramasse-miettes commence à « ralentir » et l'interface se fige pendant une minute.

\n

Règle n°1 : ne chargez pas tout d'un coup. Les grandes données en JavaScript nécessitent un traitement par flux (streaming) et un découpage en morceaux.

\n\n

Streaming de données : lire le fichier par morceaux

\n

L'API navigateur FileReader permet de lire un fichier par parties. Mais encore plus pratique — ReadableStream. Exemple : traitement d'un gros fichier JSON ligne par ligne.

\n\n

Exemple : streaming JSON avec NDJSON

\n

Le format NDJSON (chaque ligne est un objet JSON distinct) est idéal pour les grandes données. Voici comment le lire en flux :

\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(); // reste dans le tampon\n    for (const line of lines) {\n      if (line.trim()) yield JSON.parse(line);\n    }\n  }\n}\n\n// Utilisation\nfor await (const obj of streamJSON(selectedFile)) {\n  processRow(obj); // traite un objet à la fois\n}\n
\n

La mémoire n'augmente presque pas — nous ne conservons qu'une seule ligne en mémoire. Cette approche est la base du traitement des grandes données JavaScript dans les projets réels.

\n\n

Web Workers : ne bloquons pas l'interface

\n

Même le streaming s'exécute dans le thread principal. Si les calculs sont complexes — l'interface se fige. Solution : Web Workers. C'est un thread séparé où l'on peut manipuler des gigaoctets sans latence.

\n\n

Création d'un Worker pour traiter du CSV

\n

Code du worker (worker.js) :

\n
self.onmessage = async function(e) {\n  const { file, chunkSize } = e.data;\n  const reader = new FileReaderSync(); // lecture synchrone — autorisée dans un 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    // Envoi du résultat intermédiaire\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 }); // morceaux de 1 Mo\n\nworker.onmessage = (e) => {\n  if (e.data.type === 'chunk') {\n    updateUI(e.data.data); // met à jour le tableau/le graphique en douceur\n  }\n};\n
\n

Maintenant, l'interface reste réactive, même si nous traitons 2 Go de données. C'est une technique clé pour le b

Blogs

Book Recommendations