Tester les performances d’un code Javascript via un benchmark [performance]

Je vous conseille de tester régulièrement votre code Javascript pour voir les performances par rapport à d’autres commandes. Il arrive qu’on hésite entre deux (ou plus!) façons de faire.

Il existe le populaire http://jsperf.com/ qui offre la possibilité de tester autant de bouts de code que l’on souhaite, en appelant même quelques framework bien connus (comme jQuery).

Mais si vous avez des besoins un peu plus particulier, ou vous devez travailler sur un environnement restreint, alors il est possible d’utiliser JSLitmus. La façon de l’utiliser est incroyablement simple :

1
2
3
4
5
<script src="JSLitmus.js"></script>
<script>
JSLitmus.test('Mon premier test', function() { /* do something */ });
JSLitmus.test('Mon second test', function() { /* do something else */ });
</script>

Cela fait apparaître un bouton “Run tests” avec un petit tableau. Une fois le test fini le tableau et un graphique vous donnent les informations nécessaires, et en l’occurrence plus le chiffre (nombre d’opérations/sec) est grand et mieux c’est.

Voici un exemple qui montre que l’utilisation de search est bien plus rapide que de déclarer une RegExp puis appeler match :

1
2
3
4
5
6
7
8
9
10
<html>
<head>
</head>
<body>
<script>
JSLitmus.test('Mon premier test', function() { var regExp = new RegExp("pouet$"); var ok = ("pouet".match(regExp) != null); });
JSLitmus.test('Mon deuxième test', function() { var ok = ("pouet".search("pouet") != -1); });
</script>
</body></html>

Résultat :

IE8 Developer Toolbar qui ne s’affiche plus [astuce]

Avec Internet Explorer il est possible d’utiliser un débogueur qu’ils nomment “IE Developer Toolbar”. C’est très peu puissant, mais quand on doit travailler sur ce navigateur ça peut être utile…

Pour l’activer il faut appuyer sur la touche F12, seulement, dans mon cas, même si elle apparaissait bien dans la liste des fenêtres ouvertes, quand je cliquais dessus rien ne se passait : elle ne s’ouvrait pas ! La solution consiste à faire un SHIFT + Clic Droit sur la fenêtre puis choisir “Maximize” (ou “Agrandir” en français), et là votre Developer Toolbar va s’ouvrir en grand. Les pré-réglages étant mauvais, la fenêtre s’ouvre dans un étrange mode.

Simple, mais il fallait y penser…

L’option “Déplacer vers le groupe” a disparu des onglets de Firefox ? [astuce]

Je me suis retrouvé dans une drôle de situation : après avoir ré-installé Firefox 5.0.1, je ne trouvais plus l’option “Déplacer vers le groupe” qui est présent lorsque vous faites un clic droit sur un onglet comme ceci :
Démonstration du menu d'options

Pour la faire réapparaître, c’est tout simple : il suffit de créer un nouveau groupe d’onglets !

L’opérateur typeof en Javascript [programmation]

Si vous avez déjà essayé d’utiliser typeof en Javascript pour trouver le type d’un objet, vous avez dû vous rendre compte que cet opérateur n’aide pas beaucoup….

Le typeof par défaut de Javascript

Déjà, comme typeof est un opérateur, vous n’avez pas besoin d’utiliser des parenthèses ou une quelconque autre décoration.
Ainsi on aura :

1
2
typeof 2; // -> "number"
typeof "Kodono"; // -> "string"

On peut remarquer qu’ici typeof nous a bien donné ce qu’on attendait… mais voilà ce qu’il se passe avec d’autres exemples :

1
2
3
4
5
typeof []; // -> "object"
typeof new Boolean(true); // -> "object"
typeof /a/; // -> "object"
typeof new Date(); // -> "object"
typeof null; // -> "object"

Comme on peut le voir, l’opérateur va fournir un “object” dans de nombreuses situations, ce qui n’aide pas du tout.

Créer un meilleur typeof

Pour faire court, on peut appliquer Object.prototype.toString.call à un objet qui va retourner une chaine au format “[object Class]”. Quelques exemples :

1
2
3
Object.prototype.toString.call(new Number(2)); // -> [object Number]
Object.prototype.toString.call(new Date()); // -> [object Date]
Object.prototype.toString.call(/a/); // -> [object RegExp]

Maintenant que l’on sait ça on peut créer notre propose fonction typeOf (en sachant que Object.prototype peut se raccourcir par ({})/).
On trouve sur Internet différentes façons de faire que je vais vous proposer.

La plus lente

Elle n’est pas très rapide (dûe à l’utilisation des expressions régulières), mais elle est très courte :

1
2
3
4
5
6
7
8
9
function typeOf(obj){return({}).toString.call(obj).match(/\s(\w+)/)[1]}
 
console.log(typeOf(new Number(2))); // -> Number
console.log(typeOf(new Date())); // -> Date
console.log(typeOf("test")); // -> String
console.log(typeOf(null)); // -> Null
console.log(typeOf(/a/)); // -> RegExp
console.log(typeOf([])); // -> Array
console.log(typeOf(function(){})); // -> Function

jQuery.type

Si vous utilisez déjà jQuery, vous pouvez utiliser la fonction jQuery.type qui propose une fonction assez rapide et efficace.
Ils utilisent la méthode suivante :

1
2
3
4
5
6
7
8
9
10
11
12
function typeOf(obj){
  var c2t={"[object Boolean]":"Boolean","[object Number]":"Number","[object String]":"String","[object Function]":"Function","[object Array]":"Array","[object Date]":"Date","[object RegExp]":"RegExp","[object Object]":"Object"};
  return obj==null?String(obj):c2t[({}).toString.call(obj)]||"object";
}
 
console.log(typeOf(new Number(2))); // -> Number
console.log(typeOf(new Date())); // -> Date
console.log(typeOf("test")); // -> String
console.log(typeOf(null)); // -> Null
console.log(typeOf(/a/)); // -> RegExp
console.log(typeOf([])); // -> Array
console.log(typeOf(function(){})); // -> Function

La plus courte et rapide

Celle-ci ne prend que quelques caractères, et se veut rapide en plus !

1
2
3
4
5
6
7
8
9
function typeOf(obj) {return({}).toString.call(obj).slice(8,-1)}
 
console.log(typeOf(new Number(2))); // -> Number
console.log(typeOf(new Date())); // -> Date
console.log(typeOf("test")); // -> String
console.log(typeOf(null)); // -> Null
console.log(typeOf(/a/)); // -> RegExp
console.log(typeOf([])); // -> Array
console.log(typeOf(function(){})); // -> Function

Conclusion

Si vous utilisez déjà jQuery dans votre code, alors vous pouvez faire confiance à jQuery.type, sinon je vous conseille la dernière fonction proposée :

1
function typeOf(obj) {return({}).toString.call(obj).slice(8,-1)}

Retrouver l’url d’une page JSP [programmation]

Dans une page (scriptlet) JSP vous pouvez exécuter du Java grâce aux balises <% %>. C’est avec cela qu’on peut retrouver l’url de la page en cours :

1
2
3
4
5
6
7
8
9
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE html>
<html>
<head><title>Exemple JSP</title></head>
<body>
L'url de la page est : <%= HttpUtils.getRequestURL(request).toString() %>?<%= request.getQueryString() %>
</body>
</html>

Stocker un mot de passe en PHP grâce à bcrypt [sécurité]

[niveau: intermédiaire]

Il a été démontré que le stockage de mot de passe n’est pas chose aisée, et que l’utilisation d’une méthode de hashage (MD5, SHA-1, etc) n’est pas parfaite, même avec l’utilisation d’un salt. D’après cette constatation plusieurs articles indiquent que la meilleure méthode reste l’utilisation de bcrypt, comme on peut le lire dans How to safely store a password.

L’utilisation de bcrypt est assez simple :
1) Télécharger phpass (fichier .tgz qui contient un fichier PasswordHash.php);
2) Appeler PasswordHash.php dans votre page :

1
<?php require('includes/PasswordHash.php'); ?>

3) Maintenant vous pouvez utiliser l’objet PasswordHash comme cela :

1
2
3
4
5
<?php
$password = $_POST["password"];
$hasher = new PasswordHash(8, FALSE);
$hash = $hasher->HashPassword($password);
?>

Et pour vérifier un mot de passe, vous devez utiliser ce petit bout de code :

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php // vérification du mot de passe
$password = $_POST["password"];
$password_correct = "password qui vient de la base de données"; /* Le hash stocké précédemment */
$hasher = new PasswordHash(8, FALSE);
$check = $hasher->CheckPassword($password, $password_correct);
 
if ($check) {
 echo "Password correct!";
}
else {
 echo "Password incorrect...";
}
?>

A noter que si vous souhaitez le rendre compatible avec d’autres systèmes équivalents (comme BCrypt pour Java par exemple), alors il faudra vous assurer que votre machine a bien CRYPT_BLOWFISH d’installé (on peut le voir avec <?php echo CRYPT_BLOWFISH; ?>) afin d’avoir une bonne compatibilité des deux systèmes.

Function Scroll To [javascript]

[niveau débutant]

<EDIT>: A noter qu’il existe la fonction HTMLElement.scrollIntoView() qui fait la même chose et qui semble être compatible avec tous les navigateurs contrairement à ce qu’il se dit sur divers forums (j’ai testé sur les navigateurs récents en tout cas, mais j’ai aussi testé d’IE6 à IE9 et ça semble fonctionner).</EDIT>

Pour se déplacement dans votre page jusqu’à un élément, pas besoin de jQuery.scrollTo() car vous pouvez le faire en quelques lignes de code.

Pour cela, on va calculer la position (coordonnées) de notre élément où on souhaite se rendre; on utilise les propriétés offsetLeft et offsetTop. Il faudra aussi tenir compte de l’offsetParent pour avoir une position correcte.

var elem = document.getElementById('footer_bg');
var left = 0;
var top = 0;
do {
  left += elem.offsetLeft;
  top  += elem.offsetTop;
} while (elem = elem.offsetParent);
// on a maintenant les coordonnées X=left et Y=top de notre élément
// on peut donc se déplacement dans le document grâce à window.scrollTo(X,Y)
window.scrollTo(left,top);

Vous pouvez tester ce code, ce qui devrait vous amener jusqu’en bas de cette page.

Vous pouvez trouver une version de cette fonction qui fait ~100 caractères sur https://gist.github.com/1114275.

Mini code Encoder/Decoder en Base64 pour Javascript [programmation]

[niveau débutant]

Il existe plusieurs scripts sur le Net pour encoder/decoder en Base64 avec Javascript, mais c’est sur http://140byt.es/ que j’ai trouvé les plus courts, car ils font moins de 140 caractères !
Cependant, je les ai modifié légèrement pour qu’ils fonctionnent avec IE7 (et plus vieux) :

function b64_decode(d,b,c,u,r,q,x){b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(r=q=x='';c=d.charAt(x++);~c&&(u=q%4?u*64+c:c,q++%4)?r+=String.fromCharCode(255&u>>(-2*q&6)):0)c=b.indexOf(c);return r}
function b64_encode(a,b,c,d,e,f){b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";c="=";for(d=f='';e&=3,a.charAt(d++)||(b='=',e);f+=b.charAt(63&c>>++e*2))c=c<<8|a.charCodeAt(d-=!e);return f}

Soit un total de 436 bytes pour les deux fonctions.

Pour l'utiliser :

alert(decode_b64(encode_b64("foobar")));

A noter qu'il existe aussi window.btoa() qui fait pareil, mais qui n'est disponible qu'à partir de IE10.

Evénement sur la fermeture d’une fenêtre (window close) [javascript]

[niveau: intermédiaire]

Il est possible d’effectuer une action sur la page avant que l’utilisateur ne quitte la page (en la fermant, la rechargeant, en navigant dans l’historique, ou en cliquant sur un lien). Pour cela utilisez la méthode ci-dessous (via MDN) :

window.onbeforeunload = function (e) {
  e = e || window.event;
  // For IE and Firefox prior to version 4
  if (e) e.returnValue = 'Any string';

  // For Safari
  return 'Any string';
};

Si vous ne voulez pas ce comportement pour un clic sur un lien, alors il faudra gérer une variable qui sera activée lors d’un clic sur un tag A (exemple avec jQuery) :

__okForClosing = false;
window.onbeforeunload = function (e) {
  if (!__okForClosing) {
    e = e || window.event;
    // For IE and Firefox prior to version 4
    if (e) e.returnValue = 'Any string';

    // For Safari
    return 'Any string';
  }
};
$('a').click(function() { __okForClosing=true; });

Simple effet highlight sur un element avec jQuery [javascript]

[niveau: intermédiaire]

Si vous souhaitez créer un effet highlight sur un élément (en passant le background en jaune par exemple), voici comment il faut s’y prendre :

jQuery.prototype.highlight = function() { 
  jQuery(this).css("background-color","yellow").fadeTo('slow', 0.1, function() {
    jQuery(this).fadeTo('slow', 1.0, function() {
      jQuery(this).css("background-color","white");
    });
  });
};

jQuery('#mon-element').highlight();

A tester ici :

Hello, I’m an example Highlight
Total 31337 Highlight

Ceci est pour le test. Highlight