Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
LoginSign Up
menu
  1. Home
  2. /Web Development
  3. /Html
  4. /Web Workers
Your Progress0%
0 of 76 completed

Topics

Getting Started

  • What is HTML?
  • How the Web Works
  • Setting Up Your Environment
  • Your First HTML Page

HTML Document Structure

  • The DOCTYPE Declaration
  • The HTML Element
  • The Head Section
  • Meta Tags
  • The Body Element
  • HTML Comments

Text and Formatting

  • Headings (h1-h6)
  • Paragraphs
  • Line Breaks and Horizontal Rules
  • Text Formatting (Bold, Italic, etc.)
  • Quotations and Citations
  • Preformatted Text and Code
  • Subscript and Superscript

Links and Navigation

  • Creating Links
  • Absolute vs Relative URLs
  • Link Targets and Attributes
  • Email and Phone Links
  • Internal Page Links

Images and Media

  • Adding Images
  • Image Attributes
  • Image Formats
  • Figure and Figcaption
  • Responsive Images
  • Audio Elements
  • Video Elements
  • Embedding Content

Lists

  • Unordered Lists
  • Ordered Lists
  • Description Lists
  • Nested Lists

Tables

  • Table Basics
  • Table Headers and Footers
  • Spanning Columns and Rows
  • Table Captions
  • Styling Tables

Forms - Part 1 (Basics)

  • Introduction to Forms
  • Text Input Fields
  • Labels and Placeholders
  • Textarea Element
  • Checkboxes
  • Radio Buttons

Forms - Part 2 (Advanced)

  • Select Dropdowns
  • File Upload Inputs
  • HTML5 Input Types
  • Form Validation
  • Form Buttons
  • Fieldsets and Legends
  • Form Accessibility

Semantic HTML

  • What is Semantic HTML?
  • Header and Footer
  • Nav Element
  • Main and Article
  • Section and Aside
  • Div vs Semantic Elements
  • Time and Mark Elements

HTML5 Features

  • HTML5 Overview
  • Canvas Element
  • SVG in HTML
  • Geolocation API
  • Drag and Drop
  • Local Storage
  • Web Workers

Web Accessibility

  • Introduction to Accessibility
  • ARIA Attributes
  • Keyboard Navigation
  • Alt Text Best Practices
  • Color Contrast and Typography
  • Testing for Accessibility

Best Practices & SEO

  • HTML Best Practices
  • SEO Fundamentals
  • Meta Tags for SEO
  • Structured Data

Web Workers

Run JavaScript in background threads for better performance

Web Workers are a powerful HTML5 feature that allows you to run JavaScript code in background threads, separate from the main execution thread. This prevents heavy computations from blocking the user interface, keeping your application responsive and smooth.

What are Web Workers?

Normally, JavaScript runs on a single thread, which means heavy calculations can freeze your webpage. Web Workers solve this by:

  • Running JavaScript in separate background threads
  • Performing computations without blocking the UI
  • Enabling true parallel processing in web applications
  • Communicating with the main thread through message passing

When to Use Web Workers

Web Workers are ideal for:

  • Complex mathematical calculations
  • Processing large datasets or arrays
  • Image or video manipulation
  • Parsing large JSON or XML files
  • Text analysis or search operations
  • Real-time data processing
  • Cryptographic operations

Creating a Web Worker

To create a worker, you need two files: your main JavaScript file and a separate worker file.

Worker File (worker.js)

worker.js
// This code runs in the worker thread
// Listen for messages from the main thread
self.addEventListener('message', function(e) {
  console.log('Worker received:', e.data);
  
  // Do some heavy computation
  const result = performHeavyTask(e.data);
  
  // Send result back to main thread
  self.postMessage(result);
});

function performHeavyTask(data) {
  // Simulate heavy computation
  let result = 0;
  for (let i = 0; i < data; i++) {
    result += Math.sqrt(i);
  }
  return result;
}

// Alternative: Use onmessage instead of addEventListener
// onmessage = function(e) {
//   const result = performHeavyTask(e.data);
//   postMessage(result);
// };

Main File

main.js
// Check if browser supports Web Workers
if (window.Worker) {
  // Create a new worker
  const myWorker = new Worker('worker.js');
  
  // Send data to worker
  myWorker.postMessage(1000000);
  console.log('Message sent to worker');
  
  // Listen for messages from worker
  myWorker.addEventListener('message', function(e) {
    console.log('Result from worker:', e.data);
  });
  
  // Handle errors
  myWorker.addEventListener('error', function(e) {
    console.error('Worker error:', e.message);
  });
} else {
  console.log('Web Workers are not supported in this browser');
}

Complete Example

Here's a practical example showing how Web Workers prevent UI freezing:

worker-demo.html
<!DOCTYPE html>
<html>
<head>
  <title>Web Worker Demo</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      padding: 20px;
    }
    button {
      padding: 10px 20px;
      margin: 10px 5px;
      font-size: 16px;
      cursor: pointer;
    }
    #result {
      margin-top: 20px;
      padding: 15px;
      background: #f0f9ff;
      border-left: 4px solid #3b82f6;
    }
    .spinner {
      display: inline-block;
      width: 20px;
      height: 20px;
      border: 3px solid #f3f3f3;
      border-top: 3px solid #3b82f6;
      border-radius: 50%;
      animation: spin 1s linear infinite;
    }
    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
  </style>
</head>
<body>
  <h1>Web Worker Demo</h1>
  
  <p>Try clicking this button while calculation is running:</p>
  <button id="testBtn">Test UI Responsiveness</button>
  <span id="clickCount">Clicks: 0</span>
  
  <hr>
  
  <button id="startWorker">Calculate with Worker (Non-blocking)</button>
  <button id="startNormal">Calculate without Worker (Blocking)</button>
  
  <div id="result"></div>

  <script>
    const testBtn = document.getElementById('testBtn');
    const clickCount = document.getElementById('clickCount');
    const startWorkerBtn = document.getElementById('startWorker');
    const startNormalBtn = document.getElementById('startNormal');
    const resultDiv = document.getElementById('result');
    
    let clicks = 0;
    
    // Test UI responsiveness
    testBtn.addEventListener('click', () => {
      clicks++;
      clickCount.textContent = 'Clicks: ' + clicks;
    });
    
    // Heavy calculation function
    function heavyCalculation(n) {
      let result = 0;
      for (let i = 0; i < n; i++) {
        result += Math.sqrt(i) * Math.sin(i);
      }
      return result;
    }
    
    // Calculate with Web Worker (non-blocking)
    startWorkerBtn.addEventListener('click', () => {
      resultDiv.innerHTML = '<div class="spinner"></div> Calculating with worker...';
      
      const worker = new Worker('calculation-worker.js');
      
      worker.postMessage(50000000);
      
      worker.addEventListener('message', (e) => {
        resultDiv.innerHTML = `<strong>Worker Result:</strong> ${e.data.toFixed(2)}<br>
                                <em>UI remained responsive during calculation!</em>`;
        worker.terminate(); // Clean up
      });
      
      worker.addEventListener('error', (e) => {
        resultDiv.innerHTML = '<strong>Error:</strong> ' + e.message;
      });
    });
    
    // Calculate without worker (blocking)
    startNormalBtn.addEventListener('click', () => {
      resultDiv.innerHTML = '<div class="spinner"></div> Calculating without worker...';
      
      // Use setTimeout to allow UI to update
      setTimeout(() => {
        const result = heavyCalculation(50000000);
        resultDiv.innerHTML = `<strong>Normal Result:</strong> ${result.toFixed(2)}<br>
                                <em>UI was frozen during calculation!</em>`;
      }, 100);
    });
  </script>
</body>
</html>
calculation-worker.js
// calculation-worker.js
self.addEventListener('message', function(e) {
  const n = e.data;
  
  // Perform heavy calculation
  let result = 0;
  for (let i = 0; i < n; i++) {
    result += Math.sqrt(i) * Math.sin(i);
  }
  
  // Send result back
  self.postMessage(result);
});

Worker Scope and Limitations

Web Workers run in a different context and have limitations:

Available in Workers

  • self - reference to the worker itself
  • postMessage() - send messages to main thread
  • importScripts() - load external scripts
  • XMLHttpRequest and fetch API for network requests
  • Web Storage API (localStorage, sessionStorage)
  • Timers (setTimeout, setInterval)
  • WebSockets

NOT Available in Workers

  • DOM manipulation (no access to document or window)
  • Parent page objects
  • Most browser APIs like alert(), confirm(), or prompt()
worker-capabilities.js
// In worker.js

// ✅ This works - importing external scripts
importScripts('utils.js', 'math-library.js');

// ✅ This works - making network requests
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => {
    // Process data
    self.postMessage(data);
  });

// ✅ This works - using timers
setTimeout(() => {
  self.postMessage('Delayed message');
}, 1000);

// ❌ This doesn't work - no DOM access
// document.getElementById('myDiv').textContent = 'Hello';

// ❌ This doesn't work - no window object
// window.alert('Hello');

Terminating Workers

Always terminate workers when you're done to free up resources:

terminate-worker.js
const worker = new Worker('worker.js');

// From main thread
worker.terminate();

// From inside the worker
self.close();

Shared Workers

Shared Workers can be accessed by multiple scripts, even from different windows or tabs:

shared-worker.js
// shared-worker.js
let connections = 0;

self.addEventListener('connect', function(e) {
  connections++;
  const port = e.ports[0];
  
  port.addEventListener('message', function(e) {
    port.postMessage(`Connected clients: ${connections}`);
  });
  
  port.start();
});
use-shared-worker.js
// Using a shared worker
const myWorker = new SharedWorker('shared-worker.js');

myWorker.port.addEventListener('message', function(e) {
  console.log(e.data);
});

myWorker.port.start();
myWorker.port.postMessage('Hello');

Inline Workers

You can create workers without separate files using Blob URLs:

inline-worker.js
// Create worker from inline code
const workerCode = `
  self.addEventListener('message', function(e) {
    const result = e.data * 2;
    self.postMessage(result);
  });
`;

const blob = new Blob([workerCode], { type: 'application/javascript' });
const workerUrl = URL.createObjectURL(blob);
const worker = new Worker(workerUrl);

worker.addEventListener('message', function(e) {
  console.log('Result:', e.data);
});

worker.postMessage(5); // Result: 10

// Clean up
URL.revokeObjectURL(workerUrl);

Error Handling

Always implement proper error handling for workers:

worker-errors.js
const worker = new Worker('worker.js');

// Listen for errors
worker.addEventListener('error', function(e) {
  console.error('Worker error:', e);
  console.error('Filename:', e.filename);
  console.error('Line:', e.lineno);
  console.error('Message:', e.message);
  
  // Prevent error from bubbling
  e.preventDefault();
});

// Alternatively, use onerror
worker.onerror = function(e) {
  console.error('Worker failed:', e.message);
};

Best Practices

  • Check browser support: Always check if Web Workers are available
  • Terminate when done: Free up resources by terminating workers
  • Handle errors: Implement error handlers for robust applications
  • Use for heavy tasks only: Workers have overhead; don't use for simple operations
  • Minimize message passing: Transferring large data can be slow
  • Keep workers simple: Workers should focus on computation, not complex logic
  • Consider Transferable Objects: For large data, use transferable objects instead of copying

Transferable Objects

For better performance with large data, transfer ownership instead of copying:

transferable.js
// Create large array buffer
const buffer = new ArrayBuffer(1024 * 1024); // 1MB

// Transfer (move) instead of copy
worker.postMessage(buffer, [buffer]);

// After transfer, buffer is no longer usable in main thread
console.log(buffer.byteLength); // 0 - buffer was transferred

// In worker
self.addEventListener('message', function(e) {
  const buffer = e.data;
  console.log(buffer.byteLength); // 1048576 - full size
});

Key Takeaways

  • Web Workers run JavaScript in background threads without blocking the UI
  • Use workers for heavy computations, data processing, and complex calculations
  • Workers communicate with the main thread using postMessage() and message events
  • Workers cannot access the DOM or window object
  • Always terminate workers when done to free resources
  • Shared Workers can be accessed from multiple scripts or tabs
  • Use Transferable Objects for efficient large data transfer

What's Next?

You now understand how to use Web Workers to improve application performance through parallel processing. In the next lesson, we'll move into Web Accessibility, starting with an introduction to why accessibility matters for creating inclusive web experiences.

Know someone who'd find this guide helpful? Please share!

Previous
Local Storage
Next
Introduction to Accessibility

Never Miss a New HTML Tutorial

Join 1,000+ developers learning HTML step-by-step. Get new tutorials, tips, and exclusive resources delivered to your inbox - completely FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

Menu

Topics

Getting Started

  • What is HTML?
  • How the Web Works
  • Setting Up Your Environment
  • Your First HTML Page

HTML Document Structure

  • The DOCTYPE Declaration
  • The HTML Element
  • The Head Section
  • Meta Tags
  • The Body Element
  • HTML Comments

Text and Formatting

  • Headings (h1-h6)
  • Paragraphs
  • Line Breaks and Horizontal Rules
  • Text Formatting (Bold, Italic, etc.)
  • Quotations and Citations
  • Preformatted Text and Code
  • Subscript and Superscript

Links and Navigation

  • Creating Links
  • Absolute vs Relative URLs
  • Link Targets and Attributes
  • Email and Phone Links
  • Internal Page Links

Images and Media

  • Adding Images
  • Image Attributes
  • Image Formats
  • Figure and Figcaption
  • Responsive Images
  • Audio Elements
  • Video Elements
  • Embedding Content

Lists

  • Unordered Lists
  • Ordered Lists
  • Description Lists
  • Nested Lists

Tables

  • Table Basics
  • Table Headers and Footers
  • Spanning Columns and Rows
  • Table Captions
  • Styling Tables

Forms - Part 1 (Basics)

  • Introduction to Forms
  • Text Input Fields
  • Labels and Placeholders
  • Textarea Element
  • Checkboxes
  • Radio Buttons

Forms - Part 2 (Advanced)

  • Select Dropdowns
  • File Upload Inputs
  • HTML5 Input Types
  • Form Validation
  • Form Buttons
  • Fieldsets and Legends
  • Form Accessibility

Semantic HTML

  • What is Semantic HTML?
  • Header and Footer
  • Nav Element
  • Main and Article
  • Section and Aside
  • Div vs Semantic Elements
  • Time and Mark Elements

HTML5 Features

  • HTML5 Overview
  • Canvas Element
  • SVG in HTML
  • Geolocation API
  • Drag and Drop
  • Local Storage
  • Web Workers

Web Accessibility

  • Introduction to Accessibility
  • ARIA Attributes
  • Keyboard Navigation
  • Alt Text Best Practices
  • Color Contrast and Typography
  • Testing for Accessibility

Best Practices & SEO

  • HTML Best Practices
  • SEO Fundamentals
  • Meta Tags for SEO
  • Structured Data
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo