站長阿川

站長阿川私房教材:
學 JavaScript 前端,帶作品集去面試!

站長精心設計,帶你實作 63 個小專案,得到作品集!

立即開始免費試讀!

無論是生成分享卡片、匯出報表,還是保存一段精美排版內容,前端同學都繞不開它。

但問題來了——市面上的截圖工具,比如 html2canvas,雖然用得多,卻有一個致命缺陷:慢!普通截圖動輒 1 秒以上,大一點的 DOM,甚至能直接卡到懷疑人生,用戶體驗一言難盡。

大家好,我是芝士,歡迎點此掃碼加我微信 Hunyi32交流,最近創建了一個低代碼/前端工程化交流群,歡迎加我微信 Hunyi32 進群一起交流學習,也可關注我的公眾號[ 前端界 ] 持續更新優質技術文章

最近發現一個保存速度驚艷到我的庫snapDOM

這貨在性能上的表現,完全可以用「碾壓」來形容:

  • 👉 相比 html2canvas,快 32 ~ 133 倍
  • 👉 相比 modern-screenshot,也快 2 ~ 93 倍

image

以下是官方基本測試數據:

場景 snapDOM vs html2canvas snapDOM vs dom-to-image
小元素 (200×100) 32 倍 6 倍
模態框 (400×300) 33 倍 7 倍
整頁截圖 (1200×800) 35 倍 13 倍
大滾動區域 (2000×1500) 69 倍 38 倍
超大元素 (4000×2000) 93 倍 🔥 133 倍

📊 數據來源:snapDOM 官方 benchmark(基於 headless Chromium 實測)。

⚡ 為什麼它這麼快?

二者的實現原理不同

html2canvas 的實現方式

  • 原理:透過遍歷 DOM,把每個節點的樣式(寬高、字體、背景、陰影、圖片等)計算出來,然後在 <canvas> 上用 Canvas API 重繪一遍。
  • 特點:
    • 需要完整計算 CSS 樣式 → 排版 → 繪製。
    • 複雜 DOM 時計算量極大,比如漸變、陰影、字體渲染都會消耗 CPU。
    • 整個過程基本是 模擬瀏覽器的渲染引擎,屬於「重造輪子」。

所以一旦 DOM 大、樣式複雜,html2canvas 很容易出現 1s+ 延遲甚至卡死。

snapDOM 的實現方式

原理:利用瀏覽器 原生渲染能力,而不是自己模擬

snapDOM 的 captureDOM 並不是自己用 Canvas API 去一筆一筆繪製 DOM(像 html2canvas 那樣),而是:

  1. 複製 DOM 節點(prepareClone)
    • → 生成一個「克隆版」的 DOM,裡面包含了樣式、結構。
  2. 把圖片、背景、字體都轉成 inline(base64 / dataURL)
    • → 確保克隆 DOM 是完全自包含的。
  3. <foreignObject> 包在 SVG 裡面
    • → 瀏覽器原生支持直接渲染 HTML 片段到 SVG → 再轉成 dataURL。

所以核心就是:
👉 利用瀏覽器自己的渲染引擎(SVG foreignObject)來排版和繪製,而不是 JS 重造渲染過程

如何使用 snapDOM

snapDOM 上手非常簡單, 學習成本比較低。

1. 安裝

透過npm 安裝:

npm install @zumer/snapdom

或者直接用 CDN 引入:

<script src="https://cdn.jsdelivr.net/npm/@zumer/snapdom/dist/snapdom.min.js"></script>

2. 基礎用法

只需要一行代碼,就能把 DOM 節點「變」成圖片:

// 選擇你要截圖的 DOM 元素
const target = document.querySelector('.card');

// 匯出為 PNG 圖片
const image = await snapdom.toPng(target);

// 直接添加到頁面
document.body.appendChild(image);

3. 更多匯出方式

除了 PNG,snapDOM 還支持多種輸出格式:

// 匯出為 JPEG
const jpeg = await snapdom.toJpeg(target);

// 匯出為 SVG
const svg = await snapdom.toSvg(target);

// 直接保存為檔案
await snapdom.download(target, { format: 'png', filename: 'screenshot.png' });

4. 匯出一個這樣的海報圖

image

開發中生成海報並保存到,是非常常見的需求,以前使用html2canvas,也要寫不少代碼,還要處理圖片失真等問題,使用snapDOM,真的一行代碼能搞定。

<div ref="posterRef" class="poster">
   ....
</div>

<script setup lang="ts">
  const downloadPoster = async () => {
    if (!posterRef.value) {
        alert("海報元素未找到");
        return;
    }

    try {
        // snapdom 是 UMD 格式,透過全局 window.snapdom 訪問
        const snap = (window as any).snapdom;
        if (!snap) {
            alert("snapdom 庫未加載,請刷新頁面重試");
            return;
        }
        await snap.download(posterRef.value, {
            format: "png",
            filename: `tech-poster-${Date.now()}`
        });
    } catch (error) {
        console.error("海報生成失敗:", error);
        alert("海報生成失敗,請重試");
    }
};
</script>

相比傳統方案需要大量配置和兼容性處理,snapDOM 真正做到了 一行代碼,快速生成。無論是分享卡片、行銷海報還是報表匯出,都能輕鬆搞定。

await snap.download(posterRef.value, {
    format: "png",
    filename: `tech-poster-${Date.now()}`
});

大家好,我是芝士,歡迎點此掃碼加我微信 Hunyi32交流,最近創建了一個低代碼/前端工程化交流群,歡迎加我微信 Hunyi32 進群一起交流學習,也可關注我的公眾號[ 前端界 ] 持續更新優質技術文章

總結

在前端開發裡,DOM 截圖是一個常見但「讓人頭疼」的需求。

  • html2canvas 代表的傳統方案,雖然功能強大,但性能和體驗常常拖後腿;
  • 而 snapDOM 借助瀏覽器原生渲染能力,讓截圖變得又快又穩。

一句話:


原文出處:https://juejin.cn/post/7542379658522116123


共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
站長阿川

站長阿川私房教材:
學 JavaScript 前端,帶作品集去面試!

站長精心設計,帶你實作 63 個小專案,得到作品集!

立即開始免費試讀!