Showing posts with label flash. Show all posts
Showing posts with label flash. Show all posts

Sunday, May 02, 2010

Apple, Flash, and The Truth

I'm sure by now you've read "Steve Jobs"'s Thoughts on Flash. Did it convince you? Do you think it was truthful? Not me. Sure it has some valid points, especially about Flash being buggy on OSX. As someone who has developed Flash applications using a Mac, I am especially aware of this bugginess, and part of me can't help but get a perverse sense of satisfaction that this bugginess is now coming back to haunt Adobe. However, this doesn't change the fact that Jobs's epistle is far from the truth. It is corporate slander, designed to make Adobe look as bad as possible. Why? So that when devices from competitor's ship with full support for Flash, this technological advantage can be discredited in the eyes of consumers. In other words, this well thought out post by Apple is not some intellectual/technical analysis, it is just marketing designed to boost Apple's profits.

The most dishonest thing about the post is what Apple says is "the most important reason" to ban Flash from their devices: that it will result in sub-standard apps and hurt their iPhone/iPad OS platform. This is complete bullshit. It's not like developers would suddenly only be able to create iPhone apps using Flash. It's not like they could no longer use all of the tools they use today. The difference is that they would have a choice. They could choose to use Flash. Or they could choose to use Objective-C/Cocoa/XCode.

But don't forget, that not only would developers have a choice, but so would consumers. If for some strange reason, some developers started choosing to use Flash,  it's not like consumers would be forced to buy those Flash-authored apps. No, they could still choose other, traditional apps. In fact, if, as Apple claims, Flash-authored apps would be of such low quality, then one would expect that few consumers would choose to purchase those apps.

So if Apple allowed developers to use whatever tools and technology they wanted to use, to create apps for the iPhone and iPad, what might happen? Well if Apple's claims are right, then there would be bad apps that nobody would buy (aren't there already a lot of such apps on the App Store?). Consumers aren't idiots, and they won't buy crappy apps when there will be better alternatives. So those Flash-authored apps will lose money. Developers aren't idiots, and they won't keep using technology that produces software that nobody wants. So they would abandon Flash and go back to Cocoa. So Apple's "concerns" would be unwarranted.

Or perhaps what would happen is that some developers would produce good apps using Flash that consumers bought for their iPhones. Certainly developers would continue to use Flash. However, in this scenario, Apple's "concerns" are proven to be false -- Flash produces some good apps. But wait, what about Flash holding back innovation on the platform? Apple would still be free to add new features to their OS, and make them available to developers through new APIs in the iPhone SDK. Who knows how long it would take Adobe to expose those features through the Flash authoring tools, but who cares? If those features greatly improve apps, and they aren't available in Flash authoring, then what happens? The power of choice wins again. Developers can still choose to use Cocoa, tap into these innovations, and user's can choose to purchase the apps that take advantage of these innovations. If these features are so great, one might expect that Adobe would try to bring them to Flash authoring as quickly as possible. Either way, the notion that the Flash platform would be held back makes no sense.

So Apple's self-described most important point is so false that it is laughable. Some of their other parts are equally false. For example, the notion of touch and Flash. Yes, many things in Flash are designed for users interacting with a mouse, not a finger. Such things don't work well on touch devices. However, this is not just true for Flash. It is equally true for HTML and JavaScript. If you've done a lot of surfing on your iPhone or iPad, you have surely experienced the "rollover" issues described in Apple's post. Want more examples? Check out this clever little video on HTML 5 and the iPad:


So why all the bullshit? As I said earlier, the reason for the post is to discredit any competitor that provides Flash support on their devices. First and foremost on that list is Android, which will support Flash in Android OS 2.2. That doesn't explain why Apple doesn't want to allow developers to use Flash to develop for the iPhone? The answer to that is simple. They want complete control of their platform. If you want to make money off of the iPhone, you have to be in bed with Apple. They saw how the web has hurt Microsoft, and they will not let this happen on the iPhone or iPad.

Now wait a minute, isn't Apple investing heavily in the web, namely HTML 5? Doesn't that demonstrate that they are willing to give up control of their platform? Yes, and no. Yes, Apple has invested into WebKit, a technology that in various forms implements a decent chunk of the HTML 5 standard. But you see, the key word here is "standard." This is how Apple fools you into thinking that they are providing an "open" alternative to their proprietary system.

It's easy to get fooled into thinking that any company that implements and open standard is innovative, but just the opposite is true. We think standards=innovation for browsers because of Microsoft IE 6. That browser dominated the world for a long while being completely stagnant. It was both non-standard and non-innovative, but this is an exceptional. It is rare that such technology can flourish. It took the unique nature of Windows, IE, and Microsoft's legal troubles to produce this situation.

Adopting a standard just means that you either change an existing feature of your technology to comply with the standard, or you copy a feature from others in the space. It is anti-innovation. When it comes to web standards, they are introduced post-hoc. XMLHttpRequest, the key technology behind Ajax, was proprietary Microsoft technology for many years before it became a standard. Many of the features of HTML 5 were introduced by various plugin technologies like Flash or Google Gears before they became part of the HTML 5 spec. You cannot innovate while waiting for some super slow moving corporate committee to vote on a new standard.

Going back to the iPhone/iPad, Apple is saying: pick either Cocoa and go through the App Store, or stick to the web, but only the "open standards" part of the web. They have given you a choice, but only the weakest, most impotent choice possible. You see this is where the other part of their Flash ban comes into affect. Not only have they recently banned compiling a Flash authored application into a native iPhone application, they have always banned Flash running in the browser. Why? Because with browser plugin technologies like Flash, Silverlight, and yes even Java, you can create user experience's on par with desktop applications. If they allowed Flash in the browser on the iPhone, then developers could create web applications that might rival the native iPhone applications. And we wouldn't want that, now would we? So Apple give you a single alternative to using Cocoa/XCode/AppStore, and then they horribly cripple it, by removing the most innovative parts and tying a design-by-committee-technology weight around its neck. Apple's endorsement of HTML 5 is one of the greatest marketing ruses ever. They stifle innovation, limit choice, and line their own pockets while getting everyone to believe they are being developer friendly and innovative.

After all of the above, you might think that I am very anti-Apple, anti-iPhone, anti-iPad. I'm not at all. I am anti-bullshit though. I don't like being lied to and treated like a lemming. Apple has every right to keep Flash off of their devices. It's their OS after all. They have very right to ban apps that were authored with Flash from their AppStore. It's their AppStore after all. Just don't lie to me about this stuff. Don't say it's better for developers or better for consumers, when it's actually worse for both. Just tell the truth: it's just better for Apple.

Wednesday, February 03, 2010

The Flash Haters

The iPad announcement had lots of subtleties to it. One of them was that the iPad browser, presumably Safari, does not include a Flash plugin. This has lead to a lot of people from Adobe getting upset. What has amazed me through all of this, is that there is even more hate for Flash than ever before. As somebody who has done a fair amount of Flash development in my career, this has really struck me as odd. Why all of the hate for Flash?

In some ways, I can actually understand why Apple would hate Flash. The Flash plugin on OSX is nowhere near as good as the Flash plugin on Windows. Now Adobe will counter they spend a disproportionate amount of money on Flash for OSX, i.e. they spend more money per OSX user than they do per Windows user. So what? There are a lot of other technologies out there that work equally well on both Windows and OSX. Just focussing on web technologies, Firefox and Chrome on the Mac are very comparable to their Windows versions. So is the Java plugin. Some other products, like Opera and Skype, tend to trail in terms of features on OSX, but not in terms of quality. If these other companies can do this, why can't Adobe? It's obviously either lack of ability or prioritization. My guess is the latter, and hence you must expect hate from Mac users. And from Apple. So it should not be so surprising that Flash is left off the iPad, iPhone, etc. If Adobe really wanted to get Flash on those devices, an obvious first step would be to make Flash on OSX as good as Flash on Windows. That is something that Adobe can do all by themselves. Instead it seems like they would rather publicly bemoan their exclusion on the iPad. Now is there a guarantee that if they improved Flash on OSX, Apple would care? No, of course not. However, there is no way they will get on those devices without this first step, IMO.

Ok, so Mac user hate for Flash is understandable. Along the same lines, I would guess that Linux user hate is also understandable. That is, if there were actually any Linux users out there. I digress. I see a lot of hate from developers. What about that? That one is not so easy for me to understand. As a web developer, Flash has been opening doorways for me for a long time. Need to cache 30 KB of data on the client? For a long time this was impossible unless you used Flash (or maybe Java.) Need to make a cross-domain call? That is still generally impossible from the browser, unless you use Flash. Need to show 2D/3D graphs and visualizations? Again, this is still generally impossible, except through Flash. Oh and video... The only way to show a video that can be played on all of the top five web browsers (IE8, IE7, Firefox 3.5, IE6, Firefox 3.0) is to use Flash.

But, but, but, what about HTML 5? Many people think it will kill/replace/maim Flash. Apparently this list includes a certain Steve Jobs. As I have said before, I hate web standards. I mean, I love them, too. But I hate them mostly. Standards are the opposite of innovation, and perhaps its enemy. However, they are the engineer's best friend. Flash has provided a lot of innovation, that HTML 5 will simply copy and standardize. That is the best possible function of standards. However, the story is not so simple. Some things, like local storage,  are already supported by IE8, Firefox 3.5, and Safari 4. This is like Flash's SharedObjects, though slightly less powerful (but good enough.) Not everything is so rosy; canvas and video playback immediately come to mind. Canvas is particularly a hot topic. You can do some amazing things with it, but it requires payment in blood. I cannot imagine what it would be like to program Farmville in JavaScript using Canvas. Maybe somebody will come up with tools for that. In fact, I would be surprised if Adobe did not do this. Of course, we still need to hope and pray that canvas is supported in IE9...

So back to the original point. Why do developers hate Flash? It certainly enables them to do more stuff in web applications. Even if that list of extra features is being shrunk by the HTML 5 monster, it's still there. So shouldn't they love it? Well, you would think so, but they don't. Here are some guesses as to why:

1. Expensive tools -- Most of the tools used by a lot of developers are free. The Flash authoring tools are far from it. That can be annoying. You have to throw down a lot of money just learn something. That's not cool.
2. Bad tools -- At least from a developer perspective. The Flash authoring tools have historically been aimed at designers. That changed with Flex Builder/Flash Builder, but the damage was done. Also, those tools were aimed more at application development, which largely seemed like a waste of Flash.
3. Back to the Mac  -- A lot of developers use Macs, and we all know about Flash on OSX...
4. Accessibility -- Unfortunately this doesn't mean much to most developers. But it should. I must admit, that a year ago I probably wouldn't have listed this. However, as I have learned more, I have learned how Flash is such a huge problem for accessibility. This is actually one area where HTML 5 really shines, with the inclusion of the ARIA standards.
5. Design envy -- This kind of goes back to #2. Flash has had all the awesome capabilities for years, but they have largely gone untapped in web applications. Maybe by playing to designers all of those years, Flash has earned enemies. Imagine a developer being asked to scope some radical web feature. They give a typically large scope for it. His manager turns around and gets a designer, a freakin' designer, to do it in half the time.

What have I missed? Why do web developers hate Flash so much?

Wednesday, April 22, 2009

ActionScript Quickie: Check for Required Params

You ever need to test that a bunch of variables are not null/empty/true? Here is a quick and dirty way to do it in ActionScript 3.0:

private function validArgs(...args):Boolean{
return args.every(function(arg:Object, ...crap):Boolean {
return arg ? true : false; });
}

Usage:

var firstName:String = ...
var lastName:String = ...
var iq:int = ...
var friends:Array = ...
validArgs(firstName, lastName, iq > 100, friends.length);

Wednesday, March 25, 2009

Safari Flash Fail

This happens to me a lot:

Take a look at the stack trace that gets sent to Apple:

So I think this is being caused because I set the storage allowed by the Flash player to 0 KB. The default is 100 KB. Why do I have it set at 0 KB? It's not because I am some privacy fanatic, just the opposite in fact. It was because I was debugging some PayPal code a few months back that required that Flash local storage be unavailable. Most sites then ask to set it back to the default 100 KB. However, if the SWF in question is too small to show the settings dialog, then it can't show the dialog to ask the user to set the amount of local storage for the site. You can right-click any SWF to bring this setting up, well any SWF that is biggest enough to display the settings manager. This is on a per site basis, but you can set things globally as well. Dealing with the error that is thrown when setting data fails is what I helped PayPal with. Obviously there are a lot of sites that do not deal with this error, and that seems to bubble up in Safari and cause it to crash.

Sunday, February 08, 2009

Added Twitter Social Graph APIs

Twitter recently created social graph APIs. You can get the friends or followers of a given user. This information was available in other ways previously, but the new social graph APIs are very convenient they return an array of numeric IDs. So if you want to do things like visualizing the social graph of people or use this to suggest friends, etc. now you've got an easier way to do it. Of course a great way to visualize such data is in Flash. So I added these APIs to TwitterScript. When the TwitterEvent returns, its data property will be the array of numeric IDs.

Wednesday, January 28, 2009

How Google Makes The Net Suck

Some people like to compare developers to artists. When it comes to web development, some people say there's always a man behind the curtain. Whether you agree or not, there are definitely certain freedoms that web developers enjoy. As a web developer, what are the greatest limitations and obstacles in your way? Once it may have been browser quirks. Now maybe it's all those annoying users who still use IE6. However, I think the greatest obstacle to progress is Google.

Now Google would have you believe just the opposite. I do not think they are disingenuous. In a large organization, it's all too easy for different groups to have different motivations. But ask yourself this, how much money does Google from Chrome? What does Google make money from? That's easy: advertising on search. And that is what is hold us all back.

If you have endured my purple prose to this point, I will finally cut to the chase. One of the most important aspects of any web page is how its PageRank. If your web page is all about deep sea diving, where does it surface when somebody searches Google for deep sea diving? The black art of making your page get a higher PageRank has given birth to an entire cottage industry known as Search Engine Optimization (SEO.)

As a developer I have never given much thought to SEO. I always thought that SEO was about the content of the page, and web developers are not responsible for the content. We are responsible for retrieving/generating that content from all kinds of sources, as well as creating applications that are easy and intuitive for the user to interact with a meaningful way. But, if we go back to the deep sea diving example, we're not responsible for providing information about deep sea diving. Heck you are lucky if most developers even known how to swim, but I digress.

But I was wrong. SEO is not just about content. It is about structure. If you want a good PageRank, then quality content about deep sea diving will lead to other people linking to your page and that will increase your PageRank. But there are much more instantly gratifying things you can do. For example, your page should a title and it better contain the term deep sea diving. No big deal, right? The title is really just part of the template outside of the main contents of the page. Its value has little effect on anything, besides PageRank that is. However, it gets worse.

To maximize your PageRank, then immediately after your page's body tag you should have an H1 tag whose contents should contain the term deep sea diving. Oh maybe you put the phrase on the page, but you put it in a div that styled quite nicely? Not good enough. It needs to be in an H1 tag. Maybe you used some JavaScript to create the H1 tag? That is no good at all. Why? Because The All-Mighty Googlebot does not understand how the page looks to a user. It only understand basic HTML constructs. That's right, it's time to party like it's 1999.

Oh, maybe your organization hired an artist who created a killer deep sea diving logo and you load it on to the page as an image? Not good enough. If you put deep sea diving as the alt text, that will win you some bonus points from the Googlebot, but it is still dwarfed by the rewards you could receive by busting out the H1. Nothing compares to the mighty H1 tag. And don't just put that H1 tag anywhere on the page. Heck you might even get penalized for having more than one! Nope only one, and it better appear (in the HTML source code) as close to the body tag as possible.

Ok, so maybe you give in and put the catch phrase in an H1 tag. That wasn't too bad, right? Now back to your regularly scheduled hacking? Not so fast. Do you have some hierarchical information on the page? Sections, headings, menus, etc? How are you going to do those? Again you better not even think about using things like JavaScript to create them dynamically. Nope, they have got to be static on the page. Back to divs, spans (maybe a table or two), along with some oh-so-clever CSS? Forget about it. Let me introduce you to H1's other friends: H2, H3, H4, H5, H6. That's right, if you want that damn Googlebot to "understand" the hierarchy of concepts on your page, then you better put away your divs and spans.

Maybe you think that's going overboard, but it's not. Do you have a section on your deep sea diving page called "Gear" ? Then if you want to show up on a search for deep sea diving gear, you better have the term Gear wrapped in an H2 or an H3 tag.

What about RIA technologies? Again, if you dynamically create things with JavaScript, it will get picked up, but it is non-optimal. You have to do things the way that the Googlebot wants it done to get best results. What about Flash or Silverlight or JavaFX? Flash will get you screwed on about the same level as JavaScript. Silverlight or Java might as well be black holes. Whatever is in there, is never getting out.

There are tricks you can employ like progressive enhancement. There you do things the way that the Googlebot wants them, then dynamically obliterate that garbage and replace it with rich content that your users actually want. This can backfire. If the Googlebot figures out that you are tricking it, then it will banish you to purgatory.

What if you just make a great web application that users will love and don't bother to worry about the Googlebot? That's fine of course, it just means that people will not find your application by searching for it. Is your business model and marketing efforts robust enough to not need SEO? Yeah, I didn't think so.

So now do you understand? The Googlebot ties your hands, or at the very least makes you jump through all kinds of hoops. There are all these great technologies you could use to make your site as interactive as any desktop application, but The Googlebot does not like this. You've got to play his game whether you like it or not.

Tuesday, January 06, 2009

JavaFX Performance

Recently I did a comparison of JavaFX performance vs. Scala. I did this mostly for kicks, and because some people thought that Mr. JavaFX was picking on other, non-Java languages that run on the VM. James Iry duly pointed out that JavaFX should be benchmarked against the likes of Ruby, Groovy, or Scala. It is meant to be a client-side technology, so it should go up against client-side technologies. So I re-did the little performance comparison to match JavaFX against JavaScript, ActionScript (Flash), and C# (Silverlight).

A comparison like this really becomes a comparison of Virtual Machines. For JavaScript there are a lot of choices. I decided to go with some that are supposed to be fast: Google Chrome, Firefox 3.1 (beta 2), and Safari 4 (developer preview.) Because I wanted Chrome involved, I had to go Windows. So I ran everything under Windows XP, running under Parallels on my MacBook. Here is the pretty graph:

I was just a little surprised by these results. JavaFX is indeed the fastest, but just barely. I was somewhat shocked to see Chrome's V8 JS engine right behind. In fact the difference is negligible for small iterations (shown above.) At larger iterations, JavaFX maintained 20-40% margin. As you can see from the graph, Flash and Silverlight were kneck-and-kneck as well, but was always about 7-10x slower than Chrome/JavaFX. Safari and Firefox were very underwhelming.

Of course this was just a micro-benchmark. The code just does a series of recursive calls. So what were are really measuring is the ability of the VMs to unwind these recursive calls. It is not suprising that HotSpot handles this easily. Actually, the same code in straight Java is much faster than the JavaFX version. It is surprising to see how well V8 handles this.

Now does the ability to unwind recursion translate into performance that a web application user would notice? Maybe. It certainly points to JavaFX's or V8's ability to make optimizations to application code. It is probably a more meaningful test than some raw number crunching.

Wednesday, November 19, 2008

Gumbo and Data

This week I was at Adobe MAX. While there I picked up a DVD with a preview of Flex Builder 4 and Flash Catalyst (Thermo.) One thing of particular interest to me was the new data-centric abilities of Flex Builder. Let's take a look at them.

Recently I finished an article for IBM on using Grails and Flex together. In the article I created a Digg-clone and used things like Flex DataGrid and Forms to browse and submit stories. I decided to see how well the new Flex Builder tools could create the same code for me. So I took the existing service and imported into Flex Builder

The screenshots give you an idea of the process. As you can see from the final screenshot, there is a lot of code generated! A service proxy and return types are both generated. Actually for each there is a base class with all of the guts and empty class built for you to customize. There is a modeling class that contains metadata about the return type. The base service class uses a new Flex class HTTPMultiService. It is a lot of code, a lot more than I wrote. Most of it seems reasonable though.

You can also generate a data grid for displaying the data. This worked perfectly for me. Gumbo also promises that in the future you will be able to generate other components, in particular a Form.

Wednesday, October 22, 2008

AjaxWorld 2008

AjaxWorld was this week, and it was interesting. I think the down economy is having an affect on everyone, but there were still a lot of interesting things to learn about. On Monday, I did a talk on a favorite topic of mine, networked applications. The talk was a lot of fun, hopefully the audience would agree with that assessment. Overall though, I would say there were a couple of major themes at AjaxWorld this year.

1.) Comet. There were a lot of talks about some form of data push from the server to the browser. Kevin Nilson did a nice job of differentiating Ajax (infinite loop of XHR polls) vs. Comet (long poll.) The folks at ICEFaces have built some nice abstractions on top of Comet. There was also a lot of interest around WebSockets, especially the work by the folks at Kaazing. A duplexed socket connection to the server sounds great on paper. I think there will be some very interesting technologies that grow around that.

2.) Don't make me learn JavaScript! There seemed to be a lot of folks advocating the "only know one language" approach to the web. In most cases that language was NOT JavaScript (even though the Jaxer guys say it can be.) Vendors liked Oracle and ICEFaces preached abstractions that shielded the developer from JavaScript. Of course the GWT folks say do everything in Java. Microsoft says use Silverlight so you can do everything in C#. Of course one of the best sessions was by Doug Crockford who told everyone to man up and learn JavaScript. I tend to agree with Crockford, even though I prefer ActionScript...

Monday, October 13, 2008

ActionScript Vector Performance

Flash Player 10 is coming out this month. This weekend I went to Adobe's FlashCamp. It was a lot of fun by the way, and a big thank you must go to Dom and the folks at Adobe for a great event. Adobe really treats developers well. Anyways, there are a lot of great new features in Flash Player 10. Other folks will talk about 3-d and text engines and Pixel Bender, etc. but me? I'm excited about Vectors.

If you are like me, then the first time you heard about the new Vector class in ActionScript, you thought it might have something to do with graphics and what not. However, I was overjoyed to learn that it was like the Vector from C++ and Java, i.e. a list-style collection. Like the Vector from the STL and in Java 1.5+, it is parameterized. Even better, you can specify a fixed length for it. In other words, you can say that is a collection that only allows one type of object and that there is fixed number of objects in it. This leads to excellent performance optimizations that are possible, and indeed Adobe has taken advantage of this. Of course I had to test this out for myself.

One of the other nice things about FlashCamp was that they gave us a new build of Flex Builder. This one has support for the new language features supported in Flash 10. To enable the new features, you just change the Flash Player version that you target and voila! I took some benchmark code that I had used for Flash/JS comparisons. Here is the original code:

private function testArray():Number{
var startTime:Date = new Date();
var arrStr:String = null;
var arr:Array = new Array();
var i:int=0;
for (i=0;i<=94;i++){
arr.push(i);
}
for (i=0;i<=arr.length;i++){
arr.push(arr.pop());
arr.sort().reverse();
arr.push(arr.splice(0,1));
}
arrStr = arr.join();
return (new Date()).getTime() - startTime.getTime(); }

And here is the new version that uses a Vector instead of an Array.

private function testVector():Number{
var startTime:Date = new Date();
var v:Vector.<int> = new Vector.<int>();
var arrStr:String = null;
var i:int = 0;
for (i=0;i<=94;i++){
v.push(i);
}
for (i=0;i<=v.length;i++){
v.push(v.pop());
v.sort(comp).reverse();
v.push(v.splice(0,1));
}
arrStr = v.join();
return (new Date()).getTime() - startTime.getTime(); }

Do you like the Vector syntax?

Anyways, back to the results. The Array averaged around 90 ms on my MacBook. The Vector code averaged around 20 ms on my MacBook. 4.5x? Very nice.

One thing I immediately wondered about Vector was if the Flash compiler erased the type. At first glance, there is no reason to do this. It is a different type, so there is no backwards compatibility issue. It does not extend Array, but it is a dynamic class. The documentation states that the push() method does not do type-checking at compile time, but does do this at runtime. This seemed weird, but it would imply that type information is not erased, since it can be checked against at runtime. However, in my testing I could use push() to push any object into any Vector, and had no compile time or runtime errors.

Sunday, October 05, 2008

October Talks

October is going to be a busy month for me. Next weekend I will be at Adobe's FlashCamp. I will be there Friday night and Saturday, and I may do a short session on TwitterScript, the ActionScript API that I maintain. In particular I want to talk about some of the authentication wrinkles present in TwitterScript and its forked brothers.

On October 20, I am speaking at AjaxWorld. I am going to be talking about a subject near and dear to me, Networked Applications. I'll be talking about why you shouldn't waste the power of your servers building HTML strings but why you should instead start using things like jQuery, GWT, or Flex to cash in on the power of your user's computers.

The week after that, I will be on the east coast speaking at EclipseWorld. On Day One, I am doing a day long, introductory workshop on Ruby on Rails. Of course I'll also talk about how Eclipse can help you out. On Day Two, I am doing two talks. One ties in to the previous day's workshop and is about RadRails. The other session is on ... iPhone development. Kind of a strange topic for me. Chris Williams from Aptana was supposed to do both sessions, but couldn't make it. So Aptana asked me to fill in for him. Hopefully they won't wind up regretting that decision!

Tuesday, September 23, 2008

No SharedObjects Allowed

Client side storage by the Flash player (SharedObjects) has several advantages over traditional client side storage, a.k.a. HTTP cookies. From a security standpoint, it is better because the data is never sent over the wire. However the main advantage to most people is that it is bigger, and when it comes to managing data on the client, size definitely matters.

By default you get 100 KB instead of the 4 KB you get with cookies. If your application tries to store 101KB, it won't fail. Instead the user will be prompted to increase the allocated space by a factor of 10, i.e. from 100 KB to 1 MB. Of course you probably don't want the user to ever see this screen. One of the other advantages of SharedObjects is that people don't delete them. People blow away their cookies all too often, but most people would have no idea how to do the same with SharedObjects. The only you would find out would be if you saw the Flash player settings screen, i.e. the interface that appears when a Flash application tries to go over the 100 KB default limit.

So stick to under 100 KB and all is good, right? Not so fast. The settings interface requires that your Flash app is at last 136x213. If it is smaller than that, then what happens? First let's explain what happens when it is big enough to show the settings interface. When you flush data to local storage, a string is returned with a status. Here is typical code for this.


var testSo:SharedObject = SharedObject.getLocal("test", "/", false);
testSo.data.testValue = "test";
var soStatus:String = testSo.flush();
if (soStatus != null){
switch (soStatus){
case SharedObjectFlushStatus.PENDING:
testSo.addEventListener(NetStatusEvent.NET_STATUS, someHandler);
break;
case SharedObjectFlushStatus.FLUSHED:
break;
}
}

There are two possible return values, either "pending" or "flushed." There is no fail. So if you were flushing 101 KB, then you would get a pending return value. Now all you can do is what for an event, or more precisely a NetStatusEvent. This will tell you if the user allowed you to increase the size or not. If not then the NetStatusEvent will come back with a failure code.

If there is not enough space to display the settings interface, then you would think that you would just get an automatic failure, but you don't. Instead you get a "pending" from the return of flush. It's not really pending, since the user can't actually choose to allow it to succeed. It can only fail. But the player pretends this is not the case and that the user denied you request. So you need to still listen for the NetStatusEvent. If you don't catch that event, then it will cause the Flash player to throw an error to the user, and of course you do not want that. Here is a picture of that.


Thursday, September 04, 2008

JavaScript Faster than Flash

This is the last benchmark for awhile. Well, at least for today. I converted the JS benchmarks to ActionScript and tested them. The result were surprising, as JavaScript in Safari 4 and Firefox 3.x edged out Flash:


A few notes. I could not convert all of the tests, as two of them (the DOM and Ajax tests) were predicated on browser specific code. I could have done 'equivalent' functionality in ActionScript, but it did not appropriate for comparison. Otherwise the code was translated as is ... for the most part. I did add static type information where possible. There were also a few APIs (on Date and Array) that had be tweaked slightly. I tested similar changes to the JavaScript. The only test where there was any effect was the Date test. The JavaScript used Date.parse, which does not exist in ActionScript. The Date constructor does the same thing. If I switched to using the Date constructor in JavaScript, it was just slightly slower.

It certainly seems that much of the performance advantage enjoyed by Flash upon arrival of Flash Player 9 has been erased. Flash had a strong advantage still in more mathematical calculations (dates, integer and floating point arithmetic) as well as string manipulation. It did very poorly with arrays and regular expressions. I would guess that as the JITs for JavaScript get better, the string advantages will disappear. Flash will probably maintain an advantage in more mathematical computations, especially given its vector graphics features. Hopefully advances in JavaScript will spurn Flash VM progress.

Notes
1.) Tested on both Flash 9 and 10 RC2 on both OSX and Windows. Negligible performance differences in any of the permutations.
2.) Also tested with Silverlight, but only on Windows. It was slower than everything except IE7. However, that was because it was terribly slow at regular expressions and error handling. It clearly had the best JIT as it was able to reduce some of the tests to 0 after a couple of executions.

Tuesday, September 02, 2008

Firefox 3.1: Bring on the JIT

Web developers everywhere are excited about Firefox 3.1. Part of that is because of CSS improvements, but the big reason is because of TraceMonkey. This a JavaScript engine with a JIT that uses trace trees, a pretty clever technique to turn interpreted JavaScript (read slow) into compiled native (read fast.) JIT is a big part of why VMs like the Java VM and the CLR are very fast, in general much faster than VMs that do not JIT like in Python, Ruby, or (until now) JavaScript. It is why JRuby is faster than Ruby. Thus the prospect of making JavaScript much faster is very exciting.

Recently I had done some micro-benchmarking of JavaScript performance vs. ActionScript/Flash performance. This concentrated on XML parsing only. Now the ActionScript VM is a JIT VM. In fact, Adobe donated it to Mozilla and it is known as Tamarin. It has been Mozilla's intention of using this for JavaScript in Firefox for awhile, as JavaScript is essentially a subset of ActionScript. TraceMonkey is based on Tamarin, but it adds the trace tree algorithm for picking what to JIT. The trace tree approach allows for smaller chunks of code to be JIT'd. For example if you had a large function, like say a single script that runs when the page loads, then with a traditional JIT you either JIT the whole function or not at all. Now what if that function has a loop that runs dozens of times, maybe populating a data table for example. With a trace JIT you can JIT just that one critical loop, but not the whole giant function. So it should be an improvement over Tamarin and thus ActionScript. Of course there is only one way to tell...

So I repeated the same XML parsing tests that I did for Firefox 3.0 and Safari 4 (beta). First, I had to enable JIT in Firefox. One of the links above describes how to do this (open about:config in FF 3.1, look for the jit.content option and set it to true.) I restarted FF 3.1 just to make sure this took effect. I then ran the tests. The results? Not much difference between FF 3.0 and 3.1b+JIT. FF 3.1b+JIT was about 4% faster, which is probably statistically negligible. It was still 6x slower than ActionScript and almost 3x slower than Safari 4.

So what went wrong? Not sure. Here is the code that gets executed in my test:

function load(){
var parser = new DOMParser();
var xml = {};
var start = 0;
var end = 0;
var msg = "";
var results = document.getElementById("result");
var li = document.createElement("li");
initReq();
req.open("GET", "LargeDataSet?size=50", true);
req.setRequestHeader("Connection", "close");
// use a closure for the response handler
req.onreadystatechange = function(){
if (req.readyState == 4 && req.status == 200){
msg = "XML Size=" + req.responseText.length;
start = (new Date()).getTime();
xml = parser.parseFromString(req.responseText, "text/xml");
end = (new Date()).getTime();
msg += " Parsing took: " + (end-start) + " ms";
li.appendChild(document.createTextNode(msg));
results.appendChild(li);
}
};
req.send(null);
}

Pretty simple code. I manually execute it 20 times. It would sure seem like it could be JIT'd. What gets timed is just the parser.parseFromString(...) call, where parser is a DOMParser. Maybe that object cannot be JIT'd? Maybe there is a bug with the JIT that will be resolved in the future? It does seem to suggest that TraceMonkey may not always be the slam dunk everyone expects.

I was surprised by the results. I thought that FF3.1 would be faster than FF3. I didn't think it would be faster than ActionScript in this case, but I thought that it might be close. In many other cases, I expect ActionScript to still be much faster than TraceMonkey. Why? Well there is one other ingredient in VMs like the JVM and CLR that make them fast: static typing. This allows the VM to make a lot of other optimizations that work in combination with JIT'ing. For example, knowing that a particular variable is a number or a string allows the VM to inline references to that variable. This can eliminate branches in logic (if-else statements, where maybe the else is not possible.) The JIT can then take place on the simplified, inlined code, and be about as fast as possible.

If you read about some of the techniques used in TraceMonkey, it tries to do a lot of the above via type inference. So in some cases TraceMonkey and the AVM2 (ActionScript VM) may be able to do the same level of optimizations. In fact, given its tracing approach, TraceMonkey may be able to do better. But I am guessing that there will be a lot of situations where AVM2 will be able to do more optimizations just because of the extra information it has at its disposal in the form of static typing.

Thursday, August 28, 2008

Search Twitter from Flash

I have updated the Twitter ActionScript API. I added support for search. You are probably aware that search is provided by Summize, who was acquired by Twitter. It is pretty obvious that the APIs have not yet been merged!

Twitter's API is all based on Rails ActiveResource ... which is awesome. It turns any resource (often a database table) into a RESTful service. REST is often associated with XML, but Rails (and thus Twitter) supports it as JSON (Twitter supports ATOM and RSS as well) too. For ActionScript, XML is great. Or I should say POX is great and that is what Rails serves up.

The Twitter Search API is different. It supports two formats: ATOM and JSON. No POX. I went with the ATOM format. For JSON, I would have used Adobe's corelib. It works well, but I didn't want to add the weight. Plus, JSON tends to parse much slower in AS3 than XML. That is because AS3 implements E4X. To get E4X to work with ATOM, you have to be mindful of namespaces. For example, here is the code I used to interate over the entries: for each (entryXml in xml.atom::entry). Here the xml variable is the parsed result from search.twitter.com and atom is a Namespace object. Not as pretty as just xml.entry, but oh well.

Sunday, August 24, 2008

Parsing XML on the Client: JavaScrpt vs. ActionScript

Developer: Wow the JavaScript interpreter on Firefox 3 is awesome, but the one on the new Safari is even better. It is a great time to be a JavaScript developer!

Me: It is still a lot slower than ActionScript.

Developer: Oh don't quote me old numbers, the new browsers are so much faster.

Me: Still slower than ActionScript.

Developer: Maybe slower at doing useless things like calculating prime numbers. Who would do that in a browser anyways? The new browsers are fast at doing realistic things.

Me: But still slower than ActionScript.

Developer: Show me some proof on something realistic, like parsing XML coming back from an Ajax call.

Me: [Whips together a servlet for producing huge chunks of XML and some JS and a SWF for calling it and doing a DOM parse.] Alright let's see the results of these tests...

Everything is O(N), as you would expect, and can verify by doing a linear regression of XML document size vs. parse time. Safari 4 is much faster than Firefox 3, the ratio of their slopes (FF3/S4) = 2.95. But they both lose badly to ActionScript 3 (running Flash Player 10, RC2), (FF3/AS3) = 6.36 and (S4/AS3) = 2.16. Maybe IE can do better, should we give it a try?

Developer: Now you are being a jerk.

Monday, June 09, 2008

Gears and Flash

Tonight I launched up Firefox 3, and it informed there was an update to Gears ready to install. I went for it, and sure enough Gears was now working with Firefox 3! I didn't find any official announcement about this, but I didn't let that stop me from finishing an idea I had last week: getting Gears and Flash to work together.

This was not too hard. It is just a matter of using ExternalInterface to create a bridge between the two worlds. I wrote a quick POC, using a simple DB table for storing name/value pairs. I think it would be fun to re-implement the flash.data package that is normally only available in AIR apps...

Here is the JavaScript code:
function dbCall(sql, args){

var db = google.gears.factory.create('beta.database');
var rs = null;
try{

db.open('database-test');
db.execute('create table if not exists little_table (key varchar(20), value varchar(100))');
rs = args ? db.execute(sql, args) : db.execute(sql);
data = [];
while (rs.isValidRow()){

row = {};
for (var i=0;i<rs.fieldCount();i++){

var name = rs.fieldName(i);
row[name] = rs.field(i);
}

data.push(row);
rs.next();
}
return data;
} finally {

rs.close();
}
}


Here is the ActionScript code:
import flash.external.ExternalInterface;


[Bindable]
private var rs:Array = [];

private function load():void{

rs = ExternalInterface.call('dbCall', 'select * from little_table');

}
private function save():void{
var key:String = keyIn.text;
var value:String = valueIn.text;
ExternalInterface.call('dbCall', 'insert into little_table values(?,?)', [key, value]);
keyIn.text = "";
valueIn.text = "";
load();

}
private function clearData():void{
ExternalInterface.call('dbCall', 'delete from little_table');
load();

}


And here is the MXML I used to test it out:
<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="load()">
<mx:DataGrid x="202" y="59" id="grid" dataProvider="{rs}">

<mx:columns>
<mx:DataGridColumn headerText="Key" dataField="key"/>
<mx:DataGridColumn headerText="Value" dataField="value"/>

</mx:columns>
</mx:DataGrid>
<mx:Label x="10" y="251" text="Key"/>

<mx:TextInput x="74" y="249" id="keyIn"/>
<mx:Label x="242" y="251" text="Value"/>

<mx:TextInput x="285" y="249" id="valueIn"/>
<mx:Button x="460" y="249" label="Save" click="save()"/>

<mx:Button x="243" y="298" label="Clear" click="clearData()"/>

</mx:Application>

Monday, April 21, 2008

Video Solution

Last week my oldest son, Michael, Jr. was in a musical production at his preschool. Of course we videotaped it so we could share it. This wasn't the first time I had shared video online, but this time really made me annoyed. I was really annoyed with the poor quality of sharing sites like YouTube. I tried Facebook's video sharing, and it wasn't much better. I decided it was time to roll my own. After some experimenting here is the stack of tools and service I came up with.

Video Importing/Editing: iMovie. This is what I was already using. iMovie is famously easy to use. The importing is easy, the editing is easy. The default export is .m4v files, which are H.264 files designed to work on iPods. This is important.

Video Playing: Flash. I wrote my own video player using Flex. The Flash player has built-in support for H264 video. Thus the videos I export out of iMovie play naturally in the Flash player. They just need some Flash code to load and control the video stream. I wrote this myself as it was pretty straightforward. I created an external XML file as a metadata repository. This tells my player what videos are available and information about each video, like its size. I hosted the custom built player and metadata files on Google Page Creator.

Video Storage: Amazon S3. This was the most difficult part. S3 is relatively cheap. It is NOT easy to use, contrary to what others might say. I was shocked to discover that there is no interface (web or desktop) for uploading and managing files stored on S3. I wound up using S3Fox. It seems like a nice interface, but buggy. Amazon really should offer administrative tools.

Next Steps: Ideally I would build a plugin for iMovie that would upload the video to S3 and write the metadata about the movie to my Google Pages. I am thinking of doing an AIR app for this first, and then maybe go Cocoa. I must also monitor my usage to make sure that S3 is cheaper than other alternatives like Box.net.

Wednesday, April 16, 2008

eBay Wins MySQL Award

Yesterday eBay won an award at the O'Reilly MySQL conference. Congratulations to the Chris Kasten's team. Chris also did a presentation today at the MySQL conference. The caching layer his team created allows us to store "session" data on the server. This data can actually be persisted across sessions, depending on the use case, so it is really a little better than your typical HTTPSessions. Plus it actually scales :-)

The MySQL cache compliments HTTP cookies. We also use Flash for local storage as another alternative to the tiny world of HTTP cookies. Flash has a lot of advantages. The most obvious is the 100K default limit as opposed to the 4K limit of HTTP cookies. Flash "cookies" are not sent to the server, making them much more secure. One of the fun things I did recently was help setup guidelines on when an application should use plain 'ol HTTP cookies, Flash local storage, or the MySQL cache. I got to become much more familiar with the MySQL cache, and thus it wasn't suprising to me when I heard about it winning the award from MySQL.