UNPKG

@razz21/vue-scan

Version:

Track and visualize Vue 3 component renders

88 lines (87 loc) 2.66 kB
import { debounce as h } from "../core/utils.js"; import r from "./offscreen-canvas.worker.js"; const n = () => Math.min(window.devicePixelRatio || 1, 2), o = (i) => { const t = i.match(/^rgba?\((\d+), (\d+), (\d+)(?:, [0-1](?:\.\d+)?)?\)$/); if (!t) throw new Error("Invalid color format"); return `${t[1]},${t[2]},${t[3]}`; }, c = 500; class w { canvas = null; options; worker = null; batchRaF = null; batch = []; batchSize = 0; constructor(t, s) { this.options = s, this.canvas = document.createElement("canvas"), this.canvas.style.cssText = ` position: absolute; top: 0; left: 0; width: 100%; height: 100%; `, t.appendChild(this.canvas), this.resizeCanvas(), this.worker = new r({ name: "VueScanOffscreenCanvas" }); const e = this.canvas.transferControlToOffscreen(); this.worker?.postMessage( { type: "init", canvas: e, width: window.innerWidth, height: window.innerHeight, dpr: n(), color: o(this.options.color), duration: this.options.duration }, [e] ), this.onResizeCanvas = h(() => { this.resizeCanvas(), this.worker?.postMessage({ type: "resize", width: window.innerWidth, height: window.innerHeight, dpr: n() }); }, 100), window.addEventListener("resize", this.onResizeCanvas); } async highlight({ rect: t, name: s, uid: e }) { return await new Promise((a) => { if (this.batch.push({ uid: e, name: s, rect: t }), this.batchSize++, this.batchSize >= c) return this.sendBatch(), a(); this.batchRaF || (this.batchRaF = requestIdleCallback(() => { this.batchSize > 0 && this.sendBatch(); })), a(); }); } onResizeCanvas; /** * Send the batch to the worker and reset it. */ sendBatch() { const t = this.batch; this.worker?.postMessage({ type: "highlight", rects: t }), this.batch.length = 0, this.batchSize = 0, this.batchRaF !== null && (cancelAnimationFrame(this.batchRaF), this.batchRaF = null); } deleteElement(t) { this.worker.postMessage({ type: "delete", uid: t }); } resizeCanvas() { this.canvas && (this.canvas.style.width = `${window.innerWidth}px`, this.canvas.style.height = `${window.innerHeight}px`); } clear() { this.canvas?.remove(), this.canvas = null, window.removeEventListener("resize", this.onResizeCanvas), this.worker?.postMessage({ type: "clear" }), this.worker?.terminate(), this.worker = null; } } export { w as VueScanCanvas }; //# sourceMappingURL=index.js.map