While designing Babylon.js v2.0 (a library for building 3D on the web), I recently found myself wishing that more APIs were fluent—that is, I wish the community could more easily read, understand, and build upon the work while spending less time in the tech docs.
In this tutorial, I’ll walk through fluent APIs: what to consider, how to write them, and cross-browser performance implications.
What's a Fluent API?
A fluent API, as stated by this Wikipedia article, is an implementation of an object-oriented API that aims to provide for more readable code. JQuery is a great example of what a fluent API allows you to do:
$('<div></div>') .html("Fluent API are cool!") .addClass("header") .appendTo("body");
The fluent API lets you chain function calls by returning this object.
We can easily create a fluent API like this:
var MyClass = function(a) { this.a = a; } MyClass.prototype.foo = function(b) { // Do some complex work this.a += Math.cos(b); return this; }
As you can see, the trick
is just about returning the this
object (reference to current instance
in this case) to allow the chain to continue.
If you are not aware of how the “this” keyword works in JavaScript, I recommend reading this great article by Mike West.
We can then chain calls:
var obj = new MyClass(5); obj.foo(1).foo(2).foo(3);
Before trying to do the same with Babylon.js, I wanted to be sure that this would not generate some performance issues.
What About Performance?
So I did a benchmark!
var count = 10000000; var MyClass = function(a) { this.a = a; } MyClass.prototype.foo = function(b) { // Do some complex work this.a += Math.cos(b); return this; } MyClass.prototype.foo2 = function (b) { // Do some complex work this.a += Math.cos(b); } var start = new Date().getTime(); var obj = new MyClass(5); obj.foo(1).foo(2).foo(3); for (var index = 0; index < count; index++) { obj.foo(1).foo(2).foo(3); } var end = new Date().getTime(); var start2 = new Date().getTime(); var obj2 = new MyClass(5); for (var index = 0; index < count; index++) { obj2.foo2(1); obj2.foo2(2); obj2.foo2(3); } var end2 = new Date().getTime(); var div = document.getElementById("results"); div.innerHTML += obj.a + ": With return this: " + (end - start) + "ms<BR>"; div.innerHTML += obj2.a + ": Without return this: " + (end2 - start2) + "ms";
As
you can see, foo
and foo2
do exactly the same thing. The only
difference is that foo
can be chained whereas foo2
cannot.
Obviously the call chain is different between:
obj.foo(1).foo(2).foo(3);
and
obj2.foo2(1); obj2.foo2(2); obj2.foo2(3);
Given this code, I ran it on Chrome, Firefox and IE to determine whether I have to get concerned about performance.
And here are the results I got:
- On Chrome, the regular API is 6% slower than the fluent API.
- On Firefox, both APIs run at almost the same speed (the fluent API is 1% slower).
- On IE, both APIs run at almost the same speed (the fluent API is 2% slower).
The thing is that I added an operation into the function (Math.cos
) to
simulate some kind of treatment done by the function.
If I remove everything
and just keep the return
statement, on all browsers there is no
difference (actually just one or two milliseconds for 10,000,000 tries). You
can test this for yourself across the browsers. And if you don’t have the
devices handy, there are plenty of free tools on dev.modern.IE. Just don’t performance test a virtual machine
against a real device.
So my conclusion is: It’s
a go!
A fluent API is great—it produces more readable code, and you can use it without any problem or performance loss!
More Hands-On With JavaScript
It might surprise you a bit, but Microsoft has a bunch of free learning on many open-source JavaScript topics, and we’re on a mission to create a lot more with Microsoft Edge coming. Check out my own:
- Introduction to WebGL 3D with HTML5 and Babylon.JS
- Building a Single Page Application with ASP.NET and AngularJS
- Cutting Edge Graphics in HTML
Or our team’s learning series:
- Practical Performance Tips to Make your HTML/JavaScript Faster (a seven-part series from responsive design to casual games to performance optimization)
- The Modern Web Platform Jump Start (the fundamentals of HTML, CSS, and JavaScript)
- Developing Universal Windows App with HTML and JavaScript Jump Start (use the JS you’ve already created to build an app)
And some free tools: Visual Studio Community, Azure Trial, and cross-browser testing tools for Mac, Linux, or Windows.
This article is part of the web dev tech series from Microsoft. We’re excited to share Microsoft Edge and the new EdgeHTML rendering engine with you. Get free virtual machines or test remotely on your Mac, iOS, Android, or Windows device @ http://dev.modern.ie/.
Comments