canvas.toBlob() requires a callback function but canvas.toDataURL() returns the result synchronously. Why the difference? It's not a problem, but I'm super curious and I can't find an explanation for why it is that way.
Because toDataURL
was an early error...
At the time it was implemented (by Safari IIRC), the FileAPI was still only being discussed and exporting the result of a canvas was already a need. So they made this method, which does return the data in a convenient data URL, that you can use directly as the src
of several elements in the document. At this time, returning it synchronously sound like a good idea, everything in the Canvas API was synchronous.
But a few years later, with more and more implementations, more and more uses, and new APIs, it became obvious that toDataURL
was not a good idea. Just like synchronous XHR if you are old enough to remember.
Even though you can have the data URL in a synchronous way, to display it will be an asynchronous task anyway.
To generate an image file from a canvas is a slow operation, you need to export all the pixel data, un-multiply it, and then call the compression algorithms.
Added to that, a data URL needs to be stored as a base64 encoded String, 34% bigger than the binary data it represents, and copied in memory every time you assign it somewhere in the DOM...
The FileAPI introduced ways to hold binary data in memory, and to be able to display it, manipulate it or send it as is to a server. All this implying minimal memory overhead => data URLs became obsolete (for most cases).
So it has been decided to add a new method, that would take advantage of these new APIs, and which would return a Blob instead of a data URL. In the common fight against UI blocking operations, it has been decided that this method would be asynchronous (, but unfortunately, that was before Promise came-in...). Now all that has to be done synchronously is to grab the pixel data, like getImageData
does. The remaining operations can be done in-parallel.