Well, just in case you read RSS and you missed my tweet ... everything you need to know in github repository.
Have fun with Harmony Collections
behind the design
My JavaScript book is out!
Don't miss the opportunity to upgrade your beginner or average dev skills.
Showing posts with label browser. Show all posts
Showing posts with label browser. Show all posts
Wednesday, January 18, 2012
Sunday, January 15, 2012
Y U NO use libraries and add stuff
This is an early introduction to a project I have been thinking about for a while.
The project is already usable in github but the documentation is lacking all over the place so please be patient and I'll add everything necessary to understand and use yuno.
If we are using a generic JS loader, the aim is to simply download files and eventually wait for one or more dependency in order to be able to use everything we need.
The require logic introduced via node.js does not scale in the browser due synchronous nature of the method itself plus the sandbox not that easy to emulate in a browser environment.
The AMD concept is kinda OKish but once we load after dependencies, there is no way to implement a new one within the callback unless we are not exporting.
I find AMD approach surely the most convenient but still not the best one:
Specially the last point means that AMD does not scale properly with already combined code because AMD relies in the module/folder structure itself ... so, cannot we do anything better than what we have so far?

Directly out of a well known meme, yuno logic is quite straightforward:
Let's imagine that extraStuff contains similar code:
Both plugin and extraStuff needs jQuery to be executed ... will jQuery be loaded twice? Nope, it's simply part of a queue of modules that needs to be resolved.
As soon as it's loaded/added once, every module that depends on jQuery will be notified so that if the list of dependencies is fully loaded, the callback passed to and will be executed.
The yuno.add method reflects Object.defineProperty which means for ES5 compatible browsers getters, setters, and values, are all accepted and flagged as not enumerable, not writable, and not configurable by default.
Of course we can re-define this behavior but most likely this is what we need/want as default in any case ... isn't it?
For those browsers not there yet, the Object.defineProperty method is partially shimmed where __defineGetter/Setter__ or simply the value property will be used instead.
Bear in mind this shim may change accordingly with real needs but so far all mobile browsers should work as expected plus all Desktop browsers except IE less than 9 ... not so common targets for modern web sites.
Last, but not least, yuno logic does not necessarily need the add call so feel free to simply define your global object or your namespace the way you want.
However, as I have said before, the add method is a simple call able to make things more robust, to speedup and ensure notifications, and to use a standard, recognizable pattern, to define our own objects/functions being sure nobody did before thanks to defaults descriptor behavior which is not writable and not configurable indeed.
Last, but not least, the reason I am writing this is because I am personally not that happy with any solution we have out there so if you are willing to contribute, please just leave a comment, thanks.
The project is already usable in github but the documentation is lacking all over the place so please be patient and I'll add everything necessary to understand and use yuno.
Zero Stress Namespace And Dependencies Resolver
Let's face the reality: today there is still no standard way to include dependencies in a script.If we are using a generic JS loader, the aim is to simply download files and eventually wait for one or more dependency in order to be able to use everything we need.
The require logic introduced via node.js does not scale in the browser due synchronous nature of the method itself plus the sandbox not that easy to emulate in a browser environment.
The AMD concept is kinda OKish but once we load after dependencies, there is no way to implement a new one within the callback unless we are not exporting.
I find AMD approach surely the most convenient but still not the best one:
- we cannot implement a provide like procedure, whenever this could be handy or not
- it's not clear within the module code itself, what we are exporting exactly
Specially the last point means that AMD does not scale properly with already combined code because AMD relies in the module/folder structure itself ... so, cannot we do anything better than what we have so far?
The yuno Concept
Directly out of a well known meme, yuno logic is quite straightforward:
- automagically resolved path, you point once to yuno.js file in your page and you are ready to go
- compatible with already combined files (smart builder coming soon)
- yuno.use() semantic method to define dependencies, if necessary
- yuno.use().and() resolved callback to receive modules AMD style once everything has been loaded
- yuno.add() standard ES5 way to define new namespaces, objects, properties, or constructors ( so no extra note in the documentation is needed )
- cross referenced dependencies automagically resolved: if two different scripts needs same library, this will be loaded once for both
- external url compatible, because you may want to include a file from some known CDN rather than put all scripts in your own host ( speed up common libraries download across different libraries that depend on same core, e.g/ jQuery )
- modules, namespaces, or global objects, cannot be reassigned twice, which means if we are adding twice same thing we are doing it wrong, but if we are not aware of other script that added same thing before we have a notification
- something else I may decide to add after this post
// define a jQuery plugin
yuno.use(
"jQuery",
"extraStuff"
).and(function (jQuery, extraStuff) {
yuno.add(jQuery.fn, "myPlugin", {value:function () {
// your amazing code here
}});
// we may opt for just this line
jQuery.fn.myPlugin = function () {};
// in order to export our plugin
// however, the purpose of yuno is to have
// a common recognizable way to understand
// what the module is about
// plus the "add" method is safer
});
Let's imagine that extraStuff contains similar code:
// define extraStuff
yuno.use(
"jQuery"
).and(function (jQuery) {
yuno.add(jQuery.fn, "extraStuff", {value:function () {
// your amazing code here
}});
});
Both plugin and extraStuff needs jQuery to be executed ... will jQuery be loaded twice? Nope, it's simply part of a queue of modules that needs to be resolved.
As soon as it's loaded/added once, every module that depends on jQuery will be notified so that if the list of dependencies is fully loaded, the callback passed to and will be executed.
Y U NO Add
Modules are only one part of the proposal since we may define a script where no external dependency is needed.
// note: no external dependency, just add
yuno.add(this, "MyFreakingCoolConstructor", {value:
function MyFreakingCoolConstructor() {
// freaking cool stuff here
}
});
// this points to the global object so that ...
MyFreakingCoolConstructor.prototype.doStuff = function () {
// freaking cool method
};
The yuno.add method reflects Object.defineProperty which means for ES5 compatible browsers getters, setters, and values, are all accepted and flagged as not enumerable, not writable, and not configurable by default.
Of course we can re-define this behavior but most likely this is what we need/want as default in any case ... isn't it?
For those browsers not there yet, the Object.defineProperty method is partially shimmed where __defineGetter/Setter__ or simply the value property will be used instead.
Bear in mind this shim may change accordingly with real needs but so far all mobile browsers should work as expected plus all Desktop browsers except IE less than 9 ... not so common targets for modern web sites.
Last, but not least, yuno logic does not necessarily need the add call so feel free to simply define your global object or your namespace the way you want.
However, as I have said before, the add method is a simple call able to make things more robust, to speedup and ensure notifications, and to use a standard, recognizable pattern, to define our own objects/functions being sure nobody did before thanks to defaults descriptor behavior which is not writable and not configurable indeed.
To DOs
This is just an initial idea of what the yuno object is able to do but few things are in my mind. On top of the list we have the possibility to shortener CDN calls via prefixes such "cdn:jQuery", as example, in order to use most common CDNs to load widely shared libraries.Last, but not least, the reason I am writing this is because I am personally not that happy with any solution we have out there so if you are willing to contribute, please just leave a comment, thanks.
Friday, December 24, 2010
The Status of Mobile Browsing
In this year I have done more tests than ever over all these tiny and shiny portable devices and I'd like to share with the Web community the result of my experiments at the end of this 2010. "why not before xmas, ffs?" ... because whatever you bought as present for you or your relatives, will hopefully be updated soon with latest systems and related browsers :)
The classic trick to do this is to apply 3D transformation to the main container of our styled stuff:
Above technique could solve many headaches when a portion, or the whole body, looks fucked up ... give it a try but please note that GPU buffer will rarely support big images and these could cause a massive performances impact.
An ideal document size for mobile browsing should not reach more than 2~3000 pixels height ... considering a reasonable width, after that we could have problems.
Tricks a part, the horrible side effect of unsupported CSS features is that features detections are not really a solution ... "eye result" detection would be the way to go but it requires a pixel per pixel check.
The "eye result" detection is something I have invented right now as CSS check automation. We should have a snapshot of the container, saved as png, a snapshot created runtime from the rendered container, impossible with current DOM API, and two canvas elements in order to compare both image data ... where to speed up the process in JS world, we could simply compare the returned base64 encoded result of both snapshots as fast char-by-char (threaded as ints) match (e.g. "a" == "a").
This is fantasy right now, and it implicates complex, bandwidth greedy, operations I would never suggest ... but I am just saying ... that we should never trust the result we have on our desktop WebKit or another device WebKit based, we should always test results in target if we would like to avoid surprises.
Finally, messed up CSS could cause indirectly so many computation behind the scene we cannot even imagine ... until we discover the the whole interaction is compromised.
As example, those pages strongly styled in an unreasonable way through tons of overwritten or inherited CSS, in a deeply nested DOM, simply are unusable!
This is the reason 99% of common web libraries out there are obsolete when it comes to the massive amount of features detections these libraries use to understand the exact version of IE, Firefox, or Opera ... all this stuff is crap, is bandwidth unfriendly, and unnecessary.
A good library for mobile browsing is a library dedicated for mobile browsing ... where even features detections could cost time (slower CPUs) and where most of the time these features detection, specially those for edge cases, can be dropped in favour of the good old User Agent string.
Yes, you read correctly, features detections we know could simply fail in all these variants of WebKit based browsers.
Some device could expose hosted features that are not available, some other could not expose anything but still support what we are looking for ... there are many examples that caused me nightmares during my experiments and no simple solution.
The User Agent sniff sometimes is the best, cheap, fast, solution we could possibly adopt and it will rarely fail when it comes to mobile.
Last, but not least, faster WebKit implements V8 engine, the google diamond, but others may implement the classic JavaScriptCore, with or without "Extreme" acceleration.
I am counting seconds for the day Douglas Crockford JavaScript implementation of JSON will be redundant/superfluous, same as I am counting seconds until attachEvent will disappear from the Earth!
To know more about this problem, if interested, have a look.
Finally, and most important, setItem could fail once the storage reaches the memory limit which is not exposed (hopefully yet) through the API.
In few words we can have a nice Exception the moment we try to set an item, even the same, and the storage is "full".
To avoid problems, even if this is not a solution, use a bloody try catch block every time we need to set an item:
The limit I am talking about is around 2Mb but it may vary.
In this case the Web Database API provides a nice message automatically when the application tries to store more data than allowed, letting us being able to pass the limit specified at the beginning.
A good compromise is to set the initial storage value to 2 megabyte, maximum 5, and after that limit it will be the device able to allocate more space if necessary, adding other 2, up to 5, megabytes to curent database.
Rather than try catch mandatory blocks, we have callbacks for error handling but, right now, I have never been able to reproduce in a real scenario problems with the SQLite database size.
Not a big deal considering webworker are not widely supported yet ... but still bear in mind the CPU is "that one", you better learn better algo or JS practices to speed up things rather than delegate piece of massive stuff to computate on the background.
A tiny temporary block is, in my opinion, much better than a persistently slow interaction due webworkers.
Touches are truly simple and everything we need for whatever interaction: touchstart, touchmove, touchend.
There will never be a touchmove without a touchstart, neither a touchend without a touchstart. Things are slightly complicated when we assume that a touchstart, followed by a touchend, won't fire a touchmove in the meanwhile.
When we start touching our smartphone screen the area we cover with our finger may vary due pressure on the screen. If a touchstart event has been fired already but the area is "enlarging" from the same finger, we won't have another touchstart, we will be notified with a touchmove.
There are concepts as "touch tolerance" that are already applied on all layers, included hardware, but this is not enough if we would like to have full control.
Finally, touch events are a classic example where features detections fails. The only way to be sure 100% that the device will work with touch events is to listen to both touchstart and mousedown and accordingly with the one fired first, usually the touch if fired, we can switch/communicate that the device is compatible. All our detections may fail accordingly with the device or the implemented WebKit version.
The click is indeed the only universal fallback we can use to simulate interactions. Both new and old devices, included most recent Windows Mobile with that brEwser, will always react on click events. Pal Pre 2 does not expose right functionality for quirks mousemove neither ... and I am talking about web pages, if we create our own Application through Mojo framework ... well, things changes (again).
The only browser able to expose properly gesture and to make developers life easy is Safari Mobile. Even if all recent smartphones support gestures on OS level, this topic seems to be the most complicated thing ever to expose through the browser.
The problem number one is the conflict that these events could cause with System Gestures. If I think about Palm Pre 2 "cards" interaction and the way I love to use this phone, I can instantly imagine how many side effects "my own gestures" could cause from UX perspective ... specially if I am able to avoid System gestures defaults. The problem number two is that we may find gestures variants, just to make our life, as developers, more interesting ... isn't it? Well, as soon as these variant will be part of the newer browser version we can find on these devices, I will dedicate a post about them ... so, patience is the key! (isn't it Weronika :P)
However, if touches events are exposed correctly, some crazy dude out there (and I am not excluding me) could implement gestures through touches events.
gesturestart is when touch list length is greater than 1, gesturechange is only if gesturestart has been fired and both scale and rotate are simple Math operations, while gestureend is fired when the touch list length goes down to 1 or 0 ... almost easy stuff, we don't really need them as long as touches work.
Opera Mobile does not expose touches or gestures and the interaction is compromised but as render engine and web surfing, it is a pretty damn fast and cool browser that will be hopefully installable in the most recent Windows Mobile OS, since this has the worst browser you could ever imagine, compared with all others.
Marry Christmas Everybody
The Dedicated WebKit ... Nightmare!
As ppk mentioned already in Front Trends conference, we have basically only 5 browsers in our desktop PCs/Macs/Linuxes machines. Much more fun comes when we think we are dealing with a single browser, a generic WebKit based one, and we discover that there's no browser similar to another one, every bloody device has its own implementation with few exceptions represented by Safari Mobile, almost the same in iPad, iPod, and latest iPhone.WebKit and CSS(3)
Even if the CSS engine is basically the same for every single specific implementation, the number of supported, and so called, CSS3 features, are platform and device dependent. Something works as expected, something simply does not work, while something pretends to work but it does not until we force the rendering trying to activate Hardware Acceleration.The classic trick to do this is to apply 3D transformation to the main container of our styled stuff:
#styled-stuff-container {
-webkit-transform: translate3d(0, 0, 0);
}
Above technique could solve many headaches when a portion, or the whole body, looks fucked up ... give it a try but please note that GPU buffer will rarely support big images and these could cause a massive performances impact.
An ideal document size for mobile browsing should not reach more than 2~3000 pixels height ... considering a reasonable width, after that we could have problems.
Tricks a part, the horrible side effect of unsupported CSS features is that features detections are not really a solution ... "eye result" detection would be the way to go but it requires a pixel per pixel check.
The "eye result" detection is something I have invented right now as CSS check automation. We should have a snapshot of the container, saved as png, a snapshot created runtime from the rendered container, impossible with current DOM API, and two canvas elements in order to compare both image data ... where to speed up the process in JS world, we could simply compare the returned base64 encoded result of both snapshots as fast char-by-char (threaded as ints) match (e.g. "a" == "a").
This is fantasy right now, and it implicates complex, bandwidth greedy, operations I would never suggest ... but I am just saying ... that we should never trust the result we have on our desktop WebKit or another device WebKit based, we should always test results in target if we would like to avoid surprises.
Finally, messed up CSS could cause indirectly so many computation behind the scene we cannot even imagine ... until we discover the the whole interaction is compromised.
As example, those pages strongly styled in an unreasonable way through tons of overwritten or inherited CSS, in a deeply nested DOM, simply are unusable!
WebKit and JavaScript(ES5)
Under the flag "we support HTML5", many things implemented in ES5 specs are already there indeed. In few words these tiny devices are already "10 years" ahead whatever destktop browser based on Internet Explorer ... which is good, which gives us the possibility to forget all crap we use to detect, filter, change, assume, until now.This is the reason 99% of common web libraries out there are obsolete when it comes to the massive amount of features detections these libraries use to understand the exact version of IE, Firefox, or Opera ... all this stuff is crap, is bandwidth unfriendly, and unnecessary.
A good library for mobile browsing is a library dedicated for mobile browsing ... where even features detections could cost time (slower CPUs) and where most of the time these features detection, specially those for edge cases, can be dropped in favour of the good old User Agent string.
Yes, you read correctly, features detections we know could simply fail in all these variants of WebKit based browsers.
Some device could expose hosted features that are not available, some other could not expose anything but still support what we are looking for ... there are many examples that caused me nightmares during my experiments and no simple solution.
The User Agent sniff sometimes is the best, cheap, fast, solution we could possibly adopt and it will rarely fail when it comes to mobile.
Last, but not least, faster WebKit implements V8 engine, the google diamond, but others may implement the classic JavaScriptCore, with or without "Extreme" acceleration.
Native JSON Support
Almost all mobile browsers support native JSON. This is essential for fast and safe JSON strings and JS objects conversion into JSON strings.I am counting seconds for the day Douglas Crockford JavaScript implementation of JSON will be redundant/superfluous, same as I am counting seconds until attachEvent will disappear from the Earth!
GeoLocation API
A mobile browser that does not come with GeoLocation API support is a death device. Mobile therm talks by itself, it's the user "on the way", full stop. Remove the possibility to share or know the location and good by "to go" experience.session and local Storage Limits
Whatever freaking cool idea you come with these storages is not enough. What all these demo and examples around the net are saying is not exact. First of all the correct way to set an item is via official API, and not via direct access:
localStorage.setItem("setItem", "whatever");
// rather than
localStorage.setItem = "whatever";
// cause you don't want unexpected results later
localStorage.getItem("setItem"); // whatever
localStorage.setItem // ... what do you expect?
// a method or "whatever"
To know more about this problem, if interested, have a look.
Finally, and most important, setItem could fail once the storage reaches the memory limit which is not exposed (hopefully yet) through the API.
In few words we can have a nice Exception the moment we try to set an item, even the same, and the storage is "full".
To avoid problems, even if this is not a solution, use a bloody try catch block every time we need to set an item:
try {
localStorage.setItem("key", "bigValue");
} catch(e) {
// now we are fucked ... where do we put bigValue?
// we can still do stuff or clear some value
localStorage.clear(...)
}
The limit I am talking about is around 2Mb but it may vary.
Database API
Something nobody liked that much, something I love since the beginning. The SQLite database behind the scene is the best portable, tiny, and cross platform database engine we could possibly use on a browser. I am not a big fun of all these NoSQL fuzz, just use what the fuck you need when the fuck you need.In this case the Web Database API provides a nice message automatically when the application tries to store more data than allowed, letting us being able to pass the limit specified at the beginning.
A good compromise is to set the initial storage value to 2 megabyte, maximum 5, and after that limit it will be the device able to allocate more space if necessary, adding other 2, up to 5, megabytes to curent database.
Rather than try catch mandatory blocks, we have callbacks for error handling but, right now, I have never been able to reproduce in a real scenario problems with the SQLite database size.
WebWorkers
These beasts could be the ideal solution in a multi-core device. Unfortunately, webworkes do not come for free with current mobile CPUs. It does not matter if these are operated behind the scene since the scene itself could interact slower than usual due tasks priorities.Not a big deal considering webworker are not widely supported yet ... but still bear in mind the CPU is "that one", you better learn better algo or JS practices to speed up things rather than delegate piece of massive stuff to computate on the background.
A tiny temporary block is, in my opinion, much better than a persistently slow interaction due webworkers.
Touch Support
Touch events are the mandatory choice for mobile web development ... people should completely forget about mouseover and this kind of interaction bullshit, when it comes to device ... there is no fucking mouse on device, and these events should be used only as quirk fallback for those devices that do not expose properly touch events.Touches are truly simple and everything we need for whatever interaction: touchstart, touchmove, touchend.
There will never be a touchmove without a touchstart, neither a touchend without a touchstart. Things are slightly complicated when we assume that a touchstart, followed by a touchend, won't fire a touchmove in the meanwhile.
When we start touching our smartphone screen the area we cover with our finger may vary due pressure on the screen. If a touchstart event has been fired already but the area is "enlarging" from the same finger, we won't have another touchstart, we will be notified with a touchmove.
There are concepts as "touch tolerance" that are already applied on all layers, included hardware, but this is not enough if we would like to have full control.
Finally, touch events are a classic example where features detections fails. The only way to be sure 100% that the device will work with touch events is to listen to both touchstart and mousedown and accordingly with the one fired first, usually the touch if fired, we can switch/communicate that the device is compatible. All our detections may fail accordingly with the device or the implemented WebKit version.
The Click Event
In some device, as is for example the delicious Palm Pre 2 I am testing these days (thanks again Palm!) there are no touches, even if the browser exposes them, so it is not possible to drag or scroll via JavaScript but it is possible to trust the classic click event.The click is indeed the only universal fallback we can use to simulate interactions. Both new and old devices, included most recent Windows Mobile with that brEwser, will always react on click events. Pal Pre 2 does not expose right functionality for quirks mousemove neither ... and I am talking about web pages, if we create our own Application through Mojo framework ... well, things changes (again).
The Canvas Element
Almost every mobile browser supports canvas. Unfortunately, the Hardware Accelerated Canvas is still a myth. Canvas will be HW Accelerated hopefully soon, but what I have spotted right now, is that as example iOS 4.0.2 or lower has a tremendously faster canvas manipulation than iOS 4.2, or the latest iOS you can install in your iPad or iPhone. I am really sorry if you have already screwed up your mobile browsing experience updating this OS with latest ... since we all know you cannot go back now, let's hope Apple QA will test properly, next update, canvas performances ... epic fail from my point of view (and I can easily demonstrate it with eye test over exactly same operations ...)Flash ... maybe
The world #1 plugin sucks for mobile ... not all of them, but still sucks. At least the render is faster via bytecode than canvas one could be, but since we have HTML5 video element as well and since the interaction in a small screen cannot contain all those details and cool effects that Flash has given us 'till now, I don't think Flash should be considered mandatory for a mobile experience ... still, if present, Flash could be our best friend as fallback for all those "not implemented yet" HTML5 features (or in some case, give us even more ... accordingly with security risks we may face).Gestures ... if any ...
I still don't know how to pronounce this word properly ... but it does not matter.The only browser able to expose properly gesture and to make developers life easy is Safari Mobile. Even if all recent smartphones support gestures on OS level, this topic seems to be the most complicated thing ever to expose through the browser.
The problem number one is the conflict that these events could cause with System Gestures. If I think about Palm Pre 2 "cards" interaction and the way I love to use this phone, I can instantly imagine how many side effects "my own gestures" could cause from UX perspective ... specially if I am able to avoid System gestures defaults. The problem number two is that we may find gestures variants, just to make our life, as developers, more interesting ... isn't it? Well, as soon as these variant will be part of the newer browser version we can find on these devices, I will dedicate a post about them ... so, patience is the key! (isn't it Weronika :P)
However, if touches events are exposed correctly, some crazy dude out there (and I am not excluding me) could implement gestures through touches events.
gesturestart is when touch list length is greater than 1, gesturechange is only if gesturestart has been fired and both scale and rotate are simple Math operations, while gestureend is fired when the touch list length goes down to 1 or 0 ... almost easy stuff, we don't really need them as long as touches work.
Opera Mobile
This is a must have browser if you want a common cross device web experience or a better browser than the one you have preinstalled in that phone.Opera Mobile does not expose touches or gestures and the interaction is compromised but as render engine and web surfing, it is a pretty damn fast and cool browser that will be hopefully installable in the most recent Windows Mobile OS, since this has the worst browser you could ever imagine, compared with all others.
Mozilla Fennec
This is in my opinion too young and too featureless to compete with WebKit based implementations first and Opera Mobile after. Mozilla guys are working harder and improving a lot ... but still too much to do and hopefully a stable and cool release before next summer?Nothing Else
Starting from the fact I could not test all of them, and ppk is here again the man you are looking for, all I can say is that the only superior mobile browser is WebKit based, no matters which branch, as long as things I have talked about are, more or less, supported.Marry Christmas Everybody
Sunday, October 24, 2010
The Layer ... Of The Layer ... Of The Layer ...
When I read tweets like this one I cannot avoid a quick comment but the reason I am posting, is simply to explain that every time we write a web page/application, we are dealing with at least 4 different layers.
Moreover, this post is complementary for few slides I have introduced at front-trends, specially regarding the "avoid classic OOP emulation when not necessary" point.
Even if many developers don't care, I keep saying that every millisecond gained in this first layer, the page itself, is important.
Moreover, if we have a good understanding of the JavaScript programming language, we can easily realize that all these "Java Pretending Style Frameworks" emulating classic inheritance and OOP are not easier to maintain neither faster for what we need on mobile devices, included Netbooks.
The "easier to maintain" fuzz, associated with "Java style JavaScript", a sentence that does not make sense itself, is only a Java developer point of view.
Well written JavaScript without any "wannabe another language" pragmas, is truly much easier to both understand and write, modify, or fix, while the great magic behind this or that framework/library could become our first enemy when something goes wrong and we would like to understand and debug that magic 'cause we had a problem and we have strict deadline that may not match with a bug lifecycle.
Finally, as easily demonstrated via this test page, we can all spot how much more it costs to simply initialize a new instanceof constructor, compared with proper way to go natively via JavaScript, in that case made easier by this essential script, developed following TDD and tested here cross browser.
Anyway, common sense first and fast production quality, should always be kept in mind when we decide an approach, rather than another one. So, here frameworks play usually quite good role, the one to bring same functionality cross browser.
But what is a browser?
This is were the browser speed may vary, accordingly with the platform, and were every technique able to speed up render ( DOM+CSS engine such Gecko, Trident, others ) and JavaScript ( engine a part such V8, JavaScriptCore, SpiderMonkey ) is more than welcome. These guys are implementing any sort of trick to make the page and the code that fast, even if they have to deal with different operating systems. And guess what is an operating system?
You cannot expect that Linux, Mac, and Windows, just mentioning fews Desktop related ( more choices on mobile world ) magically display and provide browser functionalities via the same API. We would need something like a jOSQuery library here to make it happens ... but even worse, every operating system may have another abstract layer able to use, as example, Hardware Acceleration.
In few words, if we asked too many things to do on first abstract layer, and being the first the slower one, nothing can be that fast.
As example, if we spend just a millisecond more to create each object we need for a single frame, we can easily switch from 30fps, a decent visual framerate, to 29 or less, were things will start to be visually slower for our eyes ...
Finally, kudos for Opera Mini and its growing market share, I am pretty sure it will become soon the IE for mobile platforms, making developers life easier, being a portable browser fallback for whatever website or application, hoping will not have all IE problems we all know.
Moreover, this post is complementary for few slides I have introduced at front-trends, specially regarding the "avoid classic OOP emulation when not necessary" point.
Layer #1: JavaScript Libraries
We all know the DOM is a mess, and this is most likely the reason we chose a JS library rather than deal directly with possible problems we can have when we develop an x?HTML page.Even if many developers don't care, I keep saying that every millisecond gained in this first layer, the page itself, is important.
Moreover, if we have a good understanding of the JavaScript programming language, we can easily realize that all these "Java Pretending Style Frameworks" emulating classic inheritance and OOP are not easier to maintain neither faster for what we need on mobile devices, included Netbooks.
The "easier to maintain" fuzz, associated with "Java style JavaScript", a sentence that does not make sense itself, is only a Java developer point of view.
Well written JavaScript without any "wannabe another language" pragmas, is truly much easier to both understand and write, modify, or fix, while the great magic behind this or that framework/library could become our first enemy when something goes wrong and we would like to understand and debug that magic 'cause we had a problem and we have strict deadline that may not match with a bug lifecycle.
Finally, as easily demonstrated via this test page, we can all spot how much more it costs to simply initialize a new instanceof constructor, compared with proper way to go natively via JavaScript, in that case made easier by this essential script, developed following TDD and tested here cross browser.
Anyway, common sense first and fast production quality, should always be kept in mind when we decide an approach, rather than another one. So, here frameworks play usually quite good role, the one to bring same functionality cross browser.
But what is a browser?
Layer #2: The Browser
As libraries are considered an abstract way to reach same goal in all browsers, browsers are simply abstract applications able to bring the web cross platform.This is were the browser speed may vary, accordingly with the platform, and were every technique able to speed up render ( DOM+CSS engine such Gecko, Trident, others ) and JavaScript ( engine a part such V8, JavaScriptCore, SpiderMonkey ) is more than welcome. These guys are implementing any sort of trick to make the page and the code that fast, even if they have to deal with different operating systems. And guess what is an operating system?
Layer #3: The Operating System
We are even lucky if the browser deals directly with the operating system graphic API, since many other middle layers could be part of this stack ( flash or third parts plugins, as example ).You cannot expect that Linux, Mac, and Windows, just mentioning fews Desktop related ( more choices on mobile world ) magically display and provide browser functionalities via the same API. We would need something like a jOSQuery library here to make it happens ... but even worse, every operating system may have another abstract layer able to use, as example, Hardware Acceleration.
Layer #4: The Hardware
Open GL ES 2.0 is simply another abstraction able to transform API calls into specific hardware driver calls which means that starting back from the DOM and the used WebGL or CSS3 with HW support, things have been modified, translated, re-created at least a couple of times.In few words, if we asked too many things to do on first abstract layer, and being the first the slower one, nothing can be that fast.
As Summary
We, as web or scripting programming languages developers, rarely think that performances on the highest level ever can be that important but unfortunately, that highest level is the slowest one ever so, specially if we would like to reach best frame rate via canvas, WebGL, or CSS3 animations, it's highly recommended to be sure that the strategy/code we are using is the best one for our requirements.As example, if we spend just a millisecond more to create each object we need for a single frame, we can easily switch from 30fps, a decent visual framerate, to 29 or less, were things will start to be visually slower for our eyes ...
Finally, kudos for Opera Mini and its growing market share, I am pretty sure it will become soon the IE for mobile platforms, making developers life easier, being a portable browser fallback for whatever website or application, hoping will not have all IE problems we all know.
Saturday, August 22, 2009
sessionStorage cross domain
This is just a quick post about my last HTML5 sessionStorage implementation for "every" browser and this is the summary:
Finally, few bug fixes and this version is both W3C Draft compatible and cross browser.
This is a mixed list of almost all A-Grade browsers but about Android and iPhone, the total amount of available RAM could be 2 Mb.
It is not suggested to store in any case massive amount of information but so far I have putted every kind of library avoiding server requests for each tab session and without problems.
The sessionStorage aim is, in any case, to remember an arbitrary amount of data for each session and for each tab, surpassing cookies limits without number of keys or amount of data limits.
This project will be part of vice-versa library in order to make vice-versa the cross browser "lingua franca" W3 framework able to bring standards where these are not present yet.
I would like to say a big thanks to Jonathan Cook (J5 in WebReflection comments) for his suggestions, patience, and ideas exchange ;)
- Linear Storage Protocol finally consistent as a stand alone general purpose storage (string, file, request)
- RC4 Stream Cipher key generation without breaking characters (\x00 not in the random range)
- Cross Domain Support, if both site a.com and site b.com support my implementation, they will not delete or modify each other domain information
- optimized boot strap for frames and iframes, the storage parsing and reassignment is performed once and not every time which means zero delay when an iframe is injected or more frames uses the same implementation
Finally, few bug fixes and this version is both W3C Draft compatible and cross browser.
Known Supported Browsers
- Chrome 1 and 2, version 3 or 4 should have native support for Web Storage
- Internet Explorer 5, 6, and 7, 8 has native support for Web Storage
- Opera 7, 8, 9, and 10 beta, hopefully 10 final will have native support
- Safari 3, version 4 has native support for Web Storage
- Firefox whatever version, since it supports Web Storage since version 1.5
- Google Android and iPhone, but latest WebKit releases should support Web Storage
This is a mixed list of almost all A-Grade browsers but about Android and iPhone, the total amount of available RAM could be 2 Mb.
It is not suggested to store in any case massive amount of information but so far I have putted every kind of library avoiding server requests for each tab session and without problems.
The sessionStorage aim is, in any case, to remember an arbitrary amount of data for each session and for each tab, surpassing cookies limits without number of keys or amount of data limits.
This project will be part of vice-versa library in order to make vice-versa the cross browser "lingua franca" W3 framework able to bring standards where these are not present yet.
1.4 Special Guests
I would like to say a big thanks to Jonathan Cook (J5 in WebReflection comments) for his suggestions, patience, and ideas exchange ;)
Saturday, August 15, 2009
Opera Detection Revamped?
How to know if onload and unload event are supported without firing them?
Apparently, it has never been that simple!
Object.prototype.toString
.call(window.opera) ===
"[object Opera]"
;
Enjoy
P.S. Prototype Framework uses this trick since version 8, I had no idea about that! Good one!
Thursday, April 23, 2009
vice-versa project, a philosophy rather than a library
Array.forEach(document.all, function(node, i, all){
// vice-versa project
});
well, there are few things I can say here, and first one is: please, if interested, help me!
The second one is my vision, a web where rather than criticisms, there is more collaboration to obtain good overall performances improving code quality.
This is not my old JSL project, this is a new groove, a new project, a non library, something I hope you will all appreciate.
But, if not, I am here to discuss about it :)
vice-versa project
Have fun with Web Development!
Update
Implemented a TaskSpeed test file for vice-versa project. Here first results ordered by average.
browser Pure vice Moo qoox dojo YUI AVG
Dom versa Tools doo
--------------------------------------------------------------------
Safari 4 198 114 392 205 246 410 260.83
Chrome 1 251 273 589 279 336 692 403.33
Opera 10 215 206 764 267 311 659 403.67
FireFox 3 404 670 2962 3557 1197 792 1597.00
IE 8 876 1031 10312 1470 2267 1749 2950.83
IE 7 795 1767 8174 1734 7796 3329 3932.50
IE 6 3941 4686 67590 16611 22388 24591 23301.17
Tuesday, September 02, 2008
Google Chrome Fix
Update 2008/09/04
I have created a new version that should be able to recognise the correct Google directory in every supported windows, and not only English version.
Please do not hesitate to tell me if the created link for No Sandbox Option is not creating it properly, thank you.
Google Chrome Fix Multi Language OS
-----------------------
I successfully tested the new browser in my laptop, while today I had some headache at work.
This is the reason I created in few minutes a simple Windows Application that let you choose which option you want to solve crashes during Google Chrome startup:
Please note that the registry fix option changes a key that should solve Symantec problems, but it is not clear if this key could change security level for those PC that use Symantec end point protection, or similar softwares.
In every other case, the GUI create a link to launch Chrome without multiple sandbox, and if I am not wrong, it should mean that multi tab will not be multi thread.
Here you can find the project page, where there is a download section and an executable file.
Thanks to AutoIt developers, and ~d-bliss for the icon.
Enjoy :)
I have created a new version that should be able to recognise the correct Google directory in every supported windows, and not only English version.
Please do not hesitate to tell me if the created link for No Sandbox Option is not creating it properly, thank you.
Google Chrome Fix Multi Language OS
-----------------------
I successfully tested the new browser in my laptop, while today I had some headache at work.
This is the reason I created in few minutes a simple Windows Application that let you choose which option you want to solve crashes during Google Chrome startup:
The application failed to initialize properly (0x00000005). Press Ok to terminate application.
Please note that the registry fix option changes a key that should solve Symantec problems, but it is not clear if this key could change security level for those PC that use Symantec end point protection, or similar softwares.
In every other case, the GUI create a link to launch Chrome without multiple sandbox, and if I am not wrong, it should mean that multi tab will not be multi thread.
Here you can find the project page, where there is a download section and an executable file.
Thanks to AutoIt developers, and ~d-bliss for the icon.
Enjoy :)
Wednesday, March 12, 2008
Do You Like Browser Benchmarks? Here I am!
Hi guys,
today we will not talk about my last JavaScript ArrayObject creation :D
Today is the benchmark day, and in this case the test is as simple as explicative ... both Math object and scope are two things we use every day for whatever purpose in this baby Web 2.0 era!
Let me start directly with results (ORDER BY speed ASC):
What kind of benchmark is it?
This is a double test that includes the usage of scoped shortcuts, and the usage of the object that you cannot absolutely get by without: the global Math one!
To understand better this kind of test, please look at these functions:
The first one, is the most common in every day libraries / scripts, while the second one and the third one, are used by "a little bit more skilled" developers.
The second one, uses the same concept of my good old friend, the smallest FX library from 2006: bytefx
The scoped schortcut is absolutely the fastest way to use a global objet, constructor, whatever you want.
Just think about nested scopes, this amazing ECMAScript 3rd Edition more close to future than many other new program languages ... ( IMO, and sorry for exaggeration :lol: )
When you write the name of something in your scope, the engine looks obviously in the same scope, than in the external one, going on until the super global object, the window
This behavior is basically what should happen using the with statement as well ... but unfortunately, even if this is basically what's up, performances are clearly against the usage of absolutely comfortable with statement.
At the same time, there is one browser that you are probably using right now, that create a bit of confusion about everything I've just said right now: Firefox 2
With quite twice of time, using scoped shortcuts, this browser (the best I've ever used for years, and the one I'll use for other many years) reverse totally my conviction about how does scope work ... anyway, we are lucky because Mozilla staff is creating good stuff with Firefox 3 ... who cares about Firebird and other old versions? :D
Don't you really trust me and my results?
So do this bench by yourself :geek:
today we will not talk about my last JavaScript ArrayObject creation :D
Today is the benchmark day, and in this case the test is as simple as explicative ... both Math object and scope are two things we use every day for whatever purpose in this baby Web 2.0 era!
Let me start directly with results (ORDER BY speed ASC):
Firefox 3.0b4
----------------------------------
regular avg time in ms: 9.98
scoped avg time in ms: 3.18
encapsulated avg time in ms: 12.98
Safari 3.0.4 (523.15)
----------------------------------
regular avg time in ms: 13.42
scoped avg time in ms: 6.42
encapsulated avg time in ms: 11.82
Opera 9.24
----------------------------------
regular avg time in ms: 13.82
scoped avg time in ms: 9.6
encapsulated avg time in ms: 17.64
Internet Explorer 8.0.6001.17184
----------------------------------
regular avg time in ms: 16.42
scoped avg time in ms: 6.82
encapsulated avg time in ms: 16.82
Firefox 2.0.0.12
----------------------------------
regular avg time in ms: 26.84
scoped avg time in ms: 42.06
encapsulated avg time in ms: 28.64
What kind of benchmark is it?
This is a double test that includes the usage of scoped shortcuts, and the usage of the object that you cannot absolutely get by without: the global Math one!
To understand better this kind of test, please look at these functions:
function regular(){
for(var i = 0, time = new Date; i < 10000; i++)
Math.round(i / Math.PI);
time = new Date - time;
return time;
};
function scoped(){
for(var round = Math.round, PI = Math.PI, i = 0, time = new Date; i < 10000; i++)
round(i / PI);
time = new Date - time;
return time;
};
function encapsulated(){
with(Math){
for(var i = 0, time = new Date; i < 10000; i++)
round(i / PI);
time = new Date - time;
};
return time;
};
The first one, is the most common in every day libraries / scripts, while the second one and the third one, are used by "a little bit more skilled" developers.
The second one, uses the same concept of my good old friend, the smallest FX library from 2006: bytefx
The scoped schortcut is absolutely the fastest way to use a global objet, constructor, whatever you want.
Just think about nested scopes, this amazing ECMAScript 3rd Edition more close to future than many other new program languages ... ( IMO, and sorry for exaggeration :lol: )
When you write the name of something in your scope, the engine looks obviously in the same scope, than in the external one, going on until the super global object, the window
This behavior is basically what should happen using the with statement as well ... but unfortunately, even if this is basically what's up, performances are clearly against the usage of absolutely comfortable with statement.
At the same time, there is one browser that you are probably using right now, that create a bit of confusion about everything I've just said right now: Firefox 2
With quite twice of time, using scoped shortcuts, this browser (the best I've ever used for years, and the one I'll use for other many years) reverse totally my conviction about how does scope work ... anyway, we are lucky because Mozilla staff is creating good stuff with Firefox 3 ... who cares about Firebird and other old versions? :D
Don't you really trust me and my results?
So do this bench by yourself :geek:
Subscribe to:
Posts (Atom)