Blog


Native JSON Support is Required

There's a JavaScript feature that I feel needs much more attention: Native JSON support in browsers.

It's something that should be a JavaScript language feature and yet no browser, or standards body, has defined, specified, or implemented what exactly it is, or should be. On top of this, it is one of the most (implicitly) requested language additions.

A recent ticket was opened for the Gecko engine, requesting a form of native JavaScript (de-)serialization whose API is based upon an implementation by Douglas Crockford. In effect, you'd be getting two additions to the JavaScript language: A .toJSONString() method on all objects (which will serialize that object to a string representation of itself) and a .parseJSON() method on all strings (which is responsible for deserializing a string representation of a JSON object).

I'd like to try and make the case for why I feel that native JSON support should standardized and made part of the JavaScript language.

1) The recommended implementation is considered harmful.

There are, currently, two popular means of transferring and deserializing JSON data. Each has their own advantages, and disadvantages. The two methods are:

  1. An implementation of JSON deserialization, by Douglas Crockford (which uses a JSON string, transferred using an XMLHttpRequest).
  2. And JSONP, which adds JavaScript markup around simple JSON data and is transferred (and deserialized) by injecting a <script> element into a document.

Currently, Crockford's json.js is the recommend means of deserializing JSON data. This has been discussed extensively elsewhere. Currently, json.js is better at keeping malicious code from being executed on the client (JSONP has no such protection), and thus, is recommend for most use cases.

However, json.js has taken two serious blows lately, which has moved it from being "recommend" to "harmful":

It's possible to covertly extract data from json.js-deserialized JSON data.

Joe Walker recently exposed a vulnerability which allows malicious users to covertly extract information from JSON strings that are deserialized using JavaScript's eval() statement. json.js currently makes use of eval(), making it vulnerable to this particular attack. This vulnerability has been discussed elsewhere too.

In order to fix this, json.js would need to use an alternative means of parsing and serializing the JSON-formatted string - a means that would considerably slower than the extremely-fast eval() statement.

It breaks the browser's native for..in method of iterating over object properties.

At this point, its pretty safe to say that that extending Object.prototype is considered harmful - and many users agree. Extending an Object's prototype is generally considered reasonable for personal situations, but for a publicly available, and highly recommended, script like json.js, it demands that it behave in a user-conscious manner.

Some attempts were recently made at cleaning up how json.js behaved, but thus far, no considerable effort has been made to provide an alternative means of deserializing JSON strings, that doesn't break a JavaScript engine's native behavior.

Summary: By adding support for JSON within a browser both of these issues will be completely circumvented (malicious users won't be able to extract data from a JSON structure, nor will the parseJSON and toJSONString methods be able to break for..in loops).

2) The recommend method of deserialization doesn't scale.

Let's start by looking at the two most popular methods of transferring JSON data (JSONP and an XMLHttpRequest transferring plain JSON), along with using an XMLHttpRequest to transfer some XML data (just for fun).

I've set up a series of tests that we can use to analyze the speed and efficiency of traditional JSON (using json.js), JSONP, and XML. I made 3 sets of files each containing a set of data records. As a base, I used some XML data from W3Schools. In the end, I came up with a total of 24 test files, each with a different number of records, in each specified format.

All of these get referenced from my mini test suites (one for each data type): JSON, JSONP, XML

These suites default to requesting the 50-record file 100 times, and taking an average reading. To get a reading on a different recordset, visit the file with the number of records in the URL, e.g.: json.html?400. Please don't run this on my server, it'll make it cry.

Instead, all of the test data and files can be downloaded here.

Note: I've only run these tests in Firefox, so caveat emptor.

Data Records by Time (in seconds)

Right off the bat, we can see two things:

  1. Transferring and de-serializing JSON data scales better than doing the same for equivalent XML data.
  2. JSONP scales better than the (more secure) XHR-requested, json.js-deserialized, JSON method.

Looking at the numbers for the recommended means of transferring JSON data, we don't get a full picture. Where are the scalability issues coming from? Maybe XMLHttpRequests don't scale so well? (Which would also help to explain the numbers for the XML transfers.)

To resolve this, let's break down the numbers for JSON into time spent processing and time spent transferring the data.

Data Records by Time (in seconds)

Here is where we see the major numbers come out. We can see that the processing time increases at a pace slightly less than O(n) time. This might be fine for most cases, however we can clearly see (from the previous chart) that JSONP is fully capable of faster parsing times.

Additionally, the processing time that json.js takes is completely blocking - no other operation is able to take place when the deserialization is taking place. When running the test suites you'll find that when the high (200-1600) record sets are processed your browser will stall (and if you're on a mac, you'll get the spinner of death). By passing this complete operation off to the browser you'll avoid all of these complications.

Summary By adding native JSON support within a browser you would have the blazing speed and scalability of JSONP, without adding any significant overhead.

Side Discussion:

In addition to studying the scalability of transferring JSON data, I've also looked at the overhead costs of pushing JSON data into an HTML structure (especially when compared to XML-formatted data).

Currently, some browsers have a native means of processing and converting XML data structures on the fly, using XSLT. XSLT is an incredibly powerful templating language and is more than capable of transforming any XML structure into an appropriate XHTML data structure.

However, for JSON data, no killer-templating system exists. I've used JSONT extensively but, in reality, it doesn't hold a candle to XSLT. (Both in terms of features and speed.)

I have two test suites one for JSONP + JSONT and another for XML + XSLT. You can download the full suite here.

Data Records by Time (in seconds)

You can see that, even with the extra speed advantages of JSONP, all of that lead is blown away by the incredibly slow nature of JSONT. Unfortunately, the situation isn't as clear-cut here as it was comparing JSONP and json.js, considering that JSONT is hardly a worthy replacement to XSLT.

Summary: In order for JSON to be, at all, competitive with XML/XSLT, there has to be a native means of transforming JSON data structures into strings (or DOM fragments), that can then be injected into an HTML document.

3) Upcoming standards imply its existance.

There are two upcoming standards that require some form of JavaScript object serialization (either explicitly, or implicitly).

The first, JSONRequest, (unsurprisingly, also from Douglas Crockford) is a means of securely transferring JSON data cross-domain. However, in order to implement this feature, some form of native JSON deserialization will be need to be implemented within the browser.

I know that Mozilla is considering implementing this feature, as is Microsoft, in Internet Explorer. Hopefully, this will mean that the two biggest browsers will have an implementation out quite soon.

The second is the new DOM Storage standard introduced by the WHATWG. While this feature does not require a form of JavaScript object serialization, it does only allow data to be stored as strings (and in order to make the most efficient use of that storage area, a form of object serialization will be needed).

However, the fact that two upcoming pseudo-standards need some form of object serialization requires us to re-examine the proposed API. It is imperative that it be rock-solid before being implemented in multiple platforms.

Here is the (rough) current API proposed by Crockford's json.js:

Object.prototype.toJSONString

var foo = { test: true, sample: "string" };
foo.toJSONString();
>> '{"test":true,"sample":"string"}'

Array.prototype.toJSONString

var foo = [ true, "string", 5 ];
foo.toJSONString();
>> '[true,"string",5]'

Boolean.prototype.toJSONString
String.prototype.toJSONString
Number.prototype.toJSONString

5.toJSONString();
>> '5'
"test".toJSONString();
>> '"test"'
true.toJSONString();
>> 'true'

However, there's still a lot of ambiguity in this particular API - especially when it comes to aspects of the language that aren't perfectly serializable.

Function and RegExp

Note that the parseJSON method (rightfully) balks at extracting a Function or a RegExp:

"function(){}".parseJSON();
ERROR: parseJSON: undefined
"/foo/".parseJSON();
ERROR: parseJSON: undefined

While it happily serializes either using toJSONString() (with varying results):

function test(){}
test.toJSONString()
>> "{"prototype":{}}"
/foo/.toJSONString()
>> "{}"

null

Also, note that while parsing a serialized 'null' gives you the correct value back:

"null".parseJSON()
>> null

it is unable to convert a null into its serialized form:

var foo = null;
foo.toJSONString()
ERROR: foo has no properties

A very important point needs to be made here: Some form of definition and specification should be made regarding this language addition. And soon. Even if it's nothing other than defining that the above behavior is correct - that should be specified somewhere for all browser developers to follow.

Summary: The current, recommended, implementation of JSON parsing and serialization is harmful and slow. Additionally, upcoming standards imply that a native JSON (de-)serializer already exists. Therefore, browsers should be seriously looking at defining a standard for native JSON support, and upon completion implement it quickly and broadly.

To get the ball rolling, I recommend that you vote up the Mozilla ticket on the implementation, to try and get some critical eyes looking at this feature, making sure that it's completely examined and thought through; and included in a browser as soon as possible.


Update: I located the specification that defines support for toJSONString/parseJSON in ECMAScript 4. This is great news. Now that the definition for this feature is happily moving along, it's just time to get some implementations going!

Tags: browsers, mozilla, xml, firefox, jsonp, javascript, json

JSON and RSS

I've been bit by the JSON bug. For a long time now, I've simply shrugged it off as 'Why not just use XML, it's parsable by most languages anyway.' However, once I started playing around with the del.icio.us JSON interface, then the Google Homepage API, and finally with the new Yahoo! JSON API - I realized that they were really on to something. The major benefits are immediately apparent:

  • It's incredibly lightweight - there's almost no extra markup, which keeps the data transfers nice and small.
  • There's very little overhead needed to parse it, since it's pure Javascript to begin with (and a number of other languages can either handle it as-is, or have a module to parse it).
  • and, probably most importantly, you can use it in a cross-domain environment. This exists due to the fact that you can execute remote Javascript (aka a JSON object), no matter what domain you're coming from. You can now completely skip the previously necessary (for XML) proxies.

So, this brings me to my first project using JSON - a fast RSS to JSON Convertor. You simply plug in the URL of the RSS (or Atom) feed that you wish to convert - and you'll have a nice, plyable JSON object to work with. I cache all retreived files every hour, to save on bandwidth, so please be aware of that. It also supports the addition of callbacks, making it easy to use in your program, right out of the box. If you're interested in seeing a demo, along with some sample code (and the code of the convertor), feel free to visit the project page.

The nice thing about having a RSS to JSON Convertor is that you can now convert any RSS source and play with it instantly - for example, your Google Search History, the Latest TV Listings, or even your POP Email Account. The possibilities are endless. I can't wait to play with this some more.

Tags: json, rss, javascript, programming, xml

XPath and CSS Selectors

Lately, I've been doing a lot of work building a parser for both XPath and CSS 3 - and I was amazed at just how similar they are, in some respects - but wholly different in others. For example, CSS is completely tuned to be used with HTML, with the use of #id (to get something by ID) and .class (to get something by its class). On the other hand, XPath has to ability to traverse back up the DOM tree with .. and test for existance with foo[bar] (foo has a bar element child). The biggest thing to realize is that CSS Selectors are, typically, very short - but woefully underpowered, when compared to XPath.

I thought it would be worth some merit to do a side-by-side comparison of the different syntaxes of the two selectors.

Goal CSS 3 XPath
All Elements * //*
All P Elements p //p
All Child Elements p > * //p/*
Element By ID #foo //*[@id='foo']
Element By Class .foo //*[contains(@class,'foo')] 1
Element With Attribute *[title] //*[@title]
First Child of All P p > *:first-child //p/*[0]
All P with an A child Not possible //p[a]
Next Element p + * //p/following-sibling::*[0]

Syntactically, I was surprised how similar the two selectors were, in some cases - especially between the '>' and '/' tokens. While they don't always mean the same thing (depending on what axis you're using in XPath), they're generally assumed to mean the child element of the parent. Also, the ' ' (space) and '//' both mean 'all descendants of the current element'. Finally, the '*' means 'all elements', regardless of their name, in both.

Even though I already knew all of this ahead of time - it's certainly nice being able to rediscover the similarities when it comes down actually having to program an implementation of them.



1 This isn't right due to the fact that it would match 'foobar' and 'foo bar', when only the second pattern is correct. The actual syntax would be far more complex and would probably require multiple expressions to get the job done.

Tags: xml, xpath, css, dom, html

Wanted: Javascript/Design Guru

I'm looking for a Javascript/Design Guru to help get some applications off the ground.

If you can look at Prototype (http://prototype.conio.net/) and say "That's cool, but I can do better!", or you can scoff at the designs on Stylegala (http://stylegala.com/) and CSS Vault (http://cssvault.com/) - then this job is for you!

Knowledge of the following is a must:
- Advanced Object Oriented Javascript
- Ajax (Asynchronous Javascript and XML)
- XHTML
- Advanced, Modern, Design Capabilities
- Advanced CSS

Big Plus:
- Adobe Illustrator
- Knowledge of Microformats
- Knowldge of Social Networks

If you are primarily Javascript OR Design-Oriented - let me know, as I may still have some work for you.

This job will be on a part-time/contract basis - most likely telecommuting. Pay will determined by your skill level and previous experience.

Apply for this Job Here OR email me.

Tags: illustrator, html, xml, xhtml, design, css, jobs, ajax, javascript, adobe

Data Grab Bag

  • In the new release of Google Earth, there's an exciting feature that lets you dynamically load geographical data in from other sources. They even have an markup language for it called KML. People have already started putting Flickr photos ontop of the maps.
  • On a similar note, if you have a Geotagged RSS feed that you want to put onto a Google Map, you should consider giving this utility a try.
  • The newer versions of Microsoft Word save their documents in an XML format. So it was only a matter of time before someone wrong an XSL template to generate these documents.
  • Do you have a lot of text that you want converted into speech? You should check out the say command on OS X.
  • Google now has built in currency conversion. I've been waiting for this for a long time, considering that you've been able to convert units of measurement and weight for the longest time, this step only seemed logical.
  • Interested to see how the moods of large-scale communites fluctuate over time? The Livejournal Mood Browser does just that, with informative graphs too!
  • What's better then a free textbook on Graph Theory? Not much!

Tags: graph, rss, osx, data, geo, theory, free, livejournal, xml, xslt, geotag, google, earth, kml

Schedule Maker Future

The other day I 'officially' launched a brand-new demo of the RIT Schedule Maker. In all, it's very very slick. It's a pure web application with zero server-side processing, all communication going straight from the user to the data source. Lots of Ajax, lots of XML - it's exciting. Doesn't work 100% yet in IE, but that's not my main concern, at the moment - my main concern was just getting something out for people to tinker with.

If you're interested in playing around with it, it isn't RIT exclusive, so feel free to hop on, plug in some courses, and see what happens. If that doesn't interest you, you can browse a collection of screenshots taken of the demo.

And now for the big news: I've made a big decision, this summer I will be putting all of my time towards launching the Schedule Maker and getting Juniper Bay (my company) off the ground. This is going to be a really big undertaking. By the end of the summer I will be launching a full-fledged scheduling application for use by students at a number of colleges and (hopefully) businesses. It will be completely free, have a complete API, you will be able to export your data into any known format, and will use all the greatest tech available in modern browsers. Once this quarter wraps up, I'm going to update the Juniper Bay web site, start a corporate blog going (detailing the advances that I make) and really get things moving.

Some things developers can look forward to:
- Completely open API and documentation
- (Pending) Open XML data set for external manipulation
- Lots of Open Source mini-projects (Ajax Authentication, Extensible REST API, screen-scraping scripts, etc.)
- Plenty of updates during the summer and upcoming months.

To say the least, the experience is going to be interesting. I will be working alone, doing all the planning, design, development, and customer support. Not that I haven't done anything like this before, but I just hope it works out. So, long story short, I'm really hoping for a lot of user input to get this off the ground. I'm going to be bouncing ideas through this web log and the (soon to exist) Juniper Bay one. Anyway, that's all for now, I'll keep everyone posted.

Tags: ajax, schedule, juniperbay, xml

Google Maps

Google released an interesting application the other day called Google Maps. Apart from the fact that it's very well designed and very easy to use, there's some fun stuff going on in the background that I really want to tinker with. More information concerning the actual tech behind the site can be found in this article.

One of my favorite commands back with Google Local was being able to search for '*' near a location, this would give you a list of results that are immediately close to you. The same thing has carried over to Google Maps, with one exception: The data is now semi-available in a easy to parse XML format. For example:

http://maps.google.com/maps?q=*+near+rochester,+ny&output=xml
will return a list of everything closest to the center of Rochester. And to make things even easier, you can use the URL:
http://maps.google.com/maps?q=*+near+rochester,+ny&output=js
to import the data straight into your web application. This is a very cool thing.

One of the features that I wanted to do with one of my projects a while back, Google Local Social Network (GLSN), was to provide results inline to the user - now it seems as if that's possible, in a big way. This is because another feature is available in XML format: Directions! Using just another form of the URL above you can get a nice, parseable, set of directions to navigate to your destination, for example:

http://maps.google.com/maps?q=buffalo,+ny+to+rochester,+ny&output=xml
I can't wait to play around with this some more, but whenever I get the time, GLSN is definitely due for an overhaul.

Tags: corp:google, maps, xml, xslt

Current Projects

jQuery JavaScript Library

jQuery

Comprehensive DOM, Event, Animation, and Ajax JavaScript Library.

Recent Projects

Pro JavaScript Techniques

JavaScript Book

The best techniques for professional JavaScript. Published by Apress.