Lesson 41-Browser Principles and Rendering Mechanisms

Browser principles and rendering mechanisms

Overview of Browser Architecture

Modern browsers typically consist of the following core components:

  1. User Interface (UI): Address bar, back/forward buttons, bookmark menu, etc.
  2. Browser Engine: Acts as a bridge between the user interface and the rendering engine.
  3. Rendering Engine: Responsible for displaying requested content (e.g., Chrome’s Blink, Firefox’s Gecko).
  4. Networking Layer: Handles network requests (e.g., HTTP requests).
  5. JavaScript Engine: Interprets and executes JavaScript code (e.g., V8 engine).
  6. UI Backend: Draws basic window widgets (e.g., combo boxes and windows).
  7. Data Storage System: Persistently stores data (e.g., Cookies, LocalStorage).

Detailed Browser Rendering Process

The complete page rendering process includes the following key steps:

  1. Parsing HTML to Build the DOM Tree:
    • The HTML parser converts the HTML document into a DOM node tree.
    • External resources (e.g., CSS, JS) trigger requests when encountered.
  2. Parsing CSS to Build the CSSOM Tree:
    • The CSS parser converts CSS rules into style objects.
    • Forms the CSSOM tree, describing the style rules for elements.
  3. Building the Render Tree:
    • Combines the DOM tree and CSSOM tree.
    • Includes only visible elements (ignores display:none and other invisible elements).
  4. Layout (Reflow):
    • Calculates the precise position and size of each node in the render tree.
    • Recursively computes from the root node.
  5. Painting:
    • Converts layout information into actual pixels on the screen.
    • Includes text, colors, borders, shadows, etc.
  6. Compositing:
    • Combines multiple layers into the final screen image.
    • Leverages GPU acceleration for improved performance.

DOM Tree and CSSOM Tree Construction Process

DOM Tree Construction Example:

<html>
  <head>
    <title>Example</title>
  </head>
  <body>
    <div id="content">
      <p>Hello World</p>
    </div>
  </body>
</html>

DOM Tree Structure:

- Document
  - HTML
    - Head
      - Title
        - "Example"
    - Body
      - Div#content
        - P
          - "Hello World"

CSSOM Tree Construction Example:

body {
  font-size: 16px;
}
div {
  margin: 10px;
}
p {
  color: red;
}

CSSOM Tree Structure:

- CSSOM
  - body
    - font-size: 16px
  - div
    - margin: 10px
  - p
    - color: red

Render Tree and Layout Process

Render Tree Construction Rules:

  1. Traverse from the root node of the DOM tree.
  2. Ignore invisible elements (display:none, script, meta, etc.).
  3. Apply style rules from the CSSOM.
  4. Generate a render tree containing visible content and style information.

Layout (Reflow) Process:

  1. Start from the root node of the render tree.
  2. Calculate geometric information (position, size) for each node.
  3. Consider style properties (e.g., box-sizing, position).
  4. Form the Layout Tree.
// Example code demonstrating layout changes
const div = document.getElementById('myDiv');
div.style.width = '100px'; // Triggers layout
div.style.height = '200px'; // Triggers layout

Repaint and Reflow

Reflow:

  • Occurs when an element’s geometric properties (width, height, position, etc.) change.
  • Requires recalculating the element’s geometry and re-laying out the page.
  • A performance-intensive operation.

Repaint:

  • Occurs when an element’s visual appearance (color, background, etc.) changes without affecting layout.
  • Only requires redrawing affected parts.
  • Less performance-intensive than reflow.

Common Operations Triggering Reflow:

// Modifying geometric properties
element.style.width = '100px';
element.style.margin = '10px';

// Modifying font size
element.style.fontSize = '16px';

// Adding/removing DOM elements
document.body.appendChild(newElement);

// Querying layout properties (forces synchronous layout)
const width = element.offsetWidth; // Triggers reflow

Optimization Strategies:

  1. Batch style modifications (use class or cssText).
  2. Use transform and opacity for animations (triggers compositing, not reflow).
  3. Avoid frequent reading of layout properties.
  4. Use DocumentFragment for batch DOM insertions.

Compositing Layers and Hardware Acceleration

Compositing Layer Concept:

  • The browser divides the page into multiple layers.
  • Each layer is drawn and composited independently.
  • Elements with independent compositing layers can be GPU-accelerated.

Common Ways to Create Compositing Layers:

/* Using will-change to hint the browser */
.element {
  will-change: transform, opacity;
}

/* Using transform or opacity */
.element {
  transform: translateZ(0); /* Triggers hardware acceleration */
  opacity: 0.9;
}

/* Using position: fixed */
.element {
  position: fixed;
  top: 0;
  left: 0;
}

Hardware Acceleration Principles:

  1. Compositing layer content is uploaded to GPU memory.
  2. The GPU handles compositing operations (more efficient than CPU).
  3. Reduces main thread workload, improving performance.

Considerations:

  • Overusing compositing layers consumes more memory.
  • Certain CSS properties force new compositing layers.
  • Use will-change judiciously.

Browser Storage Technologies

Cookie Attributes:

// Setting a Cookie
document.cookie = "username=John; expires=Thu, 18 Dec 2025 12:00:00 UTC; path=/; domain=.example.com; secure; samesite=lax";

Main Attributes:

  • name=value: Key-value pair.
  • expires/max-age: Expiration time.
  • path: Valid path.
  • domain: Valid domain.
  • secure: HTTPS-only transmission.
  • httponly: Prohibits JavaScript access.
  • samesite: Restricts cross-site requests (lax/strict/none).

Security Considerations:

  1. Avoid storing sensitive information in Cookies.
  2. Always use secure and httponly flags.
  3. Set SameSite appropriately to prevent CSRF attacks.
  4. Regularly clean up expired Cookies.

Web Storage API

Comparison of localStorage and sessionStorage:

FeaturelocalStoragesessionStorage
LifecyclePersistent until manually deletedSession-based, cleared when tab closes
ScopeShared across same-origin tabsLimited to current tab
Storage Size~5MB~5MB
APIIdenticalIdentical

Basic Operation Example:

// Storing data
localStorage.setItem('key', 'value');
sessionStorage.setItem('sessionKey', 'sessionValue');

// Retrieving data
const value = localStorage.getItem('key');
const sessionValue = sessionStorage.getItem('sessionKey');

// Removing data
localStorage.removeItem('key');
sessionStorage.removeItem('sessionKey');

// Clearing all data
localStorage.clear();
sessionStorage.clear();

Use Cases:

  • localStorage: User preferences, long-term login state.
  • sessionStorage: Temporary shopping cart data, form drafts.

IndexedDB Database

IndexedDB Features:

  • JavaScript-based object-oriented database.
  • Asynchronous API (avoids blocking UI).
  • Supports transactions.
  • Stores large amounts of structured data.
  • Indexes enable efficient queries.

Basic Operation Example:

// Opening the database
const request = indexedDB.open('MyDatabase', 1);

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  // Creating an object store
  const objectStore = db.createObjectStore('books', { keyPath: 'id' });
  // Creating an index
  objectStore.createIndex('by_title', 'title', { unique: false });
};

request.onsuccess = (event) => {
  const db = event.target.result;

  // Adding data
  const transaction = db.transaction('books', 'readwrite');
  const objectStore = transaction.objectStore('books');
  objectStore.add({ id: 1, title: 'JavaScript Advanced Programming', author: 'John Doe' });

  // Querying data
  const getRequest = objectStore.get(1);
  getRequest.onsuccess = () => {
    console.log(getRequest.result);
  };
};

Transaction Modes:

  • readonly: Read-only transactions.
  • readwrite: Read-write transactions.
  • versionchange: Transactions for schema changes.

Cache API and Service Worker Caching

Cache API Basic Operations:

// Opening/creating a cache
caches.open('my-cache').then(cache => {
  // Adding a cache item
  cache.add('/styles.css'); // Automatically fetches and caches
  // Or finer control
  cache.put('/data.json', new Response(JSON.stringify({ key: 'value' })));

  // Matching cache
  cache.match('/styles.css').then(response => {
    if (response) {
      console.log('Retrieved from cache:', response);
    }
  });

  // Deleting cache item
  cache.delete('/old-resource.js');
});

Service Worker Caching Strategies:

  1. Cache First: Prioritize cache, fallback to network.
  2. Network First: Prioritize network, fallback to cache.
  3. Stale While Revalidate: Return cache while updating cache.
  4. Network Only: Always fetch from network.
  5. Cache Only: Always retrieve from cache.

Example Service Worker Code:

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('v1').then(cache => {
      return cache.addAll([
        '/',
        '/index.html',
        '/styles.css',
        '/script.js'
      ]);
    })
  );
});

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(response => {
      // Return cache if hit
      if (response) {
        return response;
      }
      // Otherwise fetch from network
      return fetch(event.request);
    })
  );
});

Application Cache (AppCache) – Deprecated

AppCache Alternatives:

  • Use Service Worker and Cache API for offline functionality.
  • More flexible and robust caching control.
  • Better error handling mechanisms.

Advanced Browser API Applications

Web Worker Multithreading

Web Worker Basic Usage:

// Main thread code
const worker = new Worker('worker.js');

// Sending message to Worker
worker.postMessage({ data: 'Hello Worker' });

// Receiving Worker message
worker.onmessage = (event) => {
  console.log('Received Worker message:', event.data);
};

// Error handling
worker.onerror = (error) => {
  console.error('Worker error:', error);
};

// Terminating Worker
worker.terminate();

Worker Thread Code (worker.js):

// Receiving main thread message
self.onmessage = (event) => {
  console.log('Received main thread message:', event.data);

  // Performing heavy computation
  const result = heavyCalculation(event.data);

  // Sending result back to main thread
  self.postMessage(result);
};

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

Advanced Use Cases:

  1. Image processing (filters, scaling, etc.).
  2. Big data analysis.
  3. Real-time data stream processing.
  4. Complex algorithm computations.

Service Worker and PWA

Service Worker Lifecycle:

  1. Register
  2. Install
  3. Activate
  4. Running
  5. Terminated

PWA Core Features Implementation:

  1. Offline Operation: Via Service Worker caching.
  2. Push Notifications: Using Push API and Notification API.
  3. Add to Home Screen: Via Web App Manifest.
  4. Background Sync: Background Sync API.

Complete PWA Example:

// service-worker.js
const CACHE_NAME = 'pwa-cache-v1';
const urlsToCache = [
  '/',
  '/index.html',
  '/styles.css',
  '/script.js',
  '/images/logo.png'
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => cache.addAll(urlsToCache))
  );
});

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => response || fetch(event.request))
  );
});

self.addEventListener('activate', event => {
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.filter(cacheName => cacheName !== CACHE_NAME)
          .map(cacheName => caches.delete(cacheName))
      );
    })
  );
});

WebSocket Real-Time Communication

WebSocket Basic Usage:

// Creating WebSocket connection
const socket = new WebSocket('wss://example.com/ws');

// On connection established
socket.onopen = (event) => {
  console.log('WebSocket connection established');
  socket.send('Hello Server!');
};

// On receiving message
socket.onmessage = (event) => {
  console.log('Received message:', event.data);
};

// On connection closed
socket.onclose = (event) => {
  if (event.wasClean) {
    console.log(`Connection closed, code=${event.code} reason=${event.reason}`);
  } else {
    console.log('Connection interrupted unexpectedly');
  }
};

// On error
socket.onerror = (error) => {
  console.error('WebSocket error:', error);
};

// Closing connection
socket.close();

Advanced Use Cases:

  1. Real-time chat applications.
  2. Collaborative editing.
  3. Real-time data dashboards.
  4. Online gaming.

Geolocation API

Acquiring User Location:

if ('geolocation' in navigator) {
  navigator.geolocation.getCurrentPosition(
    (position) => {
      console.log('Latitude:', position.coords.latitude);
      console.log('Longitude:', position.coords.longitude);
      console.log('Accuracy:', position.coords.accuracy);
    },
    (error) => {
      console.error('Location retrieval error:', error.message);
    },
    {
      enableHighAccuracy: true, // High accuracy mode
      timeout: 5000,           // Timeout (milliseconds)
      maximumAge: 0            // No cached location
    }
  );
} else {
  console.error('Browser does not support Geolocation API');
}

Continuous Location Monitoring:

const watchId = navigator.geolocation.watchPosition(
  (position) => {
    console.log('Location updated:', position.coords);
  },
  (error) => {
    console.error('Location monitoring error:', error.message);
  },
  {
    enableHighAccuracy: true,
    maximumAge: 30000, // Maximum age of cached location (milliseconds)
    timeout: 27000     // Timeout (milliseconds)
  }
);

// Stop monitoring
navigator.geolocation.clearWatch(watchId);

Privacy and Security Considerations:

  1. Must be used in HTTPS environment (except localhost).
  2. Requires explicit user authorization.
  3. Provide clear privacy policy explaining data usage.
  4. Allow users to revoke permissions anytime.

WebRTC Audio and Video Communication

WebRTC Basic Architecture:

  1. MediaStream API: Acquires local media streams.
  2. RTCPeerConnection: Establishes peer-to-peer connections.
  3. RTCDataChannel: Data transfer channel.

Acquiring Local Media Stream:

async function getLocalStream() {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({
      audio: true,
      video: true
    });
    // Display local video
    const videoElement = document.getElementById('localVideo');
    videoElement.srcObject = stream;
    return stream;
  } catch (err) {
    console.error('Failed to acquire media stream:', err);
  }
}

Establishing Peer-to-Peer Connection:

// Creating RTCPeerConnection
const pc = new RTCPeerConnection({
  iceServers: [
    { urls: 'stun:stun.l.google.com:19302' }
  ]
});

// Adding local stream
getLocalStream().then(stream => {
  stream.getTracks().forEach(track => {
    pc.addTrack(track, stream);
  });
});

// Handling remote stream
pc.ontrack = (event) => {
  const remoteVideo = document.getElementById('remoteVideo');
  if (remoteVideo.srcObject !== event.streams[0]) {
    remoteVideo.srcObject = event.streams[0];
  }
};

// Signaling server interaction code (simplified)
// In practice, SDP and ICE candidates need to be exchanged via a signaling server

Advanced Use Cases:

  1. Video conferencing systems.
  2. Screen sharing.
  3. Remote assistance.
  4. P2P file transfer.

Membership Required

You must be a member to access this content.

View Membership Levels

Already a member? Log in here

Share your love