Bootcamp backendontwikkeling met Node.js · Les

De Node.js-eventloop optimaliseren

Duik diep in de eventloop om blokkerende bewerkingen te identificeren en asynchrone code te optimaliseren voor betere prestaties.

Les 3 van 411 stappen

De Node.js-eventloop optimaliseren is een gratis Bootcamp backendontwikkeling met Node.js-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Bootcamp backendontwikkeling met Node.js. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Bootcamp backendontwikkeling met Node.js bevat in totaal 4 lessen.

Eventlus: het hart van Node.js

Welkom! Node.js gebruikt een model met één thread, maar verwerkt dankzij zijn eventlus veel bewerkingen gelijktijdig. Deze lus controleert voortdurend welke taken moeten worden uitgevoerd.

Het optimaliseren van de eventlus is cruciaal voor Node.js-applicaties met hoge prestaties. Zo blijft je server reageren en kan die veel gebruikers efficiënt verwerken.

De Node.js-eventloop optimaliseren — illustratie 1

Blokkerende bewerkingen begrijpen

Een blokkerende bewerking (of synchrone bewerking) is een bewerking die de uitvoering van alle andere JavaScript-code stillegt totdat ze is voltooid. Stel je één kassamedewerker voor die stopt om wisselgeld voor één klant te tellen, terwijl een lange rij andere klanten wacht.

In Node.js bevriest een blokkerende bewerking de volledige eventlus, waardoor die andere binnenkomende verzoeken of taken niet kan verwerken. Dit leidt tot trage reactietijden en een slechte gebruikerservaring.

Code herkennen die de processor zwaar belast

Processorgebonden taken zijn bewerkingen die veel processortijd gebruiken. Ze wachten niet op externe bronnen zoals databases of netwerkverzoeken; ze voeren alleen berekeningen uit.

  • Complexe berekeningen
  • Zware gegevenstransformaties
  • Synchrone lussen over zeer grote gegevensverzamelingen
  • Afbeeldingsverwerking of cryptografie

Dit zijn veelvoorkomende oorzaken van een geblokkeerde eventlus als je ze niet zorgvuldig afhandelt.

Demo: een blokkerende lus

Probeer dit voorbeeld uit te voeren. Let erop dat het bericht 'After blocking loop' vertraagd wordt weergegeven. Als dit een server zou zijn, zou die tijdens de uitvoering van de lus niet op andere verzoeken reageren.

console.log("Before blocking loop.");

const startTime = Date.now();
// Simulate a CPU-intensive task
for (let i = 0; i < 5000000000; i++) {
  // Do nothing, just loop
}
const endTime = Date.now();

console.log(`Blocking loop finished in ${endTime - startTime}ms.`);
console.log("After blocking loop.");

// This will be delayed because the loop blocked the event loop
setTimeout(() => {
  console.log("This message is from setTimeout (delayed).");
}, 0);

Processorgebonden werk opsplitsen

Om blokkering te voorkomen, kunnen we grote processorgebonden taken opsplitsen in kleinere delen en de uitvoering ervan uitstellen. Zo kan de eventlus tussen de delen door andere taken verwerken.

  • Gebruik setImmediate() om een functie in te plannen die na de huidige pollfase van de eventlus wordt uitgevoerd.
  • Gebruik process.nextTick() om een functie in te plannen die vóór alle I/O-bewerkingen in de huidige fase van de eventlus wordt uitgevoerd.
  • Gebruik voor echt zware berekeningen workerthreads.

Demo: uitstellen met setImmediate

Hier passen we de blokkerende lus aan met setImmediate. Hierdoor kan de eventlus de callback van setTimeout veel eerder verwerken, ook al wordt al het werk nog steeds uitgevoerd.

console.log("Before deferred loop.");

let count = 0;
const maxCount = 5000000000;

function doWorkChunk() {
  const chunkSize = 10000000; // Process 10 million iterations at a time
  const start = count;
  const end = Math.min(count + chunkSize, maxCount);

  for (let i = start; i < end; i++) {
    // Simulate work
  }

  count = end;

  if (count < maxCount) {
    setImmediate(doWorkChunk); // Schedule next chunk immediately
  } else {
    console.log("Deferred loop finished.");
  }
}

const startTime = Date.now();
setImmediate(doWorkChunk); // Start the deferred work

console.log("After initiating deferred loop.");

// This setTimeout will run much sooner now
setTimeout(() => {
  console.log("This message is from setTimeout (not delayed).");
  const endTime = Date.now();
  console.log(`Total time (approx) for deferred loop: ${endTime - startTime}ms.`);
}, 0);

process.nextTick versus setImmediate

Zowel process.nextTick() als setImmediate() stelt de uitvoering uit, maar ze werken in verschillende fasen van de eventlus:

  • process.nextTick(): voert zijn callback *vóór* alle I/O-callbacks uit tijdens de *huidige* beurt van de eventlus. Dit wordt vaak gebruikt voor foutafhandeling of om het gedrag van callbacks te normaliseren.
  • setImmediate(): voert zijn callback uit tijdens de *checkfase*, *na* de I/O-callbacks en vóór timers tijdens de *volgende* beurt van de eventlus. Dit is ideaal om langlopende taken op te splitsen.

Voorbij de hoofdthread: workerthreads

Voor echt processorintensieve bewerkingen die niet eenvoudig in kleine delen kunnen worden opgesplitst, biedt Node.js workerthreads. Hiermee kun je JavaScript-code parallel uitvoeren in volledig afzonderlijke threads.

Workerthreads blokkeren de hoofd-eventlus helemaal niet. Daardoor zijn ze ideaal voor zware berekeningen, zoals gegevensversleuteling, complexe simulaties of het verwerken van grote bestanden.

Demo: een eenvoudige workerthread

Zo kan een main.js-bestand een worker gebruiken om zware berekeningen uit te besteden. De hoofdthread blijft beschikbaar voor ander werk.

Je hebt ook een worker.js-bestand in dezelfde map nodig:

const { parentPort } = require('worker_threads'); parentPort.on('message', (task) => { console.log('Worker received task:', task); let result = 0; for (let i = 0; i < task; i++) { result += i; // Simulate heavy computation } parentPort.postMessage(result); });
const { Worker } = require('worker_threads');

console.log("Main thread started.");

// Create a new worker thread (requires 'worker.js' file)
const worker = new Worker('./worker.js');

// Listen for messages from the worker
worker.on('message', (msg) => {
  console.log(`Worker finished: Result = ${msg}`);
});

// Listen for errors from the worker
worker.on('error', (err) => {
  console.error(`Worker error: ${err}`);
});

// Listen for worker exit
worker.on('exit', (code) => {
  if (code !== 0)
    console.error(`Worker stopped with exit code ${code}`);
});

// Send a heavy task to the worker
worker.postMessage(500000000); // Send a large number for heavy computation

console.log("Main thread sent task to worker.");
console.log("Main thread continues non-blocking work.");

// Simulate other work in the main thread
let mainThreadCounter = 0;
const intervalId = setInterval(() => {
  console.log(`Main thread doing other work: ${mainThreadCounter++}`);
  if (mainThreadCounter >= 5) {
    clearInterval(intervalId);
  }
}, 100);

Controleer je begrip

Stel je een Node.js-webserver voor. Welke van de volgende bewerkingen blokkeert waarschijnlijk de eventlus en heeft daardoor de grootste negatieve invloed op de reactiesnelheid van de server?

Samenvatting: de eventlus optimaliseren

Goed gedaan! Je hebt geleerd hoe je de eventlus van Node.js soepel laat draaien voor optimale prestaties:

  • Blokkerende code herkennen: Herken synchrone, processorintensieve taken.
  • Werk opsplitsen: Gebruik setImmediate() of process.nextTick() om delen van lange taken uit te stellen.
  • Workerthreads benutten: Besteed zware berekeningen uit aan afzonderlijke threads voor echte parallelle uitvoering.

Door te voorkomen dat de eventlus wordt geblokkeerd, blijven je Node.js-applicaties responsief en efficiënt, zelfs bij een zware belasting.

Gratis beginnen

Leer JavaScript met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
22
Lessen
92

Veelgestelde vragen

Is de les “De Node.js-eventloop optimaliseren” gratis?

Ja — de volledige tekst van “De Node.js-eventloop optimaliseren” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Bootcamp backendontwikkeling met Node.js wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Bootcamp backendontwikkeling met Node.js bevat in totaal 4 lessen.

Wat leer ik in “De Node.js-eventloop optimaliseren”?

Duik diep in de eventloop om blokkerende bewerkingen te identificeren en asynchrone code te optimaliseren voor betere prestaties. Je oefent met Bootcamp backendontwikkeling met Node.js door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Bootcamp backendontwikkeling met Node.js te beginnen?

Ervaring vooraf is niet nodig. Bootcamp backendontwikkeling met Node.js op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “De Node.js-eventloop optimaliseren”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Bootcamp backendontwikkeling met Node.js?

Ja. Elke les over Bootcamp backendontwikkeling met Node.js bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Cachingstrategieën voor Node.js
  2. Load balancing voor uw Node.js-apps
  3. De Node.js-eventloop optimaliseren
  4. Profiling en geheugenlekken opsporen
← Terug naar Bootcamp backendontwikkeling met Node.js