« CSS game | Main | Kawasaki touching bloggers »

February 19, 2006

Neuberg on externalInterface

Neuberg on externalInterface: Brad Neuberg wrote a long essay on his dissatisfaction with the externalInterface feature in Flash 8, for cross-browser browser/plugin intercommunication. (I wrote a comment there, then saw that he requires a Blogger.com password, and so I had to trash the comment.) It sounds like he wants to send 1.2 megabytes of data, first from server to browser, then from browser to plugin. Or it might be 1.2M from server to plugin to browser. He found that such large clientside transfers were slow, and got a speed improvement from chunking the transfers. All this work has browser dependencies as well as plugin dependencies, and I can't tell whether his task performs the same across the browsers which now offer this update to the old LiveConnect message-passing mechanism. The spec doesn't seem to offer guidance on the size of the messages it passes. The various implementations of this spec may be optimized for such massive local data transfers, may not... seems like some too-bounded docs met some unbounded expectations... wouldn't usually be worth a comment here, but I've got an emotional response to lines like "Flash 8's broken ExternalInterface" and "whoever coded ExternalInterface should be fired". I'd be hesitant to send 1.2 megabytes of anything to anything in a browser, myself, much less start to transfer it around locally after that. Wish I knew what he was actually trying to accomplish, would be easier to make progress that way.

Posted by John Dowdell at February 19, 2006 09:06 AM

Trackback Pings

TrackBack URL for this entry:
http://weblogs.macromedia.com/mtadmin/mt-tb.cgi/7094

Comments

I'm quite disappointed with your response. I agree that there was an emotional side to the article - but you are also ignoring very specific critique, for example:

- use of eval when not necessary
- incorrect encoding/decoding of characters
- O(n2) performance that could have been O(n)

If Brad is correct in these statements (and I don't know whether or not he is), then that should be a major concern and should be addressed properly.

As to 1.2M - if Brad is correct in what he says, then it's no excuse to say that careless implementation won't be noticed simply because people will mostly be dealing with small datasets.

- Nils.

Posted by: Nils at February 19, 2006 10:37 AM

I'm not judging/excusing so much as saying I'm trying to confirm what it is that we're talking about.

If the core question is "What's the efficiency of passing 1.2M of data between Flash Player and the range of browsers in which it may find itself invoked?" then I don't know... I passed along some preliminary context for such a discussion, but am still not sure that's the core question within the essay.

Posted by: John Dowdell at February 19, 2006 12:46 PM

JD - I was a bit dubious about his comments, but if he's correct then it is a serious problem.. there are times when we're forced to get data into a SWF in less than ideal situations.

Posted by: mike lyda at February 19, 2006 01:06 PM

There was a pretty good discussion about this stuff on the dojo mailing list last month:

http://dojotoolkit.org/pipermail/dojo-interest/2006-January/002816.html

Posted by: Geoff at February 19, 2006 01:35 PM

Hi folks.

I've found that ExternalInterface has two serious issues:

1) It begins to slow to a crawl at around 10K of data, and then slows down O(n^2) after that, locking the browser up as it tries to push data over.
2) There are serious bugs and errors in its serialization and deserialization routines, so that if there is a newline in the data from either side, for example, your data disappears.

My post was emotional because I care about these things, and am disappointed in how badly ExternalInterface was implemented. I agree that expecting to be able to send 1.2 megabytes is not realistic, but expecting to be able to send 20K with a newline character is.

I also used a bit of hyperbole ("should be fired") in the post to catch the Macromedia folks attention, so hopefully they fix these bugs ;)

Thanks for the comments and feedback.

Best,
Brad

Posted by: Brad Neuberg at February 19, 2006 11:02 PM

1.2M of data could be a raw bitmap image uncompressed.

With AS3 it is possible to implement a JPEG or PNG compression but not in Flash 8. People were trying to deal with this problem in dealing with bitmap since flash player 8 was out. So sending 1.2MB by ExternalInterface to the browser that will give these raw data to another routine to do the compression and send it to the server or give it back to the swf is not irrealistic.

So yes sending 1.2MB in one shot is not so uncommon.

Posted by: Bazard at February 20, 2006 03:45 AM

Thanks for repeating your conclusions, Brad, but I'm still trying to confirm the context.

Am I correct that you're trying to pass more than a megabyte through the new cross-browser NPAPI protocol? If so, I'm still trying to imagine a scenario where you'd not only download such data once, but then would need to pass it between two local clientside engines? I'm not saying such a case couldn't exist, just that I'd need to understand it before I could lobby for it myself, thanks.

Posted by: John Dowdell at February 20, 2006 01:08 PM

Hi John, I feel like the 1.2 megabyte issue is a red herring; the issue is that things go bad at more like 10K. In addition, even if I'm just sending the following simple sentence:

"Hello World (new line character) Goodbye world"

ExternalInterface will corrupt the data (it appears as a blank string on the other side). If I include _any_ character in _any_ length of data, things go bad. So if on the Flash side I do the following:

ExternalInterface.addCallback("helloworld", this, helloworld);

And in JavaScript do the following:

var plugin = document.getElementById("flashPlugin");
plugin.helloworld("This is an XML tag: ");

Things will again get corrupted (the helloworld() method on the Flash side will receive a blank string).

My ultimate goal has been to expose Flash's SharedObjects to JavaScript for persistent long term storage. This can be used to save small amounts of text, up to medium sized amounts, such as an RSS feed or a digital book, at around 700K, or large amounts of data, at several megabytes. Using the old Flash 6 plugin methods, such as SetVariable and TCallLabel, I have been able to send both small amounts and large amounts of data both very fast and reliably. However, working with the old Flash methods, including the fscommand callbacks, is ugly and does not work on Safari, so when ExternalInterface came out I thought it would be able to replace these old hacks, but it does not.

By the way, having persistent client side storage is _very_ useful. I've already prototyped things for clients, such as an RSS reader, that is caching hundreds of K of RSS feeds. I've played with designs for web based word processors that have such things as well.

And here is the even more important reason: using work from Julien Couvreur, who has found a clever way to force browsers to cache HTTP user interfaces even when offline, we can use this offline cache to achieve offline web applications, which store and pull their data from the client side cache, but which then sync back with the server when they go online.

Posted by: Brad Neuberg at February 20, 2006 06:12 PM

I should also mention again the Flash ExternalInterface performance issues; starting at 10K, which is _much_ much smaller than 1.2 megabytes, performance begins to degrade _exponentially_ with the size of the data; this means that at just 20 or 30K, easily the size of a small amount of text in a textarea that we are sending over, performance _completely_ falls over.

It looks like you work at Adobe/Macromedia; please please fix this bug.

Posted by: Brad Neuberg at February 20, 2006 06:14 PM

Ah! So you're seeking to normalize browser-cookie storage via Flash Player... that context is very useful, thanks.

... hmm... because most browser cookies are size-limited, you're seeking to store very-large data that the browser may originally request... got it... that context helps a lot, thanks. (I'm assuming you're aware that the default limit for Flash's local storage is 100K.)

That said, I'm still not sure whether the cross-browser NPRuntime spec mandates any efficiencies for very-large files... it's oriented around message-sending rather than passing large blobs... you can confirm this here:
http://www.mozilla.org/projects/plugins/npruntime.html

(There *was* a newline issue with the NPRuntime communication in Flash Player... I don't have the link at the handy at the moment, but it came up in research searches I did while first reading your post, should be easy to find.)

Summary: You're out-of-scope... might work, might not, and be sure to check how the various supporting browsers behave. If you'd like to request any change in the Flash Player, then you can get this archived directly with the team at macromedia.com/go/wish .

Posted by: John Dowdell at February 20, 2006 09:22 PM

John, sending 10 to 100K is definently not out of scope, and the current ExternalInterface can't not handle these data sizes. In addition, ExternalInterface uses an XML serialization mechanism, but the person who created it forgot to put CDATA sections around the data that is sent around, which means using any XML characters in your data breaks things.

I also know about the 100K limit; afterwards Flash gives the user a storage dialogue. I detect this and make Flash visible, centered on the screen. See the AMASS project for details: http://codinginparadise.org/projects/storage/README.html.

Thanks for the dialogue!

Posted by: Brad Neuberg at February 21, 2006 10:18 AM