無論是生成分享卡片、匯出報表,還是保存一段精美排版內容,前端同學都繞不開它。
但問題來了——市面上的截圖工具,比如 html2canvas,雖然用得多,卻有一個致命缺陷:慢!普通截圖動輒 1 秒以上,大一點的 DOM,甚至能直接卡到懷疑人生,用戶體驗一言難盡。
大家好,我是芝士,歡迎點此掃碼加我微信 Hunyi32交流,最近創建了一個低代碼/前端工程化交流群,歡迎加我微信 Hunyi32 進群一起交流學習,也可關注我的公眾號[ 前端界 ] 持續更新優質技術文章
最近發現一個保存速度驚艷到我的庫snapDOM。
這貨在性能上的表現,完全可以用「碾壓」來形容:
以下是官方基本測試數據:
場景 | 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 實測)。
二者的實現原理不同
<canvas>
上用 Canvas API 重繪一遍。所以一旦 DOM 大、樣式複雜,html2canvas 很容易出現 1s+ 延遲甚至卡死。
原理:利用瀏覽器 原生渲染能力,而不是自己模擬。
snapDOM 的 captureDOM
並不是自己用 Canvas API
去一筆一筆繪製 DOM(像 html2canvas 那樣),而是:
<foreignObject>
包在 SVG 裡面
所以核心就是:
👉 利用瀏覽器自己的渲染引擎(SVG foreignObject)來排版和繪製,而不是 JS 重造渲染過程。
snapDOM 上手非常簡單, 學習成本比較低。
透過npm 安裝:
npm install @zumer/snapdom
或者直接用 CDN 引入:
<script src="https://cdn.jsdelivr.net/npm/@zumer/snapdom/dist/snapdom.min.js"></script>
只需要一行代碼,就能把 DOM 節點「變」成圖片:
// 選擇你要截圖的 DOM 元素
const target = document.querySelector('.card');
// 匯出為 PNG 圖片
const image = await snapdom.toPng(target);
// 直接添加到頁面
document.body.appendChild(image);
除了 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' });
開發中生成海報並保存到,是非常常見的需求,以前使用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 截圖是一個常見但「讓人頭疼」的需求。
一句話: