TIL: canvas.toBlob() is the right API for exporting Canvas content
toDataURL() blocks the main thread. toBlob() is async, integrates with the File API, and produces a proper binary Blob — use it for anything the user will download or share.

While building the share feature for Chromatic, I needed to export a side-by-side canvas composite as a downloadable image. I reached for toDataURL() first. I shouldn't have.
The problem with toDataURL()
toDataURL() is synchronous. For a small canvas it's fine. For a large canvas — say, a composite of two screenshots at full viewport size — it blocks the main thread while it encodes the PNG. On slower devices, that's a noticeable freeze.
download-with-toDataURL.js
// Synchronous — blocks the main thread
const dataUrl = canvas.toDataURL("image/png");
const link = document.createElement("a");
link.href = dataUrl;
link.download = "result.png";
link.click();It also produces a base64 string that has to be parsed back into binary if you ever want to send it to a server or use the File API.