Jaxer has been out in beta for a while and is nearing its 1.0 release. Many comments on Ajaxian about Jaxer have been about performance benchmarks. Uri Sarid, CTO of Aptana, has compiled some initial benchmarks including comparisons to PHP and Ruby on Rails. (Jaxer comes out in between the two):
We wanted to answer a simple question: how does Jaxer, with its server-side DOM and JavaScript, perform relative to these other popular alternatives?
This was not designed to be an all-encompassing shoot-out, or a detailed study of everything you might want to do in a web app. Instead, we took a few common tasks — making database requests, using JSON, etc. — and implemented them as you might expect in the three platforms. We made enough DB requests and JSON calls and so on to give us a reasonable number of milliseconds to measure. But we also wanted to make the repetitions representative of what you might find on somewhat intensive real-world page, so we’re not making a million DB requests, just a hundred, for instance. And we included one benchmark of serving an almost-static page: the “almost” was to make sure we were measuring the time the platform took to really read through the page, in case it had dynamic content in it. (Otherwise, if the page were truly static, you could always arrange for the web server to serve it without involving the platform.)
The tests include page scraping tests (e.g. mashup work), database performance, file I/O, JSON, and programatical loops.
The form attribute on various elements, which associates an element with its parent form, and the elements attribute of the form element, which associates the form with its elements. (Form-associated elements no longer need to be children of the <form> element itself within the DOM, so explicit association is required. Form-associated elements that are DOM children of the <form> element are implicitly associated, so your existing markup will continue to work the way you think it does.) [r2157]
Dean Edwards, Brendan Eich, Christian Heillmann, Jake Archibald, Joe Walker (chair)
I've captured at least some of what was said here ;).
What is the Open Web to you and why is it important (or otherwise)?
(general agreement that it's good thing, as we'd expect :)
Christian - What if open formats don't have the reach? e.g. ogg vorbis.
One JS file can't depend on another without wrapping all the code in a function. How should this be solved? An "include" function in ES4?
Brendan - "include" could make UI lock up. Can do it with (html 5) web workers (speculative parsing).
Should you pick just one library/framewrk to use, a handful, or have an open policy to use anything at any time? How do you evaluate which one(s) to use?
Christian - would be good to see comparison sites like cmsmatrix.org, not just which one is 20 milliseconds faster than the other. (MM - I tried to create something like this, but it could be bigger in both dimensions.)
Discussion about the "glow" library created by BBC, discussed by Jake Archibald yesterday. Okay to release unpolished product to open source as an individual or small company, but harder when it carries the name of a big organisation like BBC.
What kind of build scripts/engines do you recommend to concatenate multiple scripts into one?
Jokes about copy-paste and batch scripts.
Christian - It's 2008 - we should be using minifier, etc. More structured approach to releasing.
What recent tools or techniques do you use to speed up or improve your development process? Do you have any quick tips?
Jake - More developers :) HTML editor - Komodo edit. Debug - Firebug in FF, Developer toolbar and windows script debugger in IE
Christian - Moving to a Mac made developing far better, and partly due to Textmate. And Javascript bundle that runs JSLint over your code. Firebug.
Brendan - Distributed version control systems have been good. Textmate's good, but I'm an old Vi/Unix hacker.
Dean - Recently disabled Firebug to speed up development - causes bugs, reports misleading line numbers, etc. Went back to error console which gives you the correct line number. (Joe - it's getting better now.) Microsoft script debugger is actually quite good.
Christian - Firefox still the coolest browser for developers, but with all the tools, have to keep turning off greasemonkey scripts etc.
Does Cappucino / Objective-J have a future? What are their benefits and detriments?
Dean - More problems in the browser
Brendan - GWT guys are realists, acknowledge their abstractions leak. But OTOH they've made Ajax development accessible to Java developers who otherwise wouldn't do it.
Brendan (asked about what he'd do if he could change the language in the browser) - You'd get a lot of demand for Python and Ruby, Python's probably the more mature.
Brendan - Flex originally intended to make web app development like windows development. (Questions this approach). Pity we don't have things like JQuery for desktop apps.
What's the biggest missing bit of functionality from modern web browsers?
Christan - Big problem is we're stuck with old browsers.
Jake - Large companies lock down IE6.
Poll of audience - many people work for companies where the average user still runs IE6.
How to prevent? 37signals, Apple, Facebook have all written apps that don't target IE6. Christian-mainstream media could help, e.g. recent article saying users rarely get viruses via FF. Facebook also recommends FF and Safari along with IE.
Christian - Chrome is targeted at regular users, not developers - so IE market share might reduce. Brendan - Chrome might, good if they do, but difficult to see how to make a major change.
Jake - Apple get away with a lot of evil that if MS did the same thing they would be beaten for. e.g. Apple ships with a browser, just like MS.
Back to the question - what would you want:
Dean - standardised behaviour extensions for CSS
Jake - constants in CSS
Joe - vector graphics engine - canvas everywhere
Christian - web forms - e.g. calendar control
Jake - CSS - multiple background images
Christian - better layout (discussing boxes and vertical centering). Right now, we're as hacky as we were with tables.
Christian - better video and audio support (Jake - Flash alrady does this well, would rather see effort spent on other things).
The main thing to worry about is users injecting Javascript - cross-site scripting (XSS). Other vulerabilities people used to talk about - trusting user input and checking for SQL injection attacks - are boring/easy.
If I have an XSS hole, I can steal your users' cookies and log in as them, show a fake phishing page, embed malware, etc. And any service your site provides, I can perform it as if I was one of your users.
Reflected XSS - I embed my JS in a link to your site and trick your user to follow it.
Persistent XSS - I get my XSS onto your site's database (e.g. by adding it to a forum).
Examples of XSS from facebook, youtube, google groups, live search. See xssed.com - sites that were xss'd.
Preventing XSS
Use a tool that escapes everything on output. Better than escaping on input because you miss out on stuff.
IE8 has an XSS filter - if scary Javascript in the URL matches that in the page, it's blocked. But as developers, we have to assume older/other browsers.
httpOnly cookies also not so useful because many attacks don't rely on attacker seeing cookie.
HTML sanitisation. MySpace and LiveJournal have tried to do it and been XSS'd (samy is my hero). Must be really careful because many libraries have at least one hole. UTF-7 hole which Google's 404 page suffered.
CSS is also vulnerable. HTC in IE and XBL in Mozilla - both vectors for Javascript attacks.
Cross-site Request Forgery (CSRF)
Happens if you have unRESTful links. app.example.com/delete.php?id=1 But what if you're RESTful and use POSTs, are you safe? No. Page B can present you with a form that submits to Page A. The form doesn't even have to be visible - hide it and write some Javascript to submit the form when the user loads the page. Was used to get users to silently digg the page you're on. Worse, was used in GMail to set filters so mail would be redirect to the evil guys.
To prevent CSRF:
- Could check HTTP Referrer, but that's notoriously unreliable. e.g. there are virus protectors that strip the outgoing referrer headers, as well as FF extensions etc.
So the bettter solution it to embed crumbs (tokens). Embed an impossible-to-guess crumb in the form, and check the crumb each time you accept the form. Crumb is specific to the user and could be a cookie value, in the simplest case. Ideally, on every request and living for a short time (e.g. one hour). Must ensure crumb doesn't leak.
Another solution with Ajax - X-Requested-By: XMLHttpRequest tells you its an XHR call, which means it came from the same domain. So if you see this, no need for the crumb check.
Plugins:
crossdomain.xml. Used by Flash to control which services can be acessed. There are various tricks will bypass it.
The PDF hole. Jan 2007 - turned out Adobe PDF readers could execute any Javascript. So Yahoo! employees for example were told to delete every PDF on the server - because having any PDF file made the whole site vulnerable.
Google Contacts exposed contact data as JSON. If malicious pages makes a JSON call for that data, and you're logged in, it will get your contact info.
But even regular JSON is vulnerable. Possible to redefine array constructor so that when JSON arrives in the browser, malicious code is executed. So JSON should look like: /* { "json" : "goes here" } */ to ensure it's not executed. (Joe Walker makes a comment at the end of the talk that it's safer to use while (true) or throw an exception - the JSON content itself might contain a closing "*/".)
Gears is also supported in applications that use WebKit such as Fluid, as stated:
ou can download it today from http://gears.google.com.
This means that you can now access all the Gears-enabled sites (such as Zoho office, WordPress, the new YouTube uploader and Google Docs offline) in Safari.
Since launch, we've increased the number of APIs available in Gears. The 0.3 release added the ability to create desktop shortcuts for websites, and the 0.4 release added Geolocation and Blobs (useful for resumable uploads of large files). All of these are now available in Safari and work exactly the same as on the other browsers Gears supports.
We thought it might be interesting to talk about some of the technical aspects of Gears peculiar to Safari and OS X. If you aren't a developer you can safely skip the following paragraphs and go straight to the download page.
When you install Gears, you'll notice that it's composed of 2 components: an NPAPI plugin which lives in "/Library/Internet Plugins" and an InputManager. Gears needs to load first thing upon browser startup, for cases in which the first page loaded into the browser is from the Gears offline cache. NPAPI provides no mechanism for loading that early (it only provides support for loading plugins the first time a page specifically includes them) so we needed a small InputManager to do the work for us.
For browsers other than Safari that use the WebKit engine, we've provided a really simple mechanism to allow them to load Gears into their program without using the InputManager. Fluid is one example of a 3rd party browser that supports Gears this way.
On the Mac, Gears desktop shortcuts are actually small applications that are designed to open the website in the same browser they were originally created from. This means that if you created them from a Fluid app they'll open in that same place and if you've got multiple versions of Firefox installed on your machine the shortcut will open in the right one.
I gave a talk at @media Ajax in London today, as Michael kindly wrote up. The presentation is below:
And the follow up slide, showing that Stuart doesn't agree :)
He does go on to show issues with holding on to references and leaking memory, as well as many other details on closures. Clicking through presentations often doesn't give you much... but in this case I found it very interesting indeed.
Jeene is a new open source project by Karl Krukow, which aims to create a partial evaluator for JavaScript.
A partial evaluator (or program specializer) is a program which takes two inputs: another program and an environment mapping variables to values; it outputs a specialized (i.e., more efficient) version of the input program with respect to the environment. One can think of a partial evaluator as a mix between an interpreter and a compiler: it interprets the static parts of the program and emits code for the dynamic parts.
This last line, shows that the output function is much more efficient than what is created by general JavaScript curriers which have been seen before. These functions merely wait evaluating the function until all parameters are supplied; instead, a partial evaluator will create specialized function taking advantage of the information given.
Interested in what our friends are up to, even if no-one else cares (as twitter illustrates). And also interested in what systems/things are doing, not just people. Chat (meebo), collaborative editing (google docs), streaming financial data (lightstreamer), async updates (yes.com), online gaming, async server processing (polar rose, i.e. shift processing complexity to the server - note this could be seen as an alternative to Gears-style local processing in some situations).
The web was designed to be connectionless - Comet blatently aims to make it connected.
Performance
Actually does scale. Joe shows the following graph:
Technical
Seven ways (!) to implement Comet.
Long polling - "slow" XHR request. Server doesn't answer immediately. Special part of HTTP to do this - chunked mode. However, IE "lies to you" - keeps saying it's got something, but you can't actually inspect it.
Forever frame - Send text/plain and 4k whitespace to flush IE's buffer. Flush with script tag for each data block. Must keep restarting to avoid memory leak.
Script tags - Dynamic script blocks, can point to any domain.
WebSockets - HTML 5 standard. Cleaner solution.
ActiveXObject("htmlfile") - htmlfile is an activeX control similar to XHR. Normally causes "clicking" noise in browser, but there's a hack to turn it off in most cases. Obviously, this only works in IE. Most bizzare thing is you get 49 Javascript before garbage collection, leading to hair-pulling moments when you try to work out why your 50th command isn't executing!
Mime messaging - "What push was built on 11 years ago" - x-multipart-replace. Works really well, though with memory leakage issues, but not in IE and historically not in the other browsers either.
Flash remoting
Forever GIF (bonus technique) - keep sending out new slices of an animated GIF!
Technical Issues
Co-ordination when browser has multiple tabs open to the same server - using window.name or cookies, but better solution is multi-home DNS - each call points to the server using a different name (1.example.com, 2.example.com etc all pointing to the same IP address).
Issues detecting when browser or connection has broken.
Proxies which don't let the stream go through in real-time - hold on to the chunks for a while before releasing them all at once. Can detect if this is happening from the browser using a timestamp technique.
... so just like with Ajax, we have to come up with hacks, likewise with Comet. Facebook and GMail show it's possible to work around these problems and get Comet working at scale.
API Styles
e.g. with WebSocket you're simply posting and receiving data. Event handlers for onOpen, onRead etc. Joe says this will be too low-level in many cases, hence the following styles.
PubSub - e.g. cometd. Low coupling (server-browser separation - Joe describes demo where servers hot-swapped without affecting client), inter-language interop. Good analogy to SOAP, which has gradually shifted from RPC to document exchange.
API - this looks to me like Ruby's remote JS - server controls what's happening on the browser. e.g. Effect.shake("price") on the server will make the price div shake on the client.
Data Syc API - Keep changing/updating data store. Simplest to understand.
-moz-transform: translate(100px, 200px); /* Move right 100 pixels, down 200 pixels */
-moz-transform: translate(30px); /* Move down and right 30 pixels */
-moz-transform: translate(50%, 50%); /* Move down and right by 50% of the size of the element. */
This function simply moves elements around by the specified offset. For example, a text element with -moz-transform: translate(100px); will appear 100 pixels downward and to the right of where it normally would have been displayed. Of course, there are more functions than just translate. For example, there’s rotate, which lets you rotate an element by a specified number of degrees; scale, which scales elements by arbitrary dimensions along each axis; skew, which performs skews along the X and Y axes; and matrix, for arbitrary matrix transformations. There are also simple versions of these like skewx and scaley which allow for simpler syntax in some cases.
It will be interesting to see what uses developers find for CSS transforms. Much of the functionality once reserved for plugins can now be directly integrated into CSS and Javascript, which hopefully will help web developers create more graphically exciting pages. We also look forward to rapid standardization of this property now that there are two implementations.
Why Gears? Reliability, Performance, Convenience. There's a long tail of users who don't have permanent access. Furthermore, connectivity goes down everywhere - we want to keep working when that happens.
Gears philosophy. Can go to URL when offline and also be more useful when connected.
Dion explains the minimalist design philosophy. Small things - gears - that can be built up piecemeal - cf. the power of a small thing called XMLHttpRequest.
Local Server.
Database API. Led to GearsDB, GearsORM (e.g. Jooce)
Application - Buxfer. Instead of storing personal finance data on the server, since some wouldn't trust them, they gave people the option to store it locally via Gears.
Application - Digg Oracle.
Application - MySpace. Found it too resource-intensive to store chat history, so an engineer created a gears-powered local search feature in one day, and made it into production.
Application - Wordpress "speed up" feature. Caches aggressively on the desktop.
Workerpool API. Calculation demo - much more fluid when running with resource pool.
Geolocation API. Can choose different geo providers - IP
Desktop API. To get a desktop icon.
File System API. Better file uploader - get access to the files.
Blob API.
Resumable HTTP API.
Notification API. Growl for the browser.
Audio API. Playback and recording.
"Zipper model" - HTML 5 catching up to current features of Google. The idea being that Gears gets these features out much earlier so we can see how people like it and what people do with it. e.g. workerpool->HTML web workers. geolocation->W3C geolocation. Database -> HTML 5 local storage. Local server -> HTML 5 offline store. In most cases, the Gears developers are involved in the spec development.
- (from a question) Gears - get it out into as many different browsers. Chrome - push browsers to do many more things. Worth noting that even if nothing happened with Chrome, it would encourage browser developers to do more. Just like Android will push mobile platforms regardless of market share.
Matthias Georgi has posted the release of Patroon, his new templating system that uses JavaScript. It joins other solutions such as using Django via JavaScript (e.g. Dojo let's you do that), TrimPath, and more.
The way it works is simple. You setup the data that you will be able to access in the template: