Wednesday, September 10, 2014

A simple CSS page watermark

This is a very quick one about watermarking a generic website.

via CSS only

Add the following snippet to your CSS and adjust if you want custom properties.
html:after {

  /* common custom values */
  content: "© Water Mark"; /* your site name */
  font-size: 720%;         /* font size */
  color: rgba(0, 0, 0, .1);
  /* alpha, could be even rgba(0,0,0,.05) */

  /* rest of the logic */
  z-index: 9999;
  cursor: default;
  display: block;
  position: fixed;
  top: 33%;
  right: 0;
  bottom: 0;
  left: 15%;
  font-family: sans-serif;
  font-weight: bold;
  font-style: italic;
  text-align: center;
  line-height: 100%;

  /* not sure about who implemented what ..
    ... so bring it all */
  -webkit-pointer-events: none;
  -moz-pointer-events: none;
  -ms-pointer-events: none;
  -o-pointer-events: none;
  pointer-events: none;

  -webkit-transform: rotate(-45deg);
  -moz-transform: rotate(-45deg);
  -ms-transform: rotate(-45deg);
  -o-transform: rotate(-45deg);
  transform: rotate(-45deg);

  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
}

via restyle({}) at runtime

Place restyle.js in scope, then:
restyle({
  'html:after': {

    /* common custom values */
    content: '"© Water Mark"',  /* show what ? */
    fontSize: '720%',           /* how big ? */
    color: 'rgba(0, 0, 0, .1)', /* how visible ? */

    /* rest of the logic */
    zIndex: '9999',
    cursor: 'default',
    display: 'block',
    position: 'fixed',
    top: '33%',
    right: 0,
    bottom: 0,
    left: '15%',
    fontFamily: 'sans-serif',
    fontWeight: 'bold',
    fontStyle: 'italic',
    textAlign: 'center',
    lineHeight: '100%',
    pointerEvents: 'none',
    transform: 'rotate(-45deg)',
    userSelect: 'none'
  }
});
I've quickly tested this even on Google Maps and it worked like a charm and I don't know yet how many browsers will support this CSS approach but it seems that all modern browsers are just fine.
Enjoy

Sunday, August 17, 2014

Self contained Custom Elements via restyle()

There is an ongoing discussion about import link for both dependencies and Web Components, here my quick take on it: drop them! Just trash the fluff and use the DOM, it's freaking awesome these days and it works in every browser, you will rarely regret this choice!

However ...

Some dependency could be given for granted, which is actually the best we could do in order to simplify the mess (i.e. you use jQuery all over, don't include it in your file, assume it's there and mark it explicitly as must have in your component documentation).
Be sure that polyfills and/or dependencies are loaded upfront, which also means you should forget about async and other tricks if you want to rely these libraries are in.

restyle() and Custom Elements

Assuming this tiny library is in place, slightly more than just 1KB once minified and gzipped in its latest version, you might end up being able to confine the entire custom element behavior in just a javascript file. Have a look at this demo, based on same CSS and mostly same JS used in this post.
Yes, you got it right, custom elements are entirely confined in a single JS file.

A little helper for huge results!

The changes I've made in restyle are basically components oriented so that it's now possible to automatically confine some CSS inside a rule:
var style = restyle('my-element', {
  div: {
    border: '1px solid black'
  },
  i: {display: 'none'}
});

// will result in 
my-element div {
  border: 1px solid black;
}
my-element i {
  display: none;
}
Having somehow "sandboxed" all nodes also simplify the concept behind any Shadow Dom, except it works today with all browsers compatible with my document.registerElement and restyle code, basically all browsers you can think of except IE8 due Custom Element limits in this browser.

As Summary

Using little tools like restyle could give us the opportunity to use today Custom Elements without needing to wait a universally good, fast, and reliable solution via HTML5 imports combined with ES6 too, we can already place in a semantically similar way CSS into JS thanks to restyle and via JS also solve dependencies when appropriate. Feel free to play with the freshly new version of restyle and please don't hesitate to file bugs or suggest improvements: these are early days for Custom Elements and Web Components, this is the right time to nail it right!

Saturday, August 16, 2014

PointerEvents No More

It is stated and reasoned in this bug related comment that PointerEvents will not land in Blink, the Chrome/ium DOM related engine.
The brief summary, from the technical point of view, is the following:
  1. Touch events already demonstrated to work on the Mobile Web, no need to have more complex and, for mobile Web purpose, redundant API
  2. The hit-test model proposed by PointerEvents will penalize performance. Being such model not even available in Android or iOS it makes no sense to further penalize the Web against native.
  3. More complexity but less power, since it's not possible to intercept touch move while scrolling an element, being PointerEvents and scrolling mutually exclusive.
There are other reasons in the related thread and one of most important sentence, in my opinion, is summarized here:
The main shift in thinking for us has been from a position of a desktop-dominated web evolving slowly to enable mobile scenarios, to the realization that phones/tablets will soon dominate Internet usage and that the web is loosing to native mobile platforms.

Where PointerEvents failed

This is the most important argument against PointerEvents: touch capable Mobile Web has been around for 6+ years now and that Hardware still works properly with modern websites. Having 2 ways to end up dealing in the same exact way touch actions is redundant/duplicated code nobody wants to implement for a Mobile interface.

more complexity to do the same thing

If you have some experience with PoitnerEvents you know you ended up writing code like this:
// Handler => https://gist.github.com/WebReflection/9814013
// just a basic utility to simplify events managment
Handler.add(node, {
  // simulating touchstart and mousedown
  pointerdown: function (e) {
    if (e.pointerType == 'touch' ||
        e.pointerType == e.MSPOINTER_TYPE_TOUCH) {
      e.currentTarget.setPointerCapture(e.pointerId);
      e.preventDefault();
      // now prepare to move
    } else if(e.pointerType == 'mouse') {
      // mousedown, maybe start dragging?
    }
  },
  // simulating touchmove and mousemove
  pointermove: function (e) {
    if (e.pointerType == 'touch' ||
        e.pointerType == e.MSPOINTER_TYPE_TOUCH) {
      e.preventDefault();
      // do the touchmove like thing
    } else if(e.pointerType == 'mouse') {
      // mousemove, drag
    }
  },
  // simulating touchend
  pointerup: function (e) {
    if (e.pointerType == 'touch' ||
        e.pointerType == e.MSPOINTER_TYPE_TOUCH) {
      e.currentTarget.releasePointerCapture(e.pointerId);
      e.preventDefault();
      // clear state
    } else if(e.pointerType == 'mouse') {
      // mouseup, stop drag
    }
  },

  // for backward compatibility
  _fixed: function(e, method, pointerType) {
    e.setPointerCapture = e.msSetPointerCapture;
    return e;
  },
  MSPointerDown: function (e) {
    this.pointerdown(this._fixed(e));
  },
  MSPointerMove: function (e) {
    this.pointermove(this._fixed(e));
  },
  MSPointerUp: function (e) {
    this.pointerup(this._fixed(e));
  }
});
Not only we have coupled different meaning into a single stream of events, inevitably messing up readability and merging concerns because of different behaviors, but what we basically did on touch side is reflecting exactly this logic:
Handler.add(node, {
  touchstart: function (e) {
    // to also avoid dispatched mouse listeners
    e.preventDefault();
    // prepare to move
  },
  touchmove: function (e) {
    e.preventDefault();
    // do the touchmove thing
  },
  touchend: function (e) {
    e.preventDefault();
    // clear state
  }
});
If we want to also implement mouse events, how about doing in the universally compatible way we all know since 90s ?
Handler.add(node, {
  mousedown: function (e) {
    // prepare for dragging
  },
  mousemove: function (e) {
    // drag
  },
  mouseup: function (e) {
    // drop
  }
});
How cleaner is the code we all understand, write, and read compared with the PointerEvents counterpart?

no reliable polyfills

Despite the amount of attempts out there, setPointerCapture is implicitly invoked by default in every Touch based device. This basically means that unless that polyfill takes over the entire DOM interaction, killing performance already problematic even if implemented natively also due that hit-test target mentioned at the beginning, there is no way to have the exact same, default, behavior IE10 or IE11 implement.
This is not true the other way round, we can use PointerEvents to simulate Touch as shown before acting by default like them.
// demo only; don't use this code in prod!
Handler.add(node, {
  touchstart: function (e) {
    // prepare for move
  },
  touchmove: function (e) {
    // move
  },
  touchend: function (e) {
    // that's it
  },

  // use IE events to simulate touch
  pointerdown: function (e) {
    if (e.pointerType == 'touch') {
      e.currentTarget.setPointerCapture(e.pointerId);
      e.touchlist = [e];
      this.touchstart(e);
    }
  }

});
Luckily we don't have to take care about this mess, we should just use touch events that finally landed in IE11 Update 1 and eventually, if strictly necessary, we can put upfront a polyfill like ie-touch until all Windows Phone will get the update 1 installed (AFAIK this should happen around the end of August or beginning of September).

Tablet or Desktop ?

If we want to support special or different behaviors between touch and mouse we can simply split the logic and better organize it as shown before. Basically, instead of doing this per each bloody event:
node.addEventListener('pointerdown', function (e) {
  switch(e.pointerType) {
    case 'touch':
    case 'pen':
    case e.MSPOINTER_TYPE_TOUCH:
    case e.MSPOINTER_TYPE_PEN:
      // do touch things
      break;
    case 'mouse':
    case e.MSPOINTER_TYPE_MOUSE:
      // do mouse things
      break;
  }
});
We do this + that:
node.addEventListener('touchstart', function (e) {
  // finger or pen
});
node.addEventListener('mousedown', function (e) {
  // mouse indeed
});
This will also avoid O(n) checks multiplied by every input device event that will trigger on the browser.

So no "pen" anymore ?

I think pen is rather OK as touch device and it's in this event that I'd implement eventually pressure and angle for a simplified graceful enhancement over incompatible old systems that still will work as regular touch events.

Very different worlds

About Table VS Desktop there is another basic concept to consider: nobody drags with touch events, everyone drags with mouse. This is a fundamental split logic we should not underestimate. With touch screens we swipe, spread, pinch, tap, double tap, longpress to action while we right click instead or just point and click, or double click, with possible drag. Accordingly, The only event that has similar intent is click, irony wants that such event already works as expected with every device ... put in click what should have a click behavior, do not merge together any other gesture or intent into a single stream if you don't want to end up with spaghetti listeners hell.

In a nutshell

The initial idea behind PointerEvents was great but it was already showing how confined in an old mouse based world it was. Having all sort of events that might or might not be fired, just consider pointerover that won't happen the way we imagine if we touch the screen, was making the API itself inconsistent with developer expectations.
Moving the problem from a proper listener name, touch or mouse, into a pointerType event property hasn't solved a thing, hasn't worked as expected, hasn't improved performance, hasn't made the code easier to maintain or write ... it messed up listeners instead, adding extra complexity or unexpected default behaviors (i.e. the NON capture for touch events unshimmable as it is) where all we'll end up doing, as developers, is to simplify the logic down to what is possible already with Touch events.

This is Great!

I would like to underline that having specs like that and having played around even in production with those specs has been a great way to evaluate how nicely implemented, or how much troublesome, would these specs have been.
Seeing Microsoft recognizing it was important to support what devs wrote already and what mobile web is these days, bringing Touch events into IE11 Update 1, has been a very welcome and nice move we should all thank them about.
This is the web I like, where instead of silly pointless and endless discussions, we can go down to the concrete and not at all costs stubborn de-facto solution that everyone already used and is happy with and eventually change, or add, something documented and easy to use instead of playing "who's got the lauder voice".
Thanks to all people that helped with PointerEvents and their failure, now please let's make Touch and TouchList as cross platform as possible, including all micro gotchas with preventDefault and scrolling behaviors.

Thursday, August 14, 2014

Can we please stop moaning ?

OK here's the catch: software development is not something I do just for living, it's a passion I have since literarily ever and here's the story.
I'm absolutely envious of modern kids able to put their hands on a Raspberry PI, as example, and develop with Python, nodejs, or pretty much any other programming language available these days using an affordable board that does not need a music-cassette like player and at least half minute of potential personal epileptic attack with multi colors on screen plus noise before being able to show you something on the same screen (yes, I come from Commodore 64 era, a platform I couldn't afford at that time, and yet I feel lucky for owning a MSX and developing/experimenting on it via QBasic when I was between 8 and 11 ... then I've met by accident an Olivetti PC and it has been love since!).

Being greedy about learning!

When in 1998 I've finished high-school in Italy there was not a single University in the entire country that was even "10 years after" close to prepare people for real-world about the World Wide Web.
Those days, and bear in mind this is still the current situation in many "modern" Universities, Computer Science studies were only about some C, Java, or DBRM basics and nothing else; possibly even with an obsolete or deprecated versions of Java itself, nothing like nashorn these days, and just to shout one example.
All I could do in that scenario in order to prepare myself and learn about the Web, was to go online and study by my own everything available on the Internet!
All of this beside some unrelated University class that supposed to give me basis about programming (it kinda didn't for what I needed, it was too early to pretend to teach me Web in Italy at that time) ... guess what, I never completed that course or the one I've done few years after 'cause I was already ways ahead of them at that time.

However, I've been spending my career giving back to the Internet what I've learned contributing with Web specifications, ES specifications, creating libraries, or contributing to them ... this is me, online, today, and since ever!

.. and learning, and learning ...

Back in those days, every time I mastered some topic, another one was coming up harder to understand, harder to find proper online documentation, something we take for granted these days, and harder due concrete lack of time: I was a full time employee already and I needed to work because my studies were not cheap at all and internet was not cheap too, and in order to have a better connection I had to pay extra so that dual channel ISDN could have been possible and I could surf at the amazing speed of 128Kbps in download and 64Kbps in upload!
You read that right: 128 Kilobits per seconds, enough to also feel some sort of realtime zero-lag connection on Quake 3 Arena, a game part of my history too, and more than that, an inspiration about what's possible online even with very low bandwidth connections!
Anyway, my will to learn software and improve daily my skills was at its highest peaks, probably because it was the beginning of my career, most likely and also because it is still required, if you want to survive and be a good, updated, developer at any time in the SW history, to know what's going on around and where Software and Hardware are heading these days, your days, whenever you are reading this!
In few words Welcome to Software Development, nothing like you learn VBScript at Uni or at work once and you are good forever in your lifetime with your job ... if that's what were you looking for, I think I've bad news for you ...

Are *You* willing to learn ?

Apparently in modern software development, and somehow specially in one of the easiest out there, JavaScript development, the worst "curse" ever or the most used example about how hard is to be a software developer is represented by a tilde, a single ~ char apparently full of shame because developers don't understand what it means ... well, I don't want to start swearing randomly here, so I'll try to be calm and explain ...

As easy as this

The only possible falsy value in JS with a tilde, is the number -1 .. repeat with me:
the only falsy value with a tilde is -1
the only falsy value with a tilde is -1
the only falsy value with a tilde is -1

~(-1) === 0; // true
~(-1) == false; // true
Say that 3 times and Crockford will appear on the mirror!
Jokes a part, what does it mean? It simply means that every JavaScript method that returns -1 instead of a boolean false PHP style over a search, or an indexOf is performed over a string or an Array will result falsy when checked against the following:
if (~[1,2,3].indexOf(2)) {
  // YES, 2 is there!!!
  // because the result was !== -1
}

if (!~[1,2,3].indexOf(4)) {
  // NO, there's a NOT "!"
  // of course it's NOT there
  // !~ === NOT
  [1,2,3].push(4);
  // metaphorically speaking ... 
}
This is also usually called a semantic operation for the simple reason that:
  • you didn't put a not "!" operator upfront so you expect that to return truthy result
  • in case you did put a not "!" operator upfront, you'll see 99% of the time a arr.push(missingValue) following ...
so what are you exactly complaining about? The funniest thing ever is that people usually ask you to write this instead:
// they tell you not to write this:
if (~[1,2,3].indexOf(2)) {
  // yeah, it's there
}

// but to write this:
if ([1,2,3].indexOf(2) !== -1) {
  // yeah, it's there
}
Today you must have realized that comparing against !== -1 is the exact equivalent of verifying that the result was not -1 via tilde, because once again: only -1 is falsy after a tilde so indexOf result is truthy only when it's !== -1!

And this is not about being smart

It's rather about learning that some language does not use only +, -, *, and / operators as they taught us at elementary school ... the language has more and you should know more about the language you develop and work with instead of going "I don't understand! OMG, why is that and what it does" first time you see a different operator ... long story short: are you still willing to learn?
'cause next thing you gonna have problems with wil most likely be the proposed power operator, for all those times you didn't want to use Math.pow(num, radix) and you'll find handy to do x**radix instead ... uh wait, you don't know that symbol, it must be evil and/or smart, right?
What are you saying? Python did that before so it's OK? Then you learned something new anyway about the tilde today and in JavaScript, you should actually be happy if that's the case instead of moaning about it?

Not only the tilde

I've been working for many small, medium, and big companies, and the constant scenario is that someone, at some point, will mention sentences like the following one:
I had a problem and I decided to use regular expressions to solve it, so now I have two problems ...
... of course you have two problems if you don't understand regular expressions or you didn't think enough if that was the right case to use them ... here the simple proof: do this in a more efficient way (didn't mention easier, shorter, faster for argument sake but you know it):
function dropA(str) {
  return str.replace(/a/ig, '');
}

// later on in dante.js ...
dropA(divineComedy);
I am waiting here to see how better, faster, shorter, etc plus absolutely not error prone your logic avoided regular expressions ...

Master them instead

Yes, some dev probably does not know, need, or understand, regular expressions, and this is OK, as long as they are not trying at all costs to avoid them!
That would be the most unproductive, error prone, slower, and stubborn approach for a single or a team in case they do not just understand regular expressions ... I mean: no fucking body understand them after born, we all had to learn them so you can continue with your argument about "having two problems" but actually unless you really know regexp you should be the last one to complain about them.

back to tilde

Yes, if you are that good that not only you managed to successfully copy and paste some code that used a tilde but you actually investigated about its meaning in binary terms, you'll also realize that when an Array might contain a huge number of items that could grow unexpectedly, tilde is not what you are looking for *but* only in that case, even if we all like to dream our code will be used up to Math.pow(2, 32) times per each Array we create.

Long story short, if this is your problem, you are actually lucky you never had to deal with WebGL so far, because trust me tilde it's going to be the very last thing you could complain about if all this is about "things you just don't understand"! ( GLES wizardry! )

About the "copy and paste" tribe

Many times I've seen people demanding, complaining, insulting, after some code they copied and pasted from Stack Overflow or any other slightly CS related forum ... I wish we could consider these kind of persons outside the actual Software Developer circle and happily ignore them instead of promoting "write dumb to rule them all" articles all over?
How about we keep promoting Software for everyone to jump in and start ignoring or ditching people that are indirectly ruining this beautiful sector full of research, sometimes sacrifices, and luckily still most of the time: passion?

About daily tasks

When it comes to code reviews and developers that actually know what are doing, I also suggest to go easy with nitpicks because I've realized in my career nitpicks are so light and pointless in a product lifecycle that could only waste time for the product growth instead of actually helping code quality.
As example, if a Senior SW Engineer in your team writes:
if (!worked) return;
instead of:
if (!worked) {
    return;
}
without the JShint even complaining, that is fine and you should probably think about how many minutes, or hours, these silly things, when everyone absolutely understand in first place what's going on with the code, have been wasted just to nitpick stuff that for new comers, might actually be a chance to better learn what they are doing, instead of letting them think brackets solved the world ... of course they did when no tests were in place, if that's your only argument because something bad unrelated with brackets happened before :P

As summary

Please respect SW Developers and, if you consider that your job, respect yourself too.
So please let's all moaning less about basic SW Development concepts ... let's all talk about how to improve what's working already instead of how to welcome new copy and paste people.


Thank You!

Sunday, August 10, 2014

Auto instance via "use strict"

This is a very simple trick that works if you are sure your minifier will not remove any 'use strict' declarations in your scripts.

As seen in jQuery

This library is the most known/common example where $(something) will actually generate an instanceof jQuery variable even without using new.

Some background

Since basically ever, JavaScript constructors such Array, Object, Function and RegExp do not distinguish between new Array/Object/Function/RegExp or just the same without new, and there are exceptions for Date, where it always returns the same instance if invoked without new, and primitives wrappers such Boolean, Number, or String, where the meaning is very different: it's casting VS value wrapper when new is used.
This behavior could be somehow desired when we'd like to obtain the exact same return type when a generic constructor is invoked either via new or not.

Handy "use strict"

Because of its guard against the execution context, where this would be undefined instead of the global window object, we can use such behavior to simplify the famous pattern.
// basic use strict feature
function Constructor() {'use strict';
  return this || new Constructor;
}
This is basically the easiest way to replicate this pre-use-strict era pattern:
function Constructor() {
  return this instanceof Constructor ?
    this : new Constructor
  ;
}
The benchmark shows no impact on Safari, but quite a gap between the old and the new pattern in Chrome. Good news is, who cares, the trick is to write less and reduce code size so if it's even faster, it's just a strawberry on top.

A different behavior

In case somebody will use Constructor.call(anotherObject) the instance will be used inside the constructor instead of being ignored via good old pattern.
This is actually not necessarily an undesired side effect because it actually lets us reuse constructors to initialize properties with mixins too, in case the initializzation is needed.
// old pattern ...
function Constructor(value) {
  if (!(this instanceof Constructor)) {
    return new Constructor(value);
  }
  this.property = value;
}

// later on ...
var mixedObject = {};
Constructor.call(mixedObject, 123);
mixedObject.property; // undefined
Using initial pattern we basically do nothing except creating a new instance that will be lost in the process while with the pattern suggested via use strict things play nicer than before!
// use strict
function Constructor(value) {'use strict';
  if (!this) return new Constructor(value);
  this.property = value;
}

// later on ...
var mixedObject = {};
Constructor.call(mixedObject, 123);
mixedObject.property; // 123 <=== yeah!

No backward compatible!

As easy as that, in order to be able to use this pattern the engine must be compatible with use strict directive, which is actually not a big deal in nodejs or other modern server side engines, as well as most common browsers targeted for mobile apps or extensions.
In case you don't know about some target, do you remember the trick to know if the JS engine is compatible?
var hasUseStrict = (function(){'use strict';return!this}());
Please note that use strict brings other features too so be sure other behaviors won't affect your code logic.

Wait ... what about arguments?

There are two scenarios here, the one when it does not matter:
// use strict
function Constructor(a, b, c) {'use strict';
  if (!this) return new Constructor(a, b, c);
  // go on ... 
}
and the one where exact number of arguments matter:
// use strict
function Constructor(a, b, c) {'use strict';
  if (!this) {
    return Constructor.apply(
      Object.create(Constructor.prototype),
      arguments
    );
  }
  // go on ... 
}
Take care

Tuesday, July 15, 2014

A W3C Custom Elements Alternative

This W3C specification is awesome, and if you follow Alex Russell you know this has been probably his biggest obsession for years now: custom Web components, something even Internet Explorer 5.5 had, thanks to its Element Behaviors capability!

Many Articles, Poor Support :-(

Regardless the amount of articles about Web Components and a dedicated website for Custom Elements, browsers capable of supporting them natively are ... well, most likely none of them, specially on Mobile world.
This has at least 2 side effects:
  1. delayed adoption and/or interest from developers
  2. need for performant, not obtrusive, and reliable polyfills
Unfortunately, today there's no such thing ... like a plural of choices, and even Mozilla x-tag project, when it comes to Custom Elements, is based on the only polyfill you can find out there, the one proposed by Polymer framework ... however ...

Polymer Is NOT Standard .

Every developer I've talked about Custom Elements replied some how like "yeah, Polymer, I've heard about it ..." ... well, the bad news is that if you think about Polymer you have no idea about the proposed standard.
True is that the entire Web Components and Custom Elements "affair" comes from Google, and in the Custom Elements case, Dimitri Glazkov, a very nice dev that already helped me with few hints, is the main specs editor.

The Misleading Piece

Unfortunately most web articles about Web Components and Custom Elements end up talking or pointing at Polymer platform but this is indeed a platform a part, same as X-Tag, Ember or Angular would be, it's not the standard itself!
As result, most example you can read online are not exactly what W3C is proposing, rather what Polymer platform provides!
Also bear in mind, Custom Elements does not mean Web Components, the proposal is huge and we should rather learn more and be able to distinguish between these standards.

Custom Elements As In Polymer

The provided polyfill is a very nice piece of code, well documented, I believe well tested, but unfortunately incomplete.
As example, if you follow its building instructions you will end up requiring an extra MutationObservers polyfill that as first line assumes you are in ES6 and the WeakMap constructor is available.
The amount of code required to provide a proper WeakMap polyfill in engines where WeakMap is not supported results into an overbloated, probably unnecessary, and not so welcome entire new library to the plate ...
... and then there are web developers that actually care about code size and compatibility with not that old browsers too ... not willing to bring 2 third parts libraries in order to better support this brand new API ...

A Lightweight Alternative

During last week I've had a chance to experiment with some sort of cross domain Custom Element and I won't bother you with details since I'd like to share instead the library that only today I've managed to organize in a repository and test with all devices and browsers I could: let me introduce you my W3C Custom Elements Polyfill, and these are few features:
  • less than 2KB minified and gzipped without extra dependencies, you serve this file, you have it!
  • a wide range of old to modern mobile devices support ... iOS 5 and Android 2 are only few of them, IE9 for Windows Phone 7 made it too together with webOS 2!
  • focus on one task ... and while this sounds obvious, I don't think to use Custom Elements we need a proper, partial, cross browser fix for both MutationObservers and WeakMap ... but good news is, if you have already a patch for MutationObservers these will be used instead of old Mutation events API: it's a win-win!

Try It Yourself!

Not only you can test it directly, you can also read most famous articles and experiment just including the single file.

As usual, contributions are welcome, and I'll put your name in the MIT license too, no CLA required ;-)

Monday, June 30, 2014

On Meaningful Performance

This post is a complementary write up about my WebPerfDays talk given at Google HQ last Friday.

Slides And More

During the talk I've live demoed an Arduino Yun board and its performance and I've also showed through a documents camera live performance tests on a wide range of devices including:
  • Android 2.3
  • Bada OS
  • Blackberry 10
  • first ZTE FirefoxOS phone
  • Windows Phone 8
  • ... probably others too ...
While it's easy for me to point at those slides, you'll miss most of the live demoing content so here a better walk through.

Embedded Systems Performance

While Intel's Edison can be considered just a promise, there is already a huge variety of boards based on Atheros AR9331 board which is a single core MIPS architecture based System on a module @ 400MHz almost as small as the promised Edison.
Arduino Yun is only one of those boards featuring such beauty, and here something interesting about performance.

nodejs and npm work but npm is freaking slow

I've also opened a ticket about this non critical issue but the long story short is that npm --version or just npm --info take more than 7 seconds to show anything at all plus if you don't disable node flags npm will crash/fail to install anything with the global flag.
The lesson here in a nutshell: if your program is capable of smaller tasks, isolate these and make these executable/available a part instead of putting any software behavior after loading, parsing, and analyzing the entire logic. --version, as example, is not even something to even think about. Make basic operations available ASAP and lazy load complex operations and related logic only when needed.

nodejs FileSystem can go faster

It does not matter if node fs is asynchronous and non blocking, it still ensures somehow atomic reads and writes and its performance are usually based on assumptions that today Hard Drives have a lot of cache, are very fast ... etc etc ... then you face embedded:

SD cards are actually pretty fast but if you have concurrent reads you won't have any cache to take advantage.
Little tricks like those used in some fspeed experimental module might help to reach better concurrent performance without needing much more RAM or CPU power from the tiny board.

nody little server

The entire talk has been live demoed over my Arduino Yun and nodejs running nody, a tiny little server focused on doing one thing: serving (little) files if presents to as many clients as possible.
nody handled up to 20 devices at the same time, asking for same or different content, without a glitch.
The project with same name already exists in npm so I might think about a new name and make it a proper package ideal for embedded systems. It's KISS and YAGNI at its best so far :-)

Mobile Web Has Embedded Performance

It would be so simple if everyone had the latest iPhone or latest Android Hardware available, unfortunately the reality is way different and specially in emerging markets where cheap phones are the target to reach.

2010 Best Practice still valid

Everything I could do to make this map experiment move smooth even on Bada or Android 2 phones is still valid these days:
  • you might want to degrade to 30 FPS instead of 60 and go smoother in older HW
  • you don't want to cache all the things because you have a limited amount of RAM
  • you might even prefer canvas to draw tiles instead of CSS because canvas is a single surface to upload and draw, CSS squares can be many impacting FPS smoothness/linearity

Benchmark For Real

The Tesla Experiment is a good benchmark to see how good is the GPU, if used at all, the CPU that will calculate all lightning, and how many touch input we can have on a single screen. A cheap old Bada OS perform actually very well in there, why aren't we targeting these devices too?

Do Not Polyfill Old Hardware!

When you realize that simply touch or mouse move events are very heavy and triggered like 15 times per second in old Androids phones, you must be think again why on earth you would use touch events to simulate Microsoft Pointer Events, a kind of event that also won't bring us much on touch devices ...
Windows 8 and WP 8 Phones have a very good hardware and the cheapest WP8 phone you can try will trigger at 60FPS any simulated touch event ... deal with it Microsoft, we need to support old Android and other browsers with its old Hardware underneath, you are the only out there without Touch Events support ... please fix this!

The power of Touch events

Using just W3C Touch Events interface we can create interesting logic for our Web Apps like this 54 cards deck or some horizontal snapped scroll (the second one with the 2 inside, try to move it horizontally).
In order to create these little demoes:
  • ie-touch which is the simple drop-in able to make WP phones react to touch events
  • dom4 to bring common new DOM Level 4 entries tested and normalized for probably the widest variety of mobile phones and OS of the last 5 years
  • ScrollHandler to understand user gestures
  • SimpleKinetic to calculate asynchronously directions and movements through deltas

Performance That Matter For Real

As mentioned during my talk, if you are still using jsperf to benchmark ++i VS i++ you really have no idea what is the problem in your app ... focus on real bottlenecks and try to avoid holding on RAM all that data, all that DOM, all those images, etc etc ... use storages, cache callbacks instead of entire network or i/o results, find the problem and solve it reasonably.
Last, but not least, spend few bucks for some cheap second hand phone and use it for tests: if it will go reasonably well in that hardware, it will FLY in any other modern browser! Don't trust your emulator when it comes to real raw performance.

Get ready for the future: it will not necessarily be more performant, rather smaller, using less power, and everywhere, as the Internet Of Things is already these days!