Quick Tip – Hauteur d’un block de texte

Piqûre de rappel pour certains, découverte pour d’autres, vous avez peut-être déjà remarqué que dans ce cas :

  1. <div style="font-size: 20px">Hello world!</div>

La hauteur du block div n’est pas de 20 pixel, mais “plus”. Ceci est, dans des cas d’intégration assez courants (positionnements relatifs) la source de problèmes.

Il est néanmoins assez difficile de définir ce “plus”, qui semble être variable en fonction de la police utilisée et du navigateur.

Par exemple sous Chrome et Firefox avec Arial :

font-size3029282726252423222120
height3635343331313028272525
font-size191817161514131211109
height2322202018161615141211

Le ratio est donc un calcul approximatif, probablement avec des arrondis, pas évident de connaitre donc la bonne hauteur du bloc.

C’est là que l’on fait intervenir le line-height. Il suffit de le rajouter Pour résoudre le problème :

  1. <div style="font-size: 20px; line-height: 1em;">Hello world!</div>

A présent, le div a bien une hauteur de 20 pixels de haut !

Quick tip – ORDER BY avec une jointure

Le saviez-vous ?

Le choix des champs pour l’ordre de tri est important dans une requête SQL.
Prennez par exemple la requête suivante :

  1. SELECT *
  2. FROM `ma_table_a` a
  3. INNER JOIN `ma_table_b` b ON (a.`aid` = b.`aid`)
  4. ORDER BY b.`aid` DESC

En plaçant un index sur le champ b.`aid`, celui-ci sera utilisé dans la requête, et celle-ci sera très rapide.
En réalité, ce n’est pas le cas. L’utilisation de cet index n’est absolument pas bon et vous allez probablement autant de temps à executer la requête que s’il n’y en avait pas.

Pourquoi ?

Dans ce genre de requête, vous avez le tri qui est executé à la fin de la requête, juste avant le renvoi des données.
Le tri est executé sur une table temporaire qui ne contient pas d’index, et donc pas celui de la table `ma_table_b`.

Comment corriger le problème ?

Si l’on choisit un index de la première table `ma_table_a`, celle de la close FROM, le tri sera effectué avant la jointure, et l’on peut ainsi bénéficier totalement de l’index de la table placé sur `aid` :

  1. SELECT *
  2. FROM `ma_table_a` a
  3. INNER JOIN `ma_table_b` b ON (a.`aid` = b.`aid`)
  4. ORDER BY a.`aid` DESC

Sur ce problème, en changeant la close ORDER BY par celle de la première table, je passe d’une requête de plus de 5 secondes… à 10ms.

Moteur utilisé : MyISAM
Nombre d’enregistrements : 130 000 / table

Quick Tip – Optimisation simple de boucles JavaScript

N’étant pas resté au bout de la soirée webperf du 21 avril, je ne me risquerais pas à faire un compte rendu qui risquerait d’être incomplet.

Néanmoins, lors de cette soirée nous avons découvert un morceau de code assez surprenant.

Pour se mettre dans le contexte, nous étions en train d’analyser le site de 20 minutes, et
Vincent Voyer
à décidé de lancer un dynatrace.

En regardant les résutlats, nous avons remarqué qu’un script avait un temps d’execution de… 1.1s, ce qui est bien entendu énorme ! Ce script vennait du tag xiti. Celui-ci sera peut-être corrigé, mais il pourra servir de cas d’exemple sur une mauvaise pratique.

En fouillant dans le code on découvre (en réindenté) le code suivant :

  1. var elts = target.getElementsByTagName('*');
  2. for (var i = 0; i &lt; elts.length; i++) {
  3. }

Pourquoi est-ce un problème ? Avant de commencer à expliquer le problème, il est important de connaitre un point important. Pour celui-là, j’ai utilisé statsy.

JS in HTML attributes: 1351 bytes
CSS in HTML attributes: 2790 bytes
JS in SCRIPT tag: 4111 bytes
CSS in STYLE tag: 69039 bytes
All innerHTML: 215207 bytes
# SCRIPT tag: 54
# STYLE tag: 1
# DOM elements: 2143
Cookie size: 340 bytes

Dans la liste des résultats ci-dessus, on remarque que la page comporte 2143 élements. Le problème est simple :
Le getElementsByTagName récupère tout les éléments DOM. Ce qui demande beaucoup de traitement sur une page kilométrique comme celle d’un site de news.

Second problème, la boucle effectuée sur ces éléments recalcule cette selection à chaque itération de la boucle. Les élements sont donc recalculés 2143 fois. C’est simplement énorme.

Comment corriger le problème ? Pour le premier, il faut savoir si cette selection est vraiment importante. Qu’à-t-on besoin de faire sur tout l’arbre DOM ?
Pour le second, il suffit de mettre en cache la taille du tableau, par exemple comme ceci :

  1. var elts = target.getElementsByTagName('*');
  2. for (var i = 0, len = elts.length; i &lt; len; i++) {
  3. }

Et dans ces conditions, le recalcul ne sera pas refait pour chaque itération.

Conclusion :
De plus en plus, les sites sont remplis de JavaScript. Ces améliorations peuvent sembler superflues, mais c’est ce qui peut faire la différence entre deux site.
Si vous n’en êtes pas convaincus, pensez aux utilisateurs de netbook, de tablettes ou de mobile : Vous allez leur faire gagner un temps fou !