Real World Example

Real World: Exporting a big report freezes the page

Generating a CSV of 200,000 rows in one loop blocks the main thread: buttons and the spinner freeze. Real apps split the work into chunks (or use a Web Worker) so the browser can update a progress bar between chunks.

async function exportReport(rows, onProgress) {
  const lines = [];
  for (let i = 0; i < rows.length; i += 5000) {
    rows.slice(i, i + 5000).forEach((r) => lines.push(r.join(',')));
    onProgress(Math.round((i / rows.length) * 100));
    await new Promise((r) => setTimeout(r, 0));   // give the event loop a turn to paint
  }
  return new Blob([lines.join('\n')], { type: 'text/csv' });
}