ZyVOP Logo
Content That Connects
SeriesAI NewsLeaderboardWrite for Us
ZyVOP Logo
Content That Connects

Empowering developers and creators with cutting-edge insights, comprehensive tutorials, and innovative solutions for the digital future.

Content

  • Categories
  • Tags
  • Badges
  • Leaderboard
  • Write Article
  • Newsletter

Company

  • About Us
  • API Documentation
  • Write for Us
  • Contact

Connect

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DMCA Policy
  • Code of Conduct

© 2026 ZyVOP. Crafted with care for the developer community.

Made with ❤️ by the ZyVOP team
All systems operational
HomeArchitectureTiled Rasterization for Large DOM Captures
Architecture

Tiled Rasterization for Large DOM Captures

How SnapDOM captures one SVG and rasterizes it in bounded tiles—without allocating a full-page bitmap.

Tinchox5
Tinchox5Senior Diplomat
August 11, 2026
4 min read
#web-performance#snapdom#JavaScript#canvas#dom-to-image#browser-api
👍1

A full-page DOM capture can succeed as SVG and still fail at the next step: turning that SVG into one enormous bitmap.

That is the problem SnapDOM addresses with tiled rasterization. The key is not merely to split the final canvas. It is to move the cut earlier—before the browser decodes the image.

TL;DR: Capture the DOM once, move a tile-sized window across the resulting SVG, and rasterize each window into its own canvas. You keep the requested resolution without ever allocating a full-page bitmap.

The hidden limit behind “full-page screenshots”

A full-page capture involves two very different artifacts:

  1. A serialized SVG containing a styled DOM clone inside <foreignObject>.
  2. The bitmap created when the browser decodes that SVG for Canvas, PNG, JPEG, or WebP.

The SVG can describe a document tens of thousands of pixels tall. The bitmap is where browsers usually push back. The practical ceiling depends on the browser and the machine, but oversized images can make img.decode() fail with an unhelpful EncodingError, or cause canvas allocation to fail afterward.

For a normal export, downscaling is a sensible fallback. But it is the wrong trade-off when the pixels themselves are the product: deep-zoom viewers, page renderers, print pipelines, tiled uploads, or visual archives should not lose resolution just because one giant bitmap is a poor container.

Cut the SVG, not the canvas

The obvious mosaic algorithm does not solve the problem:

  1. Render one giant canvas.
  2. Use drawImage() to cut it into smaller canvases.

By the time step two begins, the browser has already decoded and allocated the giant bitmap. The workaround arrives too late.

SnapDOM moves the crop earlier. With toCanvas({ crop }), SnapDOM rewrites the SVG root’s width, height, and viewBox so they describe only the requested window. Only then is the SVG passed to Image.decode().

The pipeline becomes:

Capture once → move the window → decode one small tile → consume it → repeat

The DOM is still cloned, styled, and serialized only once. Exporting ten tiles does not repeat font embedding, image inlining, or style collection ten times.

A practical tiling loop

The reliable crop bounds come from the capture metadata, not from reading the live element again.

async function tileCapture(capture, options, consume) {
  const {
    tileWidth = 2048,
    tileHeight = 2048,
    scale = 1,
    dpr = 1
  } = options

  const { contentX, contentY, w0, h0 } = capture.meta

  for (let y = 0, row = 0; y < h0; y += tileHeight, row++) {
    for (let x = 0, col = 0; x < w0; x += tileWidth, col++) {
      const width = Math.min(tileWidth, w0 - x)
      const height = Math.min(tileHeight, h0 - y)

      const crop = {
        x: contentX + x,
        y: contentY + y,
        width,
        height
      }

      const canvas = await capture.toCanvas({ crop, scale, dpr })
      await consume({ canvas, crop, row, col })
    }
  }
}

const capture = await snapdom(document.documentElement, { dpr: 1 })

await tileCapture(capture, {}, async ({ canvas, row, col }) => {
  const blob = await new Promise(resolve =>
    canvas.toBlob(resolve, 'image/png')
  )

  if (!blob) throw new Error('PNG encoding failed')

  try {
    await uploadTile(blob, { row, col })
  } finally {
    canvas.width = canvas.height = 0
  }
})

Exports on a single capture are queued, so the tiles rasterize in order instead of competing for decode and canvas memory. For genuinely large documents, encode, upload, or write each tile and release it before requesting the next one.

Geometry is part of the feature

Starting every mosaic at 0, 0 is not always correct. Root transforms, asymmetric shadows, outlines, and clipping can move the logical content inside the SVG viewBox.

SnapDOM exposes the final immutable geometry through result.meta:

Property What it measures Typical use
w0 / h0 Logical capture box Tile only the page content
contentX / contentY Content origin inside the viewBox Position the first content tile
vbW / vbH Complete serialized artifact Include shadows, bleed, and outer effects

Use contentX, contentY, w0, and h0 when you want the logical page. Use the complete viewBox when every pixel of transformed bleed or shadow must survive.

What tiling does—and does not—solve

Tiling removes the full-bitmap allocation from the equation. It does not turn DOM capture into a streaming renderer.

A few limits still matter:

  • Lazy or virtualized sections must exist in the DOM before capture.
  • Each tile, after scale × dpr, must still fit the browser’s raster limits.
  • Keeping every tile alive can consume the same total number of pixels in aggregate.
  • Stitching the tiles back into one giant canvas recreates the original problem.
  • SnapDOM still clones the full subtree, reads its styles, inlines assets, and stores the serialized SVG.
  • Each crop still parses the full <foreignObject> payload.

If the initial DOM walk is the bottleneck, clip is the complementary tool: it prunes off-window subtrees before styling and inlining, but requires a separate capture for every region. By contrast, crop reuses one frozen artifact, keeping fonts, images, animations, and live data consistent across all tiles.

Where tile windows are useful

The original use case was document export, where a tall capture naturally becomes PDF pages. The same mechanism works well for:

  • Deep-zoom or map-style viewers
  • Poster and large-format printing
  • Zoomable archives
  • Multipart uploads
  • Custom SnapDOM exporters and plugins

The claim is intentionally narrower than “unlimited screenshots.” One stable DOM snapshot becomes a sequence of bounded raster jobs. When every tile fits, the document no longer needs a global downscale.

Try the interactive mosaic

The original SnapDOM article includes a live demo that captures a 640 × 2,400 px report once and reconstructs it from ten independent canvases.

Open the interactive demo and full technical article →

You can also explore the Canvas crop API or view SnapDOM on GitHub.


Originally published by Zumerlab on the SnapDOM blog. This adapted version links back to the canonical article and interactive demo.

Tinchox5

Tinchox5

Senior Diplomat

Tech Diplomat

Comments (0)

Login to post a comment.

Related Posts

Angular 22: The End of Boilerplate and the Consolidation of the Reactive Era

If you have been following the evolution of Google's framework over the last few years, you know it has been undergoing a silent reconstruction — piece by piece...

Read article

Trusted Types Is Baseline: DOM XSS Is Now a Type Error

Firefox 148 shipped Trusted Types in February 2026, making it Baseline. Here's how to turn every dangerous innerHTML assignment in your app into a TypeError you can actually catch.

Read article

The Long Animation Frames API: Find What Actually Broke Your INP

Your field data says INP is 400ms. Your local profile says everything is fine. The Long Animation Frames API closes that gap by naming the script, the function, and the character position that stalled the frame.

Read article

From Zero-Latency Algorithms to Production Scale: Architectural Lessons Building High-Performance SaaS Ecosystems

A deep architectural exploration into scalable software engineering, zero-latency computational math, self-healing iframe widgets, and full-stack UI design systems from the founder behind ScaleQo and Quranbookk.

Read article

How to Make a Product Demo Video in React

This is a build log for a 30-second product demo video, written entirely in React and rendered to an .mp4 you can drop on a landing page, post to X, or attach t...

Read article