[whatwg] Proposing <canvas>.toBlob(contentType)

Glenn Maynard glenn at zewt.org
Thu Apr 14 07:07:17 PDT 2011

On Thu, Apr 14, 2011 at 2:42 AM, Kyle Huey <me at kylehuey.com> wrote:

> Assuming that Blob.size is here to stay, web developers are just going to
> have to cope with the fact that it's broken and causes synchronous slow
> things to happen.  I believe (though I haven't verified) that in Gecko we
> avoid statting a file on the disk that backs a Blob until Blob.size is
> called (or somebody passes it to a FileReader and we can touch the disk
> asynchronously, etc).

Every existing API that can block while creating a File or Blob object is
asynchronous (other than Worker-only APIs).  The main two are
HTMLInputElement.files and FileAPI's DirectoryEntry.getFile.  Both are
asynchronous by design, so there's no need to defer stat.

I agree it would have been nice for reading the size to be async for APIs
like this.  However, that would also have required Blob.slice() be async,
since it needs to know the size as well.  In any case, we're definitely
stuck with it.

The main drawback of making it asynchronous is that (AIUI, please correct me
> if I'm wrong) everything else about the canvas element and the 2d rendering
> context is synchronous.

I don't think this is actually considered a good thing.  I don't think new
APIs, particularly ones that aren't related to the actual drawing of Canvas,
should be forcibly made synchronous to make them conform with that.

That said, note that UAs have no obligation to actually run compression
asynchronously.  They can always do the simple thing and compress the image
synchronously, and just implement the callback API to return the results.
As long as the resulting API is the same, that should be conforming, it
would just be a low-quality implementation.

>  This adds cognitive overhead both for developers
> and actual code complexity for implementations.  I'll assert, however, that
> the "behind the scenes" complexities of presenting an asynchronous API for
> getting a blob and presenting a synchronous API that performs the
> optimization above are the same.  In particular, in both cases the UA must
> handle:modifications to the canvas after the Blob Getting API is called.

I'm not sure I understand.  getBlob should return a compressed image
containing the Canvas pixel data at the time getBlob was called, just as
DirectoryEntry.getFile returns a File representing file data at the time it
was called.  If the canvas is later changed, the Blob wouldn't change.  The
data a Blob represents is immutable.

Given this, and that providing an asynchronous API to get an object that is
> supposed to be inherently asynchronous seems silly, I would prefer the
> synchronous version here.

It's not silly, it's standard practice, for example DirectoryEntry.getFile
in FileAPI, and every other API for creating Files in FileAPI.

Accessing the data of File (rather, a Blob) is inherently asynchronous, but
*creating* one is not.  It's up to the APIs creating them to do that.

Glenn Maynard

More information about the whatwg mailing list