Activate your free membership today | Log-in

Wednesday, August 18th, 2010

When does JavaScript trigger reflows and rendering?

Category: CSS, Performance

Thomas Fuchs has some good performance things to say reflows and rendering. A video of wikipedia gives you an idea of how much happens when a basic page is rendered:

The advice?

The important thing is to always remember that reflowing and rendering HTML is the single most expensive operation browsers do. If your page feels sluggish it’s most likely a problem with rendering. While the easiest way to optimize is to get rid of as many nodes as you can, and trying to have simpler CSS rules, sometimes JavaScript is the culprit.

Following changes to the page, a Javascript query like someElement.offsetHeight will block execution - to give you the right answer, any pending reflow has to be executed first. So code like this:

JAVASCRIPT:
someElement.style.fontSize = "14px";
if(someElement.offsetHeight>100){ /* ... */ }
someElement.style.paddingLeft = "20px";
if(someElement.offsetWidth>100){ /* ... */ }
 

could be twice as fast if you wrote it like this:

JAVASCRIPT:
someElement.style.fontSize = "14px";
someElement.style.paddingLeft = "20px";
if(someElement.offsetHeight>100){ /* ... */ }
if(someElement.offsetWidth>100){ /* ... */ }
 

because there are two reflows in the first example, and only one in the second.

Posted by Michael Mahemoff at 6:26 am 8 Comments

Wednesday, July 28th, 2010

Canto.js: An Improved Canvas API

Category: Canvas, JavaScript, Library

Javascript author extraordinaire David Flanagan released Canto.js recently, a lightweight wrapper API for canvas, introduced here and documented at the top of the source code. Example:

JAVASCRIPT:
canto("canvas_id").moveTo(100,100).lineTo(200,200,100,200).closePath().stroke();
 

Notice three things:

  • canto() returns an abstraction of the canvas - a "Canto" object.
  • As with jQuery and similar libraries, there's method chaining; each method called on a Canto also returns the Canto.
  • lineTo() has been extended to support multiple lines being drawn in a single call.

Instead of setting the ink properties and then painting it, you can do it all in one step:

JAVASCRIPT:
canto("canvas_id").moveTo(100,100).lineTo(200,200,100,200).closePath().stroke({lineWidth: 15, strokeStyle: "red"});
 

And plenty more syntactic sugar - check out the API in the source code comments. Sweet!

Thanks @pkeane.

Posted by Michael Mahemoff at 11:10 pm 19 Comments

Monday, July 26th, 2010

Canvas Color Cycling

Category: Canvas, Games, Graphics, Performance

Interest in Canvas, as well as mobile apps, has led to a renaissance of old-school 8-bit graphics. Joe Huckaby of Effect Games has been playing around with color cycling, leading to some stunning effects.

Anyone remember Color cycling from the 90s? This was a technology often used in 8-bit video games of the era, to achieve interesting visual effects by cycling (shifting) the color palette. Back then video cards could only render 256 colors at a time, so a palette of selected colors was used. But the programmer could change this palette at will, and all the onscreen colors would instantly change to match. It was fast, and took virtually no memory.

There's a neat optimization going on here too: instead of clearing and redrawing the entire scene with each frame, he only updates the pixels that change:

In order to achieve fast frame rates in the browser, I had to get a little crazy in the engine implementation. Rendering a 640x480 indexed image on a 32-bit RGB canvas means walking through and drawing 307,200 pixels per frame, in JavaScript. That's a very big array to traverse, and some browsers just couldn't keep up. To overcome this, I pre-process the images when they are first loaded, and grab the pixels that reference colors which are animated (i.e. are part of cycling sets in the palette). Those pixel X/Y offsets are stored in a separate, smaller array, and thus only the pixels that change are refreshed onscreen. This optimization trick works so well, that the thing actually runs at a pretty decent speed on my iPhone 3GS and iPad!

Posted by Michael Mahemoff at 7:21 pm 13 Comments

Tuesday, May 25th, 2010

TabNabbing: Phishing By Switching Background Tab Content

Aza Raskin identifies yet another form of phishing attack. Tabnabbing is the process of replacing the entire contents of a page while it's in a background tab. Want to see it in action? Just visit Aza's article, switch to another tab for 5 seconds and see what happens. Nice clean demo, and as scary as it is simple.

There's no reload because it's possible to change favicon, title, and page contents via Javascript. Reading through the comments, the attack seems to work most consistently and potently in Firefox, with other browsers being a mixed bag based on how they handle dynamic favicons and the focus event.

The steps in detail:

  1. A user navigates to your normal looking site.
  2. You detect when the page has lost its focus and hasn’t been interacted with for a while.
  3. Replace the favicon with the Gmail favicon, the title with “Gmail: Email from Google”, and the page with a Gmail login look-a-like. This can all be done with just a little bit of Javascript that takes place instantly.
  4. As the user scans their many open tabs, the favicon and title act as a strong visual cue—memory is malleable and moldable and the user will most likely simply think they left a Gmail tab open. When they click back to the fake Gmail tab, they’ll see the standard Gmail login page, assume they’ve been logged out, and provide their credentials to log in. The attack preys on the perceived immutability of tabs.
  5. After the user has entered their login information and you’ve sent it back to your server, you redirect them to Gmail. Because they were never logged out in the first place, it will appear as if the login was successful.

Aza also notes the attack could get a lot more potent if they (a) used the CSS history exploit to discover which sites the user has visited; (b) employed certain other techniques, like timing attacks, to determine which services a user is currently logged into.

A New Type of Phishing Attack from Aza Raskin on Vimeo.

Posted by Michael Mahemoff at 10:10 am 7 Comments

Thursday, April 22nd, 2010

PHPJS: PHP Functions in JS, Now with CommonJS Packaging

Category: JavaScript, Library, PHP

phpjs

PHPJS is an effort to bring the mammoth PHP API into the land of JS., where it can be used for web apps as well as the increasing number of Javascript applications outside the browser.

The homepage explains some of the philosophy behind this project:

PHP is a language with many high-level functions and while they're not always implemented as consistently as we'd like (mostly to blame on its underlying C parts), it has a huge following familiar with its syntax so it makes sense to pick its API as a reference. Eliminating the need for our own documentation, thus making life easier, we hope.

We recognize JS - on the other hand - has beautiful language features, and we encourage you to learn them. Never let php.js be an excuse not to.

For the same reason, we're not porting entire language or control structures of PHP; we stick with the functions.

That said, we think of it as a challenge to port everything and decided to also port low-level PHP functions like strpos even though it may have a JavaScript counterpart (String.indexOf). Cause besides the intellectual challenge for us, porting more also opens up php.js to all kinds of thought excercises and study purposes. And so we leave it up to the developer to decide what to take from this resource. And what not.

It's not new - the project's been around a while and went to GitHub last September. However, it's noteworthy as it appears to be fairly unknown in parts of the Javascript community, judging from recent Twitter responsage to a mention of the project. (It was news to me, and I dabble in PHP.)

Moreover, there is significant progress here: project founder Kevin van Zonneveld yesterday announced CommonJS support. The homepage indicates it's "first steps", but longer term, this potentially brings a huge corpus of library functions into the realm of CommonJS, a win for reuse and a win for all the PHPers getting into JS.

Posted by Michael Mahemoff at 10:11 am 12 Comments

Sunday, April 18th, 2010

The Best of Steve: Performance at JSConf

Category: Performance, Presentation

steve_book_large

(Live blogging notes.)

At JSConf, Steve Souders walks us through several performance-optimising things on his mind lately.

Site Speed in PageRank

A week ago, Google announced site speed is going to be taken into account for PageRank. For Steve, this is a dream come true. Now companies are going to start investing in performance, so less of those slow-loading sites that frustrated him enough to get started down this performance path. One of the criticisms is that this will favour big companies, but Steve points out that smaller companies are often more nimble and able to adapt to changes like this.

As part of Google's webmaster tools, site performance is shown to respective site masters, along with some guidance. Another good resource is http://www.webpagetest.org/. Other than its main measurement service, a great feature of WebPageTest is side-by-side comparisons. Show your manager a side-by-side against a competitor for guaranteed satisfaction.

Performance of Third Party Widgets

There's been something of a reversal in performance hotspots. Five years ago, it was the core application code that was mostly slowing things down, much as teams would like to blame performance problem on 3rd party ads. Nowadays, those apps have been more finely tuned, and at the same time, people are using more 3rd party stuff - not just ads, but embedded widgets. All of which explains why Steve's been looking at third-party widgets lately. You can see what he's been up to at P3PC, a benchmark tool for third-party widgets.

A key question is how are the widgets embedded? People are no longer just doing the blocking document.write calls. Instead, it's much more common to dynamically create a script tag and append to the page. But where and how do you append it? jQuery's library code, for example, does it in a simple, elegant, manner:

JAVASCRIPT:
var head = document.getElementsByTagName("head")[0] || document.documentElement,
  script = document.createElement("script");
...
head.insertBefore(script, head.firstChild)
 

Others, not so much. See Steve's recent blog posts for more analysis on these techniques (e.g. on Google Analytics).

Frag Tag

An early proposal from Steve and Alex Russell ...

<FRAG>
<script src="snippet.js"></script>
</FRAG>

The idea is that the frag loads independently; even document.write doesn't block. And it could go further, into a sandboxing mechanism. "If we had this frag tag, it would be one of the biggest things website owners could do to improve the performance of their pages."

Browser Disk Cache

The main message here is that browser disk cache is too small, and he's been talking to vendors about upping capacity. And there's a survey for you.

What makes sites feel slow?

So lately Steve's been going back to basics and looking at user perception, thinking not just about how fast the Javascript takes to load, but how fast till the user sees anything. So he's promoting the standard progressive enhancement pattern, similar to Facebook's earlier talk:

* Deliver HTML
* Defer JS
* Avoid DOM
* Decorate later.

He's done a couple of studies to this end:

* Charting page load time - as the user actually sees it - against market share...in an attempt to show faster sites mean bigger market share.
* Looking at initiail payload versus execution. Many of the sample (highly popular) sites are serving many functions on initial payload, which could be deferred until later - putting scripts at the bottom of the page, and loading scripts asynchronously.

Other Stuff

Check out:

* Browserscope, "a community-driven project for profiling web browsers".

* HTTP Archive Format (HAR). An industry standard for capturing Used in an increasing number of tools, e.g. NetExport plugin in Firebug.

* Velocity Conference, which Steve founded with O'Reilly. June 22-24, Santa Clara.

Posted by Michael Mahemoff at 2:54 pm 2 Comments

Facebook’s Javascript Speed-Up

Category: Performance, Showcase

facebook_logo

(Live blogging notes.)

Makinde Adeagbo is describing Facebook's Javascript performance optimisation efforts at JSConf. By 2009, it became clear something had to be done, as the trend was towards longer and longer page loads. Back in 2006, the objective had been super fast page loading: "If any page loads in under 100ms, it takes way too long". By 2008, given all the new interactive features on the page, the 100 millisecond target had expanded to 1 second, and by mid-2009, pages were taking 5 seconds to load. Even HipHop, the PHP compiler, was smaller than the Javascript code base. And when Steve Souders called out Facebook in his book numerous times, it only adding to the team's sense of fun and joy ;).

In June 2009, the team quickly chose a target by year's end by simply checking the load time without Javascript: 2.5 seconds. Thus, dropping load time from 5 seconds to 2.5 seconds was the goal for end of 2009.

The first initiative was to include the Javascript at the bottom of the page. Great, it's faster, but at what cost? A big one: Users try to click on controls, and nothing happens. Back to the drawing board, and the team refined the setup so that the actionable stuff was initialised on the top of the page. But how to minimise all this code at the top of the page? Here, the team exploited the observation that most controls work the same way:

* User clicks
* Sends ASync request
* Insert/Replace some content

So the team set up elements like this:

<a href="/ring.php rel="dialog">...</a>

... And then hijacked them with a standard listener routine, one that would work for most of the controls. (Most, not all; 80/20 principle is in effect here.) This way, they could have one small listener routine to handle most of the controls on the page. Once the user clicks, the server gets called and outputs a new snippet of Javascript:

The Javascript:

JAVASCRIPT:
new Dialog().setTitle().setBody().show();
 

would be output by a PHP script, and then evaluated in the browser:

PHP:
$response = new DialogResponse();
$response->setTitle()->setBody()->send();
 

(A form of On-Demand Javascript.)

In fact, the team has a whole PHP library for outputting Javascript. For example, when a request comes in to expand a new story:

PHP:
$response = new AsyncResponse();
$response->setContent("#elem_id", $new_content);
$response->appendContent("#content .stories", $new_story);
$response->send();
 

And they are using a convention: "ajaxify=1" on an element indicates it's ... Ajaxified.

At this point, the team had now Ajaxified a bunch of features, but people were still skeptical about more complicated features. For example, would setting status be too hard with the same techniques. So after some research, Makinde came back with an epiphany: the humble form. Whereas the previous async requests were effectively information-less - just a simple directive and maybe an ID - the requests would now include content too. And of course, most of these things look nothing like forms due to styling. But underneath, they're still forms, e.g. the entire comments block is a single form.

Nowadays, most of Facebook runs without complete page refreshes, by dynamically flipping the content and the fragment ID. (What Facebook calls page transitions.)

Ongoing, Makinde says performance optimisation requires ongoing vigilance. Every engineer has their special case, but in the scheme of things, it's better to say no to new features unless they can be strongly justified. For example, we can live with user submitting a form that hasn't yet been hijacked; a complete page refresh is fine on occasion. We don't like it, but we don't want to make it a special case just for the sake of it.

The Gantt charts tell a great tale: users now see content much earlier, and it's interactive. So how did they fare with that 2.5 second goal for year's end? Achieved by December 23. And Makinde wants people to know Facebook is hiring as they have more Javascript to write...and delete.

UPDATE: And here are the slides ...

Posted by Michael Mahemoff at 10:56 am 3 Comments

Monday, April 12th, 2010

The Future of History

Category: HTML

back-to-the-future

Kyle Scholz has a good overview HTML5 history (spec here). We've seen more and more apps adopt the fragment identifier pattern, where you get URLs like http://www.viewru.com/#Bonobo. Better than nothing, but Kyle observes there are several downsides:

Sluggishness

  • Executing a timeout function every 100ms won't make your app any faster.
  • 100ms delay in responding to back button actions.


Browser compatibility

  • The solution above doesn't work, for example, in IE 6-7, which won't add a history event on a hash change. Really Simple History gets around this by adding an iframe and issuing a call to your server for every state change. Webkit browsers present different challenges.

Not a stack

  • Suppose your application transitions from A->B->C. Can it transition directly back to A?

HTML5 offers a cleaner solution:

JAVASCRIPT:
// Push the state onto the history stack
function setState(state) {
  window.history.pushState(state, '');
}
// Respond to a popstate event.
window.onpopstate = function(e) {
  handleState(e.state);
};
 

Not only can you move back and forth between state, but you can also set URL and page title with this API. (The fragment ID was traditionally used because it was the only way to set the URL without causing a page reload.) Comparing the new techniques to traditional fragment ID hackery:

  • Content is crawlable: A developer may express all crawlable states of their application as valid URLs.
  • HTTP-Referer is meaningful: The referrer can reflect the latest state of the application and show or hide any information to/from 3rd parties, at the developer's discretion.
  • Bookmarks can be handled in a single fetch: Since application state can be expressed in a URL, it's possible to service a request for the application and state in one request/response.
  • Can use a single URI scheme to cover new and old browsers: Since information is encoded in URLs instead of the location hash, modern and legacy users can share bookmarks and links.
  • Audible "click" in IE? Okay, I don't know about this one, but it makes sense that programmatic operations on window.history would not have an audible side effect, right?
  • Posted by Michael Mahemoff at 5:52 pm 4 Comments

    Monday, March 29th, 2010

    TXJS: Upcoming JS Conference in Austin

    Category: Conferences

    txjs

    JSConf is around the corner, but there's more 2010 conference action in the pipeline. Paul Irish pinged me about YayQuery's TXJS and its all-star cast:

    TXJS is a full-day conference hosted by yayQuery on June 5 in Austin, Texas. We just landed Douglas Crockford and John Resig as speakers, so what started as a regional conference has turned into sort of a big deal.

    Besides Crockford and Resig, we've got Peter Higgins, project lead for the Dojo toolkit; Juriy Zaytsev (aka kangax) and Andrew Dupont from the Prototype library; Brian LeRoux of PhoneGap fame; Node.js contributor Tim Caswell; and many others. We'll be announcing the venue in a few days.

    After the talks, we have a hack night and party in downtown Austin, sponsored by Google and hosted by Austin JS.

    They've kept the prices cheap at $69 for the day.

    Posted by Michael Mahemoff at 4:25 am 3 Comments

    Wednesday, March 10th, 2010

    Harmony: Canvas Drawing Tool

    Category: Canvas, Showcase, iPhone

    Harmony is a new drawing tool, a HTML5/Canvas experiment with great potential. It provides some unique brush styles, and can produce some great-looking charcoal pencil style sketches, among other things. Better to try it out than explain it in words.

    Creator Mr. Doob (Richard Cabello) explains how he used Canvas to make it darker the more you draw over it:

    The whole thing is quite modular so I can keep adding more brush styles whenever I get inspired. During the process I found out that, for some reason (apparently lack of hardware acceleration), Firefox and Opera do not support context.globalCompositeOperation = 'darker'. This was on the HTML5 spec before but got removed. Just so you know what I'm talking about, this is like the "multiply" blending in Photoshop. Webkit does support it tho. I hope they put it back on the specs and all browsers support it.

    You can also save images using data URI encoding.

    As it works on webkit, he made sure it worked on the mobile Android and iPhone browsers. No multi-touch as yet, but the touch UI still makes a nice input mechanism.

    harmony

    (Thanks FND)

    Posted by Michael Mahemoff at 4:50 am 3 Comments

    Tuesday, February 23rd, 2010

    Mouseovers on Touch Devices

    Category: Apple, Editorial, Flash, iPhone

    Most of the thinking on iPad's exclusion of Flash has been focused on battery life, performance, stability, or control of the application market, but here's a Flash developer who's thinking differently. Morgan Adams argues it's all about the mouseover, and he raises a point that is just as relevant to rich Javascript apps.

    Many (if not most) current Flash games, menus, and even video players require a visible mouse pointer. They are coded to rely on the difference between hovering over something (mouseover) vs. actually clicking. This distinction is not rare. It’s pervasive, fundamental to interactive design, and vital to the basic use of Flash content. New Flash content designed just for touchscreens can be done, but people want existing Flash sites to work. All of them—not just some here and there—and in a usable manner. That’s impossible no matter what.
    ....
    Mouseover examples:

    * Video players where the controls appear on mouseover and hide otherwise. (This seems to be the norm, in fact. Whereas a click on the same video does something different: usually Pause. Try Hulu for instance.)

    * Games where you steer with the mouse without clicking (extremely common).

    * Menus that popup up subpage links when you mouse over a main button, vs. going directly to a main category page when you click.
    ....

    He claims all the alternatives are unsatisfactory, e.g. re-coding every application manually, introducing gestures, substituting double-clicking for clicking and clicking for mouseovers.

    The issues are relevant to Javascript developers; for example, PPK has previously speculated on the demise of mouse* events, as well as hover in touch environments. How will that play out with a web app that relies on them?

    It's a bit like Dion's recent tweet: "I find myself typing click^H^H^H^H^Htap 20 times a day at the moment. Is there a term that abstractly could mean both? :)". We can get away with simple substitutions with straightforward web apps maybe, but it gets a lot more complicated with seriously rich interaction styles, the kind traditionally seen in some Flash games and now possible with Javascript. We tend to think of mobile device design as a matter of massaging the look with some CSS...the harder part to get right is often the "feel" in the look-and-feel equation. Platforms, like the web, which want to support multiple interaction styles, need to provide ways to ease the transition for developers, automating degradation and enhancement in the first instance, but allowing application designers to customise further for each device. Dan Saffer's sideshow below makes the point well, regarding gesture design in touch devices:

    Posted by Michael Mahemoff at 2:35 am 14 Comments

    Tuesday, February 9th, 2010

    Think You Know Javascript? Try this Quiz!

    Category: JavaScript

    If you know you think you know your objects from your arrays and your null from your undefined, here's a quiz for you from Perfection Kills.

    I was recently reminded about Dmitry Baranovsky’s Javascript test, when N. Zakas answered and explained it in a blog post. First time I saw those questions explained was by Richard Cornford in comp.lang.javascript, although not as thoroughly as by Nicholas.

    I decided to come up with my own little quiz. I wanted to keep question not very obscure, practical, yet challenging. They would also cover wider range of topics.

    There are fourteen questions in all, starting here:

        (function(){
          return typeof arguments;
        })();
    

  • “object”
  • “array”
  • “arguments”
  • “undefined”
  • Posted by Michael Mahemoff at 3:49 am 6 Comments

    Javascript ePub Readers

    Category: Showcase, eBooks

    republish2

    eBooks have gone mainstream, and right now the open ePub format is getting a lot of attention, being the iPad's book format of choice. Often overlooked in gadget-centric media is the fact that ePub is based on web standards, and therefore amenable to being rendered in the browser, sans plugins. Pure Javascript ePub readers are starting to crop up, and Keith Fahlgren has written about several of them:

    Just in the last few days, details emerged of two new JavaScript ePub readers, rePublish from Blaine Cook (@blaine) and JSEpub (screenshot) from August Lilleaas (@augustl). These two new readers join @liza’s epubjs, which will be a year old on Tuesday. An improved version of epubjs powers the ePub Zen Garden, which helps “dispel the myth that digital books can’t also be crafted works of visual design.”

    All are open source, and as Keith notes in the comments, there's also the commercial BookGlutton project. BookGlutton (which we covered earlier) shows the promise of browser-based eBooks: it lets you embed books as lightbox-powered widgets, and supports annotation.

    The underlying structure of ePub is described on wikipedia:

    EPUB consists of three specifications:
    Open Publication Structure (OPS) 2.0, contains the formatting of its content.[5]
    Open Packaging Format (OPF) 2.0, describes the structure of the .epub file in XML.[6]
    OEBPS Container Format (OCF) 1.0, collects all files as a ZIP archive.[7]
    Basically, EPUB internally uses XHTML or DTBook (an XML standard provided by the DAISY Consortium) to represent the text and structure of the content document, and a subset of CSS to provide layout and formatting. XML is used to create the document manifest, table of contents, and EPUB metadata. Finally, the files are bundled in a zip file as a packaging format.

    In the case of unzipping, Keith points out the inflate library has been around since 1999. One can imagine other applications for zip too; for example, it's often used as a format for bundling code (Java JARs, Python Eggs, Firefox and Chrome extensions), so reliable unzipping makes it possible to build browser-based IDEs and exploration tools against such archives.

    Posted by Michael Mahemoff at 3:34 am 1 Comment

    Wednesday, January 13th, 2010

    Gordon: Flash Runtime Implemented in Javascript

    Category: Flash, JavaScript

    This was quite a surprise! Tobias Schneider has built a Flash runtime that works right in the browser. It's implemented in pure Javascript and HTML5, and the whole thing is open source, MIT-licensed, and hosted on GitHub.

    See Gordon in action (demos hosted by Paul Irish).

    It works like a charm in recent versions of Firefox, Chrome, and Safari (and, yes, iPhone Safari, though the "blue" demo runs at tedious pace on my 3G). To install it yourself, use "git clone git://github.com/tobeytailor/gordon.git". I found the demos don't work from a file:/// URI due to the script dependency system, so point your web server at the root and point your browser at demos/.

    There's not yet any docs, so it's not clear how broadly compatible Gordon is or where it's headed. But if nothing else, it makes a bold statement about the maturity of open web technologies.

    HTML:
      <body onload="new Gordon.Movie('trip.swf', {id: 'stage', width: 500, height: 400})">
        <div id="stage"></div>
      </body>
     

    Gordon

    (Update: After much twitter love, someone finally figured out the name. How did we miss it?!!)

    Flash Gordon: Saviour?

    Update 2: There's a SWF tag support table and a browser support table. (thanks @tuxified)

    Posted by Michael Mahemoff at 3:38 pm 24 Comments

    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

    QBasic on Javascript

    Steve Hanov has been busy. Following from his hand-drawn canvas app, he's now built a working QBasic implementation powered by Canvas and Javascript and is blogging about how he did it.

    The most straightforward way of creating a basic compiler in javascript is to directly translate the basic into javascript functions. But this approach will not work for two reasons. First, there is "goto" which, although it is a reserved word, is not yet in Javascript. (Obviously, ECMAScript community finds "with", prototype inheritance, and the rules of the 'this' keyword to be far less confusing than allowing "goto"). It is possible to automatically move statements around to eliminate GOTO, but you don't want to go there.

    The other problem is that browsers tend to freeze until javascript programs finish running. To avoid freezing the browser until the program ends, we break the program into small chunks, and execute a few of those chunks every so often using a javascript timer. This gives the appearance of a running program and doesn't freeze the browser.

    Bytecode solves both of those problems. By breaking the program into bytecode instructions, we can implement goto by just changing which instruction we are going to execute next. We can also suspend execution any time to allow the user to interact with the browser.

    (thanks Shaun)

    Posted by Michael Mahemoff at 7:37 am 3 Comments

    Next Page »