You searched for: 'native'

Tuesday, January 26th, 2010

A Titanium Tablet?

Category: Appcelerator, Apple

Appcelerator has published an interesting study on the Apple Tablet. You know, the iPhone OS based one that we will Steve will show us on Wednesday.

The study asks some interesting questions revolving around the development side of the tablet. Are developers going to develop for it? What are they looking for? What are they excited about from a technology perspective?

I found it interesting to see the type of companies looking to build apps:

Appcelerator_survey_tablet_category_ranking

Games will still probably be huge on the device, but it is great to see other types of apps at the ready.

Then we have the feature requests:

Appcelerator_survey_top_anticipated_features

Even if there is a way to run iPhone apps, it is clear that people will be spending effort creating truly native experiences. There are core differences beyond screen size here. Very different capabilities to take into account.

We are seeing an increase in consumer devices. I recently talked about the table stakes of 2010 and beyond. As a consumer it is exciting to see the vision of connected devices become real. As a developer, although there is new opportunity, it is incredibly daunting. How many proprietary SDKs can one learn and fund development on?

This is where the Web comes in. The Web has the potential to become the unifying platform across devices. This isn’t about write once run anywhere, but it is about offering advanced solutions to deliver experiences across the devices using shared code, services, and APIs.

Back to Appcelerator. They publish this study right before the tablet launch. Hmm…. something tells me that Titanium (now in mobile and desktop versions) will support Tablet. As companies struggle with the pull of delivering functionality to many devices, Titanium has an opportunity of helping developers out. We have heard that Titanium is going to GA some time soon (probably in March) and we will then see pricing plans and some new products (probably around analytics and metrics). Apparently more desktop and mobile applications will be developed using Titanium than Adobe AIR this year. That would be quite a feat.

What are your thoughts on the Tablet and the Web? What did you get out of the survey?

Here is Jeff talking about their work with Scoble:

Posted by Dion Almaer at 3:01 am
8 Comments

+++--
3.3 rating from 24 votes

Friday, January 22nd, 2010

YouTube and Vimeo turn on HTML5 video tag

Category: Showcase, Video

youtubehtml5

At Google I/O the team showed a demo of YouTube running video right in the browser, instead of in the rectangle of Flash.

Now, that URL takes you to the beta, which you can opt-in too. I am torn on what to write on this showcase though…. so, especially since it is Friday, here are two takes:

Open Web Advocate

It is fantastic to see a massive site – the poster child of Flash video – implement HTML5 video. If you want to piss of an Adobean ask them “how do you feel about YouTube folks making millions off of the back of your work. Surely you got a bunch of license money… oh wait.”

This is the first step for YouTube, and now that video is a native experience in the browser they can innovate in really interesting ways.

One bonus feature for trying the beta: “Videos with ads are not supported” :)

The Other Guy

It is great to see YouTube showing off HTML5 support, however you will notice that it only works in the Safari/Chrome world (saying it works in IE via ChromeFrame is cheating) due to the fact that YouTube only supports H.264 and hasn’t done Ogg. Sure it would take a lot to get Ogg support at that scale, but it would also help the cause a lot.

When you test it at this early stage you also see that there isn’t HD support or much of the other features of the Flash player, so instead of showing off how the experience can be better….. it is in catch up mode. Features such as full screen aren’t even an option yet of course. We need to move faster.

I am looking forward how things play out over time. What guy are you today?

NOTE: Vimeo are turning on support too, also H.264 only.

Posted by Dion Almaer at 6:21 am
19 Comments

++++-
4.6 rating from 44 votes

Friday, January 15th, 2010

jQuery 1.4 is released

Category: JavaScript, jQuery, Library

The incredibly popular jQuery library has released jQuery 1.4 on a new website that will celebrate 14 days of jQuery.

There are a lot of new features, and as usual performance gains are showcased.

  • Easy Setter Functions: For a while now, you’ve been able to pass a function into .attr() and the return value of that function is set into the appropriate attribute. This functionalilty has now been extended into all setter methods
  • Ajax: A lot of enhancements to the various remoting functions including support for native JSON parsing, etags, request context, and more
  • .css and .attr have been improved
  • Per property easing on effects
  • If you want to ensure that “this” inside a function will be permanently bound to a particular value, you can use jQuery.proxy to return a new function with that scope
  • New events: focusin and focusout

And Joe Walker will be really excited to see that dojo.create has made it in! :)

javascript

  1. jQuery("<div />", {
  2.     id: "foo",
  3.     css: {
  4.         height: "50px",
  5.         width: "50px",
  6.         color: "blue",
  7.         backgroundColor: "#ccc"
  8.     },
  9.     click: function() {
  10.        $(this).css("backgroundColor", "red");
  11.     }
  12. }).appendTo("body");

Congrats to the jQuery team. I look forward to seeing posts over the next 2 weeks that go into more detail on the new coolness.

Posted by Dion Almaer at 12:13 am
23 Comments

+++--
3.6 rating from 117 votes

Monday, January 11th, 2010

Using YQL as a proxy for cross-domain Ajax

Category: JavaScript, jQuery, JSON, XmlHttpRequest, Yahoo!

OK, this is nothing shockingly new, but I found it pretty useful. Using jQuery, Ajax has become more or less a one-liner:

javascript

  1. $(document).ready(function(){
  2.   $('.ajaxtrigger').click(function(){
  3.     $('#target').load($(this).attr('href'));
  4.     return false;
  5.   });
  6. });

This loads the document any link with a class of “ajaxtrigger” points to and updates the content of the element with the ID “target”. If the link is a third party link on another domain it fails though – and silently at that. Normally you’d work around that with a server-side proxy, but you can actually do without it.

YQL is a hosted web service that can scrape HTML for you. It also runs the HTML through HTML Tidy and caches it for you. For example to load http://bbc.co.uk you’d use the following statement:

  1. select * from html where url='http://bbc.co.uk'

As a URL this turns into:

  1. http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D'http%3A%2F%2Fbbc.co.uk'%0A&format=xml

You could request JSON-P by setting the output format to json and define a callback, but that would give the HTML back as a massive object which is not nice. YQL also offers JSON-P-X as an alternative which is a JSON object with a callback and the HTML as a string inside a simple Array. See it by clicking the following URL:

http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%27http%3A%2F%2Fbbc.co.uk%27%0A&format=xml&diagnostics=false&callback=foo

Now, using jQuery’s getJSON() we can load this even without a named callback function. That way we can use one method for content that is third party and simply use load() for the other:

javascript

  1. $(document).ready(function(){
  2.   var container = $('#target');
  3.   $('.ajaxtrigger').click(function(){
  4.     doAjax($(this).attr('href'));
  5.     return false;
  6.   });
  7.   function doAjax(url){
  8.     if(url.match('^http')){
  9.       $.getJSON("http://query.yahooapis.com/v1/public/yql?"+
  10.                 "q=select%20*%20from%20html%20where%20url%3D%22"+
  11.                 encodeURIComponent(url)+
  12.                 "%22&format=xml'&callback=?",
  13.         function(data){
  14.           if(data.results[0]){
  15.             container.html(data.results[0]);
  16.           } else {
  17.             var errormsg = '<p>Error: could not load the page.</p>';
  18.             container.html(errormsg);
  19.           }
  20.         }
  21.       );
  22.     } else {
  23.       $('#target').load(url);
  24.     }
  25.   }
  26. });

You can see the demo in action here, more details are available on my blog and the source is available on GitHub.

Posted by Chris Heilmann at 7:42 pm
8 Comments

+++--
3.6 rating from 37 votes

Sunday, January 10th, 2010

WebAIM Study: Screenreaders and Javascript Co-Exist

Category: Accessibility

Paul Irish points to a recent survey by WebAIM showing what high-level accessibility guidelines frequently omit to mention: screenreaders and Javascript often co-exist. The study shows between 75% and 90% of screenreader users have Javascript enabled. This isn’t just speculation, but a survey of 655 screenreader users.


This response may help strengthen the notion that scripted content must be made accessible. Many developers incorrectly believe that inaccessible scripting is permissible so long as it degrades gracefully or a non-scripted alternative is provided. The vast majority of screen reader respondents encounter scripted content.

Assuming you’ve solved the accessibility problem just by graceful degradation to raw HTML is fallacy. The whole issue is much more nuanced.

There’s also a handy summary of problematic items reported by this user segment, which ranked as follows:

  • CAPTCHA – images presenting text used to verify that you are a human user
  • The presence of inaccessible Flash content
  • Links or buttons that do not make sense
  • Images with missing or improper descriptions (alt text)
  • Complex or difficult forms
  • Lack of keyboard accessibility
  • Screens or parts of screens that change unexpectedly
  • Missing or improper headings
  • Too many links or navigation items
  • Complex data tables
  • Lack of “skip to main content” or “skip navigation” links
  • Inaccessible or missing search functionality

Posted by Michael Mahemoff at 5:06 pm
8 Comments

++++-
4 rating from 25 votes

Friday, January 8th, 2010

Palm Developer Program: Project Appetite, $1M How App Program, and more

Category: WebOS

Ben and I had a good time building Project Appetite including CSS 3d transforms, which shows up below. Fancy using your mad Web skillz to play in the $1M market driven Hot App Program? Below is a post from my personal blog about the webOS developer program launch.

It has been a very different holiday season as everyone got ready for CES this year. This is my second time at the show (first time was having the honor to pick up an award for the Gears team) and was a very different experience.

It was great to come out with some good news today: from Verizon, to video recording, to Flash, to 3D games. From a consumer point of view the Palm Mobile Hotspot is pretty sexy. Tethering has been a pain, and I was eyeing up a MiFi when I got to learn that devices will be able to become MiFi hotspots. Awesome.

All good stuff, but I am obviously most excited about the developer side of things. This year it turned out that we got to turn on the full developer program today in conjunction with the other CES news. A ton of work went into this first launch of the full program and there is a lot packed in there:

palmdevprogramopen

New developer portal

When you work with Ben, you quickly learn that things should be as polished as possible. He really lead the charge on making a great new developer portal with a spruced up look and feel throughout, and some good new content. There is a lot more in the works and the community has been coming together nicely to provide some fantastic documentation too. We now have a good foundation to move quickly on, and to really help developers.

PDK: On-ramp for native code via Plug-in Development Kit

One of the things I love about the Web is its diversity. It isn’t just One Community. It has sub communities galore. On the server-side you have Java and PHP and Ruby and Python and [insert every other platform] camps all at home on the Web. Even on the client-side, despite the ubiquity of JavaScript, you see many different types of developers.

I am really happy that we are providing the Plug-in Development Kit (PDK) that will enable a path to native code on the platform enabling a role that we have seen on the Web via Flash, Gears, QuickTime, RealPlayer, and on and on.

The goals of the PDK are:

  • Easy porting of C/C++ applications to webOS, including those that use OpenGL ES 1.1 or 2.0
  • Easy integration of C/C++ components to enhance the capabilities of webOS applications

Read more about the PDK.

Flash 10.1

Flash 10.1 fits into this picture too. I am glad that we have a path for Flash developers to get their content to our users. Adobe has been working very hard to make their engine work on mobile. This has got to be a tough problem given the nature of it (event loop etc) and they are doing great. Can’t wait to see the finished product.

Hot Apps

We want to put our money where our mouth is, and want to reward developers in a fair way, so we decided to offer $1 million dollars in cash bonuses to webOS developers through our Hot Apps Program.

Contests are interesting, but having been involved in a few myself, they get very subjective and judging can be difficult. This is why this time around we wanted to try to let the market do its thing and reward developers based on downloads and how many devices have installed their application.

Some high level info:

The Palm Hot Apps Program will reward developers of the hottest webOS applications with a total of $1 million. The top rewards of $100,000 will go to developers as follows:

  • The developer of the free webOS application that’s downloaded the most between February 1, 2010, and May 31, 2010 will receive a $100,000.
  • The developer of the paid-for webOS app that generates the most revenue during the same period will also receive $100,000.

Developers of other top free and paid apps will also receive cash awards, as follows:

  • The next 20 apps in each category: $10,000 each
  • The next 200 apps in each category: $1,000 each

To qualify for an award, your app – either free or paid – must be available to webOS users via Palm distribution programs between February 1, 2010, and May 31, 2010. In addition, the following criteria apply:

  • The app must have been developed using the Palm webOS Software Development Kit or the Ares Integrated Development Environment. Since the Palm webOS Plug-in Development Kit is not widely available, applications utilizing this development kit or any APIs not in the Palm webOS SDK are ineligible.
  • Apps must be available for download through an official Palm webOS distribution program (App Catalog Distribution, Web Distribution, or Beta Distribution). Apps distributed through non-Palm methods do not qualify.
  • Apps developed by Palm employees or their direct relations are ineligible for awards.

What do you think of this approach?

GitHub Palm Repository

palmgithub

I am a huge GitHub fan and I am really glad that we have opened up our Palm GitHub account with some goodies. We have various projects that contain sample code that go from ye olde hello world app, to Mitch Allen’s great news app from his book to the indispensable stylematters app that our great HI put out to show you how to make beautiful, usable applications.

I hope that this is just the beginning and that you will see more and more projects on GitHub to fork! Speaking of projects to fork….

Project Appetite

palmappetite

One of the new projects is Project Appetite which is an open source project showing how you can interface with the Palm application feeds that come out of our full catalog.

Early partners have already built sites using the feeds: PreCentral App Gallery, webOS App Catalog Viewer, the House of Palm, and on FreshMeat.

Now you can integrate the feeds yourself. There are a lot of different pieces in that one project, and I need some other posts to go into details on the front end code (some fun CSS transforms if you are in Safari on Mac and hit Ctrl-F!) as well as the backend (using Java, node.js and lots of good stuff). There is still a lot that we want to do to help people and this is just the beginning of that project.

Phew. What a way to start the new year. Thanks for joining me on this journey and I can’t wait to see what folks come up with (including us!)

Posted by Dion Almaer at 9:36 am
7 Comments

+++--
3.5 rating from 21 votes

Monday, January 4th, 2010

GLGE

Not sure if the whole WebGL thing will take off? Check out the video above which shows a simple scene constructed in blender and exported to GLGE for use in a WebGL capable browser.

What is GLGE?

GLGE is a javascript library intended to ease the use of WebGL; which is basically a native browser JavaScript API giving direct access to openGL ES2, allowing for the use of hardware accelerated 2D/3D applications without having to download any plugins.

The aim of GLGE is to mask the involved nature of WebGL from the web developer, who can then spend his/her time creating richer content for the web.

2010. WebGL. Awesome. Thanks Paul Brunt!

Posted by Dion Almaer at 6:17 am
8 Comments

++++-
4.2 rating from 37 votes

Monday, December 21st, 2009

Chrome Extensions and webOS Applications look quite similar

Category: Browsers

Reposted from my personal blog

appsandextensions

“If you squint, Chrome Extensions and webOS applications look similar” — a wise friend

Having now written webOS applications and Chrome Extensions I have been struck by how similar they are, and could be.

It may seem weird to see similarity in a browser extension mechanism and a mobile application runtime, but when you look at it, there is plenty to share at a high level:

Breaking out of the sandbox

Both worlds need to break out of the web browser sandbox. Extensions can’t be restricted to the same limitations and Chrome Extensions have various API that relate to UI elements in the browser, as well as getting access to more.

On webOS we have exactly the same issue. When building native applications on webOS you can’t have the same restrictions and thus new APIs, UI widgets, and services.

This issue goes beyond even these too worlds, and is one of the big challenges for Web runtimes in the near future. I expect my runtime to be able to do a lot more and to get access to my data not just through third party server side services, but locally too. This all brings us to…

Permissions

The Web needs a permissioning model. The sandbox doesn’t give us enough, and although people quickly talk about security (which is critical) we forget what happens if the user can’t do something through the Web. They often will download an .exe to their local computer and will just run it, not knowing anything about what it does.

A big challenge for us is to come up with a model that doesn’t Do A Vista and drive our users nuts. We have to balance the desire to not ask the user for something all the time, while making sure the user knows what is happening. For power users at least, I favour the idea of showing me what is going on. Even if I grant an application a lot of power, if I could see when and what it was doing it would help. Of course, being able to restrict access to APIs is fantastic, especially when you get to layer social trust on top of the technical security. The Mozilla team talked a lot about just this and I look forward to more of their ideas and implementation.

(You can see an example of how Chrome does permissions with Cross site XHR.)

Application Bundle Info

The permissions and other metadata need to live somewhere. We have a appinfo.json file that has you declare info on your app. Chrome has a manifest.json.

On the Web we don’t really have this. You hit a URL and you bootstrap from there. The HTML5 manifest does tell the browser which files are in scope for caching and the like, but that is about it. Applications and extensions can tell the system much more. You have ids, versions, pointers to update, icons, main launching points or not…

Headless Chickens

You don’t often think of a headless web app. You can think of headless applications and extensions though. How many services are running on your computer now that have no UI? On webOS you can noWindow away and still provide value through the various services that we offer, the obvious being the rich and varied notification styles. Background apps are nicely supported.

Chrome Extensions have the notion of a background page as a way to manage a long lived lifecycle. Your background page is a singleton:

In a typical extension with a background page, the UI — for example, the browser action or page action and any options page — is implemented by dumb views. When the view needs some state, it requests the state from the background page. When the background page notices a state change, the background page tells the views to update.

In webOS and the Mojo framework we have a rich MVC system with a detailed lifecycle as well as the simple ability to define models, views and controllers.

And on

The more I look at these worlds, and others like them (e.g. Jetpack) the more I hope we come together. There are similar needs, and when you look from Chrome Extensions to Chrome OS, you can see a potential progression if done right.

My first post in the series talked about how the Web runtime is jumping out of the browser and giving us new areas to target our skills and code.

Posted by Dion Almaer at 6:00 am
6 Comments

++---
2.9 rating from 21 votes

Tuesday, December 15th, 2009

PastryKit: An iPhone Webdev Library from … Apple

Category: iPhone, Library, Mobile

John Gruber has spotted a library for iPhone web apps, from none other than Apple. This mysterious library, called PastryKit, seems to have flown under the radar as a Google search reveals precious little on it. In similar vein to other efforts, Apple’s library provides support for native-feel websites – websites that run in Mobile Safari, but feel like native apps. (That’s the objective anyway; some look-and-feel emulators are “good enough”, while others get stuck in the uncanny valley).

To get hands-on with PastryKit:

  • Visit http://help.apple.com/iphone/3/mobile/ from your iPhone or iPod Touch. This is an official Apple site using PastryKit. If you’re feeling lazy/iPhone-challenged, watch Gruber’s screencasts.
  • Now with the same site in regular Safari (on your Mac/PC), open up the Develop Menu (if it’s not there, enable it in Preference|Advanced). Choose User Agent > Mobile Safari 3.0 (or probably any other version number). And now you can see it in your browser. From Develop Menu, Web Inspector will let you view the script.

The HTML includes PastryKit as follows:

  1. <!-- PastryKit -->
  2.     <link rel="stylesheet" href="dist/PastryKit-ug-compact.css">
  3.     <script type="text/javascript" src="dist/PastryKit-ug-compact.js" charset="utf-8"></script>

PastryKit Javascript and PastryKit CSS are available. Unfortunately, they’re a bit unclear due to compression, but Gruber nonetheless pored into the source:

PastryKit accomplishes all three of the aforementioned things — hiding the MobileSafari address bar, providing fixed-position toolbars, and providing scrolling with momentum — by disabling regular scrolling and setting up its own view hierarchy and implementing its own scrolling.

The whole question of native iPhone apps was a hot topic last month after PPK whipped up a storm on the question of web apps replacing iPhone apps. The really interesting thing here is Apple’s stance. They launched the iPhone with web intended to be the platform for 3rd party apps, then switched over to native apps and haven’t done much to facilitate native-style web apps since then. Is a change coming? As Gruber puts it:

The $64,000 question, though, is whether PastryKit is something Apple intends (or that a team within Apple hopes) to ship publicly. It seems like a lot of effort to build a framework this rich just for this iPhone User Guide, so I’m hopeful the answer is yes. Perhaps something integrated with the next major release of Dashcode? And, perhaps with integrated UI layout tools, along the lines of Interface Builder?

As well as apperaring in the user guide website, Chris Messina noted PastryKit apparently appears in the iTunes LP files.

Posted by Michael Mahemoff at 8:31 pm
8 Comments

++++-
4.3 rating from 30 votes

Thursday, December 10th, 2009

Dojo 1.4 is out with Significant Improvements to Performance, Stability, and Features.

Category: Dojo

The Dojo team announced today the release of Dojo 1.4, the culmination of 9 months of hard work by the crew.

While this release is primarily a stability and performance release, we managed to sneak quite a bit of great new functionality into the various projects. All the significant changes have been outlined in the 1.4 release notes (including migration issues), and are far too numerous to list here: ranging from simple convenience changes, like dojo.Animation callbacks now being passed the node being animated, to completely new APIs like dojo.cache providing build interning outside of of dijit._Templated. Some changes are simply exposing long standing “private” API’s: dojo._Animation is public as dojo.Animation now and dojo._contentHandlers has become dojo.contentHandlers exposing Ajax transport configuration for advanced users and giving an official commitment to the preservation of those APIs.

Dojo team member Dylan Schiemann said that:

Dojo 1.4 has substantial improvements yet again in performance, developer productivity, experience, and features. The community has come together to make this release well worth the upgrade

Key updates mentioned are:

  • IO Pipeline topics
  • dojo.cache
  • dojo.contentHandlers
  • dojo.hash with native HTML5 onhashchange event support where available
  • Traversal and manipulation for NodeLists (the return value for dojo.query)
  • dojo.ready (easier to type than dojo.addOnLoad)
  • Hundreds of refinements to the Dijit API and collection of Dijits, and a few new widgets in DojoX
  • DataChart widget and other improvements to charting
  • dojox.drawing lands!
  • Editor improvements and new plug-ins in both Dijit and DojoX
  • Grid is faster, and the EnhancedGrid lands!
  • ForestStoreModel for the TreeGrid
  • GFX improvements
  • dojox.jq, a very experimental module aimed at trying to match the jQuery API as close as possible, but using Dojo underneath
  • Dojo build system optionally supports the Google Closure Tools compiler
  • Significant speed improvements, especially in IE

The release notes go into great detail about the update so check it out for the full scoop.

With 1.4 out the door, the Dojo team is already looking at v1.5 which is slated for release on Q2 2010.

Posted by Rey Bango at 2:16 pm
5 Comments

++++-
4.2 rating from 52 votes

Monday, December 7th, 2009

Underscore.js gets some updates with 0.5

Category: JavaScript, Library

We posted on the underscore.js initial announcement and we liked what we saw.

Jeremy Ashkenas of underscore.js pinged us to let us know that it is chuggin’ along and the library is now up to 0.5 and has had changes such as:

  • OOP-style wrapping: _([1, 2, 3, 4, 5]).each( ... );
  • OOP wrapping allows you to chain together computations: _([1, 2, 3, 4, 5]).chain().map( ... ).flatten().reduce( ... ).value();
  • Added speed comparisons with jQuery to the test page. Because Underscore delegates to the native implementations whenever available, its “each” function is over 5 times faster than jQuery.each in Safari, and over 3.5 times faster in Firefox. Your mileage may vary, so you can use the test page to check it in your browser of choice.
  • Added reduceRight / foldr, to go along with reduce / foldl.
  • Added first / head, and rest / tail for car and cdr enthusiasts. It turns out that they’re immensely useful on JS arguments objects.
  • Added a “range” function, identical to Python’s range(), for easy array initialization.
  • A slew of other minor improvements, to get Underscore working out-of-the-box on Rhino, to use the native StopIteration object to break out of loops where available, and so on.

The latest Underscore.js 0.5.0 includes a couple of API cleanups, a couple of speedups, and a more comprehensive isEqual() function, with Date, NaN, and RegExp support.

Marcus Irven has ported the commonly-applicable Underscore functions to Lua, and released an Underscore.lua library this weekend.

Posted by Dion Almaer at 6:33 am
3 Comments

+++--
3.2 rating from 29 votes

Wednesday, November 25th, 2009

Javascript JPEG Encoding

Category: Canvas

Andreas Ritter has managed to encode JPEGs in Javascript. This blog post explains how he did it, shows some benchmarks, and provides a demo and a downloadable library so you can play along at home.

It was surprising that it was that easy to get the first js-encoded jpeg displayed in the browser. Of course I didn’t want to stop there. I wanted to optimize things as much as I could to make the encoder fast. This took me several days. I found optimized encoder versions for flash and haxe floating around the net (Faster JPEG Encoding with Flash Player 10) and tried the optimizations used there in my javascript version. As you can seen in the benchmarks below I was quite successful.

Another idea was to use the new web workers to do the heavy lifting in an separate thread, not blocking the gui. This is something flash can’t do. So I created a version using a web worker for the encoding.

The API gives you a JPEGEncoder or an alternative JPEGEncoderThreaded. Usage is straightforward:

javascript

  1. var myEncoder = new JPEGEncoder([quality])
  2. var JPEGImage = myEncoder.encode(CanvasPixelArray,[quality])

I think the results show that JavaScript is quite fast (at least in Safari and Chrome). A little over 4 seconds for the non-threaded version is a very good [sic] result, when compared to the 3,3 seconds the optimized flash jpeg encoder takes. Please note, that JavaScript has no static types, no byte array, no Vector-class and is not pre-compiled. Taking these facts into account Nitro and V8 are faster than the ActionScript 3 VM.

Comparing the different browsers Nitro and V8 are a magnitude faster than TraceMonkey. Firefox 3.6b2 shows some improvements, but it’s still a long way. Probably the Mozilla guys should consider adopting Nitro or V8?

He used the AS3 (ActionScript) JPEG encoder as a starting point. It’s worth noting there’s also a PNGEncoder there too; that’s a port waiting to happen.

Posted by Michael Mahemoff at 1:15 pm
15 Comments

++++-
4.2 rating from 51 votes

CBC Radio 3 Case Study

Category: Articles, Editorial, Prototype, Showcase

Phil Rabin of CBC Radio 3 has kindly written a guest post on his experience creating a fantastic Web interface for the station that uses Flash for audio, but a full HTML experience that maintains state from page to page.

cbcradio3

CBC Radio 3 is a community, radio station and user-generated independent music library which is a small department of the Canadian Broadcasting Corporation. When the CBC Radio 3 web team was called upon to rebuild the site we were confronted with the technical problem of having an uninterrupted music experience for our users. The old design of the site (see image) achieved this by embedding a flash player in the body with the content being served through a statically positioned iframe in the center of the page. Radio 3’s content offerings were outgrowing the design so we went with a full page 1000px-wide layout with the player resting in the page. This created an obvious hurdle being that with a fresh page load comes a bad listening experience like myspace where a single wrong click breaks the audio. Also, not having popup player was a design decision that was made to give the website a more integrated feel.

We decided to completely removed flash from the UI equation and went full html/ajax because we found that it offered more flexibility and play with the page. The hardest part was figuring out a way to maintain state on each page load while keeping the audio continuous.

We went with an old-school frameset to create a type of inter-frame communication with the top level frameset acting as the orchestrator/bootstrapper. The visible “UI Controller” frame is completely blown out with the stateful player frame hidden from view.

The stateful player frame contains hidden swfs to handle playing audio and connecting to RTMP for our live streaming. All the communication in and out of flash is handled by a couple gateway javascript classes to abstract out the flash from the rest of the application.

Here’s an example of a communication gateway for wrapping the events coming to and from flash. The event objects are native flash event objects that get sent by Flash’s ExternalInterface and come in as JSON that can:

javascript

  1. CBCR3.namespace("CBCR3.Player.External");
  2.  
  3. CBCR3.Player.External.RTMPGateway = Class.create(CBCR3.Commons.EventDispatcher, {
  4.      
  5.     initialize:function($super)
  6.     {
  7.         $super();        
  8.     },
  9.      
  10.     //Functions to receive events from flash    
  11.     sendStreamEvent:function(event)
  12.     {
  13.         this.dispatchEvent(event.type);
  14.     },
  15.    
  16.     sendMetaDataEvent:function(event)
  17.     {        
  18.         var metaData = new CBCR3.Player.Mappers.StreamMetaDataDtoMapper().mapCollection(event.metaData);        
  19.         this.dispatchEvent(CBCR3.Player.Events.RTMPStreamEvent.metaDataReceived, {metaData:metaData});
  20.     },
  21.        
  22.     //Functions to send commands from flash
  23.     sendStreamCommand:function(commandName, commandArgs)
  24.     {        
  25.         $(CBCR3.Player.Globals.rtmpPlayerId).streamCommand(commandName, commandArgs);
  26.     }
  27. });

A single instance of this gateway is always maintained in the application which is called by a sort of simple container like this:

javascript

  1. ExternalInterface.call("CBCR3.Player.Application.IoC.getInstanceOf('rtmpGateway').sendStreamEvent", event);

An instance of the gateway has to be maintained by the player application because events coming from flash have no context. This way the application classes can subscribe to events coming from flash like this:

javascript

  1. CBCR3.Player.Players.RTMPPlayer = Class.create(CBCR3.Commons.EventDispatcher, {
  2.     initialize:function($super, rtmpGateway, thumbLookupService)
  3.     {
  4.         $super();    
  5.          
  6.         this.rtmpGateway = rtmpGateway;        
  7.  
  8.         this.rtmpGateway.addEventListener(CBCR3.Player.Events.RTMPStreamEvent.metaDataReceived, this.rtmpMetaDataReceivedHandler.bind(this));        
  9.         this.rtmpGateway.addEventListener(CBCR3.Player.Events.RTMPStreamEvent.ready, this.streamReadyHandler.bind(this));
  10.         this.rtmpGateway.addEventListener(CBCR3.Player.Events.RTMPStreamEvent.connecting, this.streamConnectingHandler.bind(this));
  11.         this.rtmpGateway.addEventListener(CBCR3.Player.Events.RTMPStreamEvent.streaming, this.streamStreamingHandler.bind(this));
  12.         this.rtmpGateway.addEventListener(CBCR3.Player.Events.RTMPStreamEvent.connected, this.streamConnectedHandler.bind(this));
  13.         this.rtmpGateway.addEventListener(CBCR3.Player.Events.RTMPStreamEvent.metaDataConnected, this.rtmpMetaDataConnectedHandler.bind(this));
  14.         this.rtmpGateway.addEventListener(CBCR3.Player.Events.RTMPStreamEvent.failed, this.rtmpMetaDataFailedHandler.bind(this));
  15.  
  16.  
  17.     },
  18.  
  19.     streamReadyHandler:function(event)
  20.     {
  21.         //handle stream event
  22.     },
  23.  
  24.     streamConnectingHandler:function(event)
  25.     {        
  26.         //handle connecting event
  27.     },
  28.  
  29.     streamConnectedHandler:function(event)
  30.     {
  31.         //handle connected event
  32.     },
  33.  
  34.     rtmpMetaDataConnectedHandler:function(event)
  35.     {
  36.        //handle meta deta connected event
  37.     },
  38.  
  39.     rtmpMetaDataReceivedHandler:function(event)
  40.     {        
  41.         //handle meta data event etc etc
  42.     }
  43. );

At the core, audio is always played by Flash. The swfs broadcast events, such as audio head position and download progress of mp3s, and connection, streaming, meta data events from RTMP. Those events get passed on the instance of the hidden stateful player.

Since the server frame is only loaded once when the site first loads, an instance of the stateful server player is instantiated for the entire session on the site. On each client frame page load, the server player instance is “injected” into the visible client UI controller by the “bootstrapper” top frame. State is maintained in that instance which allows for the controller to query the state of that object and reestablish everything like which track is playing, progress, time, thumbs up or down status, shuffle, play mode (stream or individual mp3 and playlists), etc. Everything had to be covered like if an mp3 was in mid-load when someone browsed to a new page, the loading progress had to pickup on the next page. Here’s a example of the bootstrapper code contained in the frameset:

javascript

  1. CBCR3.namespace("CBCR3.Player.Application");
  2.  
  3. CBCR3.Player.Application.R3PlayerBootStrap = Class.create({
  4.  
  5.     serverFrame:null,
  6.     clientFrame:null,
  7.  
  8.     autoStart:true,
  9.     permalink:null,
  10.  
  11.     initialize:function(preferences)
  12.     {        
  13.         this.autoStart = preferences.autoStart;
  14.         this.permalink = preferences.permalink;        
  15.     },
  16.      
  17.     setServerFrame:function(serverFrame) {
  18.         this.serverFrame = serverFrame;
  19.     },    
  20.          
  21.     setClientFrame:function(clientFrame) {
  22.         this.clientFrame = clientFrame;        
  23.     },
  24.      
  25.      
  26.     //TRY LOAD PLAYER
  27.     loadPlayer:function()
  28.     {        
  29.         if(!this.clientFrame || !this.serverFrame)
  30.             return;
  31.  
  32.         //both frames are loaded at this point
  33.         if(this.serverFrame.getPlayerInstance() == null)
  34.             this.initializePlayer();
  35.         else
  36.             this.resumePlayer();
  37.     },
  38.      
  39.     initializePlayer:function()
  40.     {
  41.         this.serverFrame.initPlayer();
  42.  
  43.         this.clientFrame.checkEnvironment();
  44.         var masterPlayerInstance = this.serverFrame.getPlayerInstance();
  45.         this.clientFrame.loadPlayer(masterPlayerInstance);
  46.         masterPlayerInstance.addEventListener("stateInitEvent:streamPlayerLoaded", this.streamPlayerLoadedHandler.bind(this));
  47.         masterPlayerInstance.addEventListener("stateInitEvent:playlistPlayerLoaded", this.playlistPlayerLoadedHandler.bind(this));
  48.     },
  49.      
  50.     resumePlayer:function()
  51.     {
  52.         this.clientFrame.loadPlayer(this.serverFrame.getPlayerInstance());
  53.         this.clientFrame.resumePlayer();        
  54.     },
  55.      
  56.     streamPlayerLoadedHandler:function(event)
  57.     {
  58.         if(this.autoStart && this.permalink.include("/stream/"))
  59.             this.clientFrame.getPlayerInstance().stream(this.permalink);
  60.     },
  61.      
  62.     playlistPlayerLoadedHandler: function(event)
  63.     {
  64.         if(this.autoStart && this.permalink.include("/play/"))
  65.             this.clientFrame.getPlayerInstance().playlist(this.permalink);
  66.     }
  67. });

We used Prototype/Scriptaculous as the base for the entire site. All the AJAX communication is handled with asp.net web services with scripting enabled. ASP.NET takes care of all the serialization of DTO’s (Data Transfer Object) into JSON which are specific to the player application.

All of the classes in the application are written using Prototype’s Class/inheritance model. Most of the classes subclass from a base EventDispatcher much like AS3, which is adapted from Matthew Foster’s example for Prototype and our own custom Event model. This allows for a nice separation of concerns and decoupled classes throughout the application and allows the UI Controller to add event listeners to custom events coming from the server player instance.

javascript

  1. CBCR3.namespace("CBCR3.Commons");
  2.  
  3. CBCR3.Commons.EventDispatcher = Class.create({
  4.      
  5.     buildListenerChain:function()
  6.     {
  7.          
  8.         if(!this.listenerChain)
  9.             this.listenerChain = {};                                    
  10.      
  11.     },
  12.      
  13.     addEventListener:function(type, listener){
  14.                                    
  15.         if(!listener instanceof Function)
  16.             alert("Listener isn't a function");
  17.              
  18.         this.buildListenerChain();
  19.                  
  20.         if(!this.listenerChain[type])                          
  21.             this.listenerChain[type] = [listener];
  22.         else
  23.             this.listenerChain[type].push(listener);
  24.          
  25.     },
  26.          
  27.     hasEventListener:function(type)
  28.     {
  29.         return (typeof this.listenerChain[type] != "undefined");
  30.     },
  31.      
  32.     removeEventListener:function(type, listener)
  33.     {
  34.         if(!this.hasEventListener(type))
  35.         return false;
  36.      
  37.         for(var i = 0; i &lt; this.listenerChain[type].length; i++)
  38.             if(this.listenerChain[type][i] == listener)
  39.                 this.listenerChain.splice(i, 1);
  40.      
  41.     },
  42.      
  43.     clearEventListeners:function()
  44.     {
  45.         this.listenerChain = {};
  46.     },
  47.      
  48.     dispatchEvent:function(type, data, target)
  49.     {        
  50.         var    event = new CBCR3.Commons.Event(type, data, target || this);
  51.         this.buildListenerChain();
  52.      
  53.         if(!this.hasEventListener(type))
  54.             return false;
  55.      
  56.         this.listenerChain[type].any(function(funct){
  57.             return (funct(event) == false ? true : false);
  58.         });
  59.     }
  60. });

This also allows the UI Controller to unsubscribe from all events when the page unloads. This was key in memory management and so that we don’t get orphaned references to instances of the UI Controller.

The most difficult part of the whole player project was re-establishing state of the controller on every page load. We hoped that we could implement some sort of state-pattern with no luck. In the end, the UI controller contains a couple monster resume methods that we haven’t been able to abstract out of that class. We’d like to bring in some sort of MVC architecture that wires up the UI player view to a state object. Any suggestions would be welcome! Go check out the site and give us some feedback!

Dion: I then asked Phil about the CBCR3 library and he replied

CBCR3 is the base namespace for all th javascript controls and apps written for the site. Everything for the player is in CBCR3.Player, the concert calendar is CBCR3.Gigs, etc. We have a shared base lib which is in CBCR3.Commons.

An issue with Prototype that we had was some bug with including 1.6.1 in a frameset in Opera. So, right now the frameset is holding an older version of prototype while the frames have the latest. One thing that Prototype was seriously lacking was Date extensions. (like addDay, addMonth, addWeek) etc.
We ended up going with YUI’s DateMath widget for that which really smoothed out working with dates.

Most of the issues we had cross-browser stuff was with IE6 (no surprise), which were almost all related to CSS rendering bugs, and IE DOM manipulation problems. A big one was upon the dynamic removal of items from lists. IE has a real hard time refreshing the positions of items. We had to write methods like

javascript

  1. myList.select("li").each( function(item){
  2.    li.setStyle({display:"none"});
  3.    li.setStyle({display:"block"});
  4. });

this would in effect “nudge” the browser and force it to update the position of the remaining DOM elements. In the end, we chose to drop IE6 support and to tell you the truth, we haven’t heard a single complaint about it!

Posted by Dion Almaer at 6:05 am
10 Comments

+++--
3 rating from 31 votes

Monday, November 23rd, 2009

New SVG Web Release: Gelatinous Cube

Just in time for Thanksgiving is another SVG Web release. The SVG Web project’s tradition is to name SVG Web releases after monsters from D&D just to increase the geek factor, so in that spirit their release name this time is “Gelatinous Cube”:

The Gelatinous Cube is a truly horrifying creature:

A gelatinous cube looks like a transparent ooze of mindless, gelatinous matter in the shape of a cube. It slides through dungeon corridors, absorbing everything in its path, digesting everything organic and secreting non-digestible matter in its wake. Contact with its exterior can result in a paralyzing electric shock, after which the cube will proceed to slowly digest its stunned and helpless prey.

Fun times.

Highlights of this release:

  • Loads of important bugs fixed
  • Performance improvements
  • You can now dynamically create new SVG root tags
  • All the namespace aware functions now implemented: setAttributeNS, getAttributeNS, etc.
  • You can now clone SVG nodes (cloneNode)
  • You can now right-click on the SVG when using Flash to view the dynamic updated SVG source
  • Running getElementsByTagNameNS scoped to a particular node now works, such as myGroup.getElementsByTagNameNS(svgns, ‘text’)
  • and much much more

Read more about the new release.

Learn more about SVG Web:

About SVG Web and SVG:

SVG Web is a JavaScript library which provides SVG support on many browsers, including Internet Explorer, Firefox, and Safari. Using the library plus native SVG support you can instantly target close to 100% of the existing installed web base. SVG itself stands for Scalable Vector Graphics, an open standard that is part of the HTML 5 family of technologies for interactive, search-engine friendly web vector graphics.

Posted by Brad Neuberg at 6:15 am
Comment here

+++--
3.9 rating from 13 votes

Friday, November 20th, 2009

Full Frontal ’09: Simon Willison on Server-Side Javascript and Node.js

Category: JavaScript, Server

Simon Willison snuck in a last-minute topic change, and is now going to give the server-side Javascript talk.

The news of the past 24 hours is ChromeOS. For the first time in years, someone’s re-thinking how an OS should work. With Chrome, you turn on your computer and you’re in the browser. What’s really interesting is to contrast it to the introduction of the iPhone, where Apple’s apps used native APIs while they expected developers to write web apps running in the browser with limited abilities. Here, Google’s apps are using the same web platform…it’s a level playing field.

Javascript combined with JSONP makes it real easy to write quick and dirty apps. An example of a quick app is Tweetersation Simon wrote with Natalie Downe. Simple app, 200 lines, written in an afternoon. At a larger system level, there’s Google Moderator, which is essentially a pure-Javascript solution with a no-op in the noscript tag.

These pure Javascript apps are great for experimenting and prototyping. The problem with this style of development, though, is you’re completely breaking web standards. The web Simon “felll in love with” is one where you point to a URL and you get content coming back.

With server-side Javascript, we can get the benefits of the things we like about Javascript, but without throwing away with the things we like about the web. Simon has been playing with node.js, and evidently the results were important enough to throw out the old talk and make this new one.

Take a step back and look at the interaction patterns with a web server. The conventional model is straightforward request-response, where the server tries to respond and disconnect as quickly as possible. But … there’s also the event loop model. As in Comet; it’s generally considered to be more efficient, so why do web developers avoid it? Simon says traditional server-side languages aren’t designed to deal with event-driven programming. It’s more like “do A, do B, do C, exit”. Javascript, on the other hand, is well suited to do callback-driven event programming.

Brave Simon now proceeds to live code with node.js. He shows a “Hello World” daemon, where the code looks like Ajax in reverse, and runs extremely fast. But where it gets really interesting – and useful – is with Comet. Another demo. The code is tiny and the benchmark looks good.

Simon’s built his own framework on top of node.js: Djangode takes the best features from Django and sticks them on the server.

javascript

  1. var dj = require('./djangode');
  2. dj.serve(dj.makeApp([
  3.     ['^/$', function(req, res) {        dj.respond(res, '<h1>Homepage</h1>');    }],    ['^/other$', function(req, res) {
  4.         dj.respond(res, '<h1>Other page</h1>');
  5.     }],
  6.     ['^/page/(\\d+)$', function(req, res, page) {
  7.         dj.respond(res, '<h1>Page ' + page + '</h1>');
  8.     }]
  9. ]), 8008); // Serves on port 8008

The more interesting example is Comet, which he’s demo’d here.

Moving on to persistence, there’s the NOSQL trend of the past 18 months, and he shows how simple it is to write CouchDB queries from node. It’s easy to talk to CouchDB from Node.js apps. Redis is another interesting database, which could lead to pages being rendered very quickly, given its performance benchmarks.

Posted by Michael Mahemoff at 12:41 pm
Comments Off on Full Frontal ’09: Simon Willison on Server-Side Javascript and Node.js

+++--
3.2 rating from 34 votes

Full Frontal ’09: Jake Archibald on Performance Optimisation

Category: Performance

Jake explains no-one likes waiting, and people are multi-threaded (except when they have to sneeze). Yet, we’re stuck with a single-threaded language for the most part; and we still face the legacy of a DOM standard from another era (DOM Level 1 – 1997). This talk provides some optimisation tips, backed by Jake’s cross-browser experiments.

Jake’s slides and research are online.

Optimise Where it Matters

Jake explains the importance of speeding things up where it really matters.

Doug Crockford has pointed out that in Javascript, bitwise operations aren’t close to the hardware, which stands in contrast to other languages. In fact, if you look at it, bitwise operations can still be faster than alternative operations; Jake shows an example where bitwise parsing of hex codes is faster than bitwise. The question is, how much faster? In many cases, such as this example, your energy is better spent on optimising big things.

Avoid eval() Where Possible

Jake says avoid eval() where possible. Thinking about what functions eval, here’s a brain teaser: what will the following output?

javascript

  1. var msg = "spatchcock";
  2. function doStuff() {
  3.   alert(msg);
  4.   if (false) {
  5.     var msg="spotted dick";
  6.   }
  7. }
  8. doStuff();

Wait for it … the answer is “undefined”. Javascript does look ahead and create space for the local variable. So during the running of the function, there’s no need to allocate space for the variable and the browser can optimise for that, but if you use “eval”, the optimisation goes away. So avoid eval().

Prefer innerHTML to DOM

Jake shows a comparison of innerHTML versus DOM Level 1. In IE, DOM manipulation is much slower, because of the sync process between the two. The differential gets even worse when creating elements. Webkit has optimised sync between HTML and DOM, hence less difference, so it’s not as bad, but create example is still slower with DOM. So from a performance perspective, best practice is construct the HTML and use innerHTML.

Selectors

It’s educational to look at the implementation of selector libraries. Jake shows a comparison – IE7 is vastly more slow in this case. It doesn’t support getElementsByClassName, querySelectorAll, evaluate; and it does support getElementById, but that’s not used by sizzle for this query. So getElementsByTagName is all that’s left; and if you knew that, and the implications, you could have made the query much faster.

Benchmarking

Pretty simple.

javascript

  1. var duration;
  2. start = new Date()
  3. thingToTest();
  4. duration = new Date() - start;

However, timing isn’t so accurate, so stick it in a function and run it many times.

Too easy … so go benchmark and report your findings.

Posted by Michael Mahemoff at 12:11 pm
13 Comments

++++-
4 rating from 25 votes