Using Multiple WebGL Contexts on a Single Web Page

Yes, multiple independent WebGL contexts can exist simultaneously on a single web page, but doing so comes with strict browser-enforced limits and significant performance trade-offs. While you can initialize separate rendering contexts across different <canvas> elements, browsers restrict the total number of concurrent active contexts. Exceeding these limits leads to context loss, where older contexts are abruptly destroyed by the browser to free GPU memory.

Browser Context Limits

Every web browser imposes a hard limit on the number of active WebGL contexts it can manage simultaneously across a single tab or the entire browser session. Depending on the browser, operating system, and underlying GPU hardware, this limit typically ranges between 8 and 16 contexts, though modern Chromium builds may allow up to 32.

When your application attempts to create a context that exceeds the browser's threshold, the browser triggers a webglcontextlost event on the oldest or least-recently-used context and unloads its GPU resources to allocate memory for the new one.

Performance and Memory Overhead

Each WebGL context acts as an isolated state machine with its own dedicated memory space on the GPU. This isolation introduces two major problems:

  • Resource Duplication: WebGL contexts cannot share resources such as textures, shaders, or geometry buffers natively. If three separate canvases require the exact same 3D model or texture, that asset must be compiled and uploaded to the GPU three separate times.
  • CPU and GPU Overhead: Managing multiple contexts increases CPU overhead due to frequent context switching in the graphics driver, resulting in lower frame rates and increased battery drain on mobile devices.

Because multiple contexts are fragile and resource-heavy, production applications requiring multiple 3D views generally avoid instantiating multiple WebGLRenderingContext or WebGL2RenderingContext instances. Instead, developers use the following patterns:

  1. Single Context with Scissor and Viewport: Use one large, fixed-position or background canvas. During the render loop, map the positions of multiple HTML placeholder elements and use gl.viewport() alongside gl.scissor() to render separate scenes to distinct regions of the single canvas.
  2. OffscreenCanvas with Transfer: Render scenes using a background Web Worker via OffscreenCanvas and transfer the rendered frames as ImageBitmaps to individual 2D canvases on the main thread.

Multiple independent contexts are functionally supported for basic use cases, but architecting your application around a single unified context is essential for stability and performance.