Lecture du DOM et performances
Grosses pertes de perfs ces jours-ci au boulot dans l'affichage d'un tableau d'environ 1200 cellules. Après comparaisons des récents commit, un suspect : la fonction calc
en CSS. Ou plutôt la lecture de certaines propriétés d'élément DOM...
Petit cas de test tout simple : un bouton qui injecte dans le DOM 1200 éléments sur lesquels on applique une position en fonction de la taille de leur parent :
<!DOCTYPE html>
<html>
<head>
<title>CSS Calc benchmark</title>
<meta charset="utf-8">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<p><button type="button" id="calc">RUN</button></p>
<div id="placeholder"></div>
<script src="script.js"></script>
</body>
</html>
.row {
display: table-row;
width: 100%;
}
.cell {
display: table-cell;
padding: 1rem;
border: 1px solid #ccc;
}
.cell > * {
position: relative;
}
const placeholder = document.getElementById('placeholder');
const run = function () {
placeholder.innerHTML = '';
let start = Date.now();
for (let i = 0; i < 100; i += 1) {
let row = document.createElement('div');
row.className = 'row';
placeholder.appendChild(row);
for (let j = 0; j < 12; j +=1) {
let cell = document.createElement('span');
cell.className = 'cell';
row.appendChild(cell);
let c = document.createElement('span');
c.textContent = `${i}-${j}`;
cell.appendChild(c);
// position calculé
c.style.top = `calc(50% - ${c.offsetHeight / 2}px`;
// position fixe
// c.style.top = '7px';
}
}
console.log(Date.now() - start);
};
document.getElementById('calc').addEventListener('click', run);
Navigateurs | top fixe | top calculé | Rapport |
---|---|---|---|
chrome 64 | ~ 5ms | ~ 360ms | ~ 70 |
Firefox 58 | ~ 9ms | ~ 1800ms | ~ 200 |
edge 16 | ~ 30ms | ~ 3600ms | ~ 120 |
La perte de performance est énorme sous Firfox mais il effectue le travail encore 2 fois plus vite que Edge qui traine la patte par rapport au 2 autres même quand on écrit une valeur fixe. Pour être précis, ce n'est pas calc
qui pose problème ni même le fait d'appliquer la position mais bien d'aller lire le offsetHeight
, source de reflow et donc coûteux en ressources.
- Titre
- What forces layout / reflow
- Auteurs
- Paul Irish
- Éditeur
- Github
- Titre
- Avoid Large, Complex Layouts and Layout Thrashing
- Auteurs
- Paul Lewis
- Éditeur
- developers.google.com