Yoan Blanc’s weblog

Another swiss guy lost in Paris

(pseudo-)yield in JavaScript: “be responsive”

Yoan BlancSun, 09 Sep 2007, ,

I watched recently the nice video on YUI Theater about high performance in JS. And one thing I learnt, apart the fact that being lazy programmer isn’t a bug, but a feature, is that you can do a (pseudo-)yield in JavaScript (like in Python for example).

def countdown(max):
 for i in range(max, 0,  -1):
  yield i

Yes, it’s a little trivial… Don’t worry, the JS one is more interesting. The goal of yield is the let the browser refresh the display before continuing our task. A typical use of yield in wxPython is a progression bar. In JS, this is done with the well known timeout method: setTimeout.

function countdown(id, max) {
 var elem = document.getElementById(id);
 function show() {
  elem.innerHTML = max;
  max -= 1;
  if(max > 0) {
   setTimeout(show, 0);
  }
 }
 show();
}

I’ve made a page of examples (please visit the one from Joseph Smarr too). You can tweak how many times the show method will be called before letting the browser refresh. A refresh costs time too. Depending of the task, it’s good to say refresh every 10 operations or more. The goal is to have a responsive user interface that give the user a good impression, speed and reactivity.

My point of view is that this trick has to be applied if your ear some complains about the reaspeed of your web application, speed is different from reactivity, but as … said, your client cannot do the difference. Give the visitor as soon as possible something to see and try to truncate big operations with appropriate yields.

One side effect of that, is that you may have to deal with the timeout functions you calls. I don’t do it in my examples, but it should be good to be sure you don’t have any running yielding operations before running a new one. Double-click on a JSON button to see the glitch. Letting the browser display something, means letting the user interact with it. In case, you really want doing naughty thing this that, this could be useful: “Continuation-Passing Style”.

To avoid any confusion, I’m talking about pseudo-yield because yield exists in JavaScript 1.7 already.

J’ai récemment regardé la vidéo sur YUI Theater parlant de hautes performances en JavaScript, et y ai appris un point intéressant: l’usage du yield (un semblant de yield). Je le connaissais dans le langage Python pour fabriquer un générateur (très utile dans wxPython lors de la confection de barre de chargement) mais pas dans JavaScript (même s’il existe dans version 1.7 du langage).

Le but de yield est de rendre la main au navigateur au milieu d’une opération longue et douleureuse, pour qu’il souffle un peu et permettre à l’affichage de se mettre à jour. Voir l’exemple de Joseph Smarr sur la question. On peut imaginer, le remplissage d’une table avec beaucoup de valeurs par exemple. On obtient du navigateur qu’il rafraîchisse son état avec la méthode setTimeout à 0 qui va continuer l’opération en cours après avoir rendu la main. Ca donne un effet d’animation le plus souvent, qui n’est pas inintéressant.

J’ai fait plusieurs exemples, tous créant des nœuds DOM et les ajoutant à la page que je vous invite à essayer. Le premier va créer des étoiles par une méthode simple ou en se servant du yield tel qu’on l’a vu et le second va afficher un contenu JSON. Au lieu de tout créer d’un coup, on va en créer un certain nombre, les afficher puis continuer, ce qui se passe pour les étoiles, ça va accélerer l’animation.

Redonner la main au navigateur, implique que des actions peuvent être opérées également, il faut donc être prudent avec son usage. Ne pas relancer une opération, si une autre est en court. Chose que je n’ai pas faite dans mes exemples.

Pour répéter ce qu’on trouve dans la vidéo, la vitesse est souvent une impression de vitesse et donner au plus vite un retour visuel de l’opération en cours est le meilleur moyen de maintenir le visiteur attentif et ne pas lui faire perdre patience. Ce que tous les sites en Flash font depuis leur naissance. D’abord informer qu’une opération est en court, puis afficher dès que possible du contenu.

About

meYoan Blanc is a web developer that lives in Paris (19, rue Bichat75010France) works for Yahoo! and comes from Switzerland ( La Chaux-de-Fonds). This web site is for this weblog, a playground for random stuffs and can help keepingconnected with some friends out there.

Get my vCard or contact me by phone (+33 1 74 30 12 92) or email ().

Misc

RSS, list.blogug.ch

This site reflects only my opinion and is not affiliated with my employer.

copyright 2006-2007 — doSimple.ch