J'essaie de trouver un algorithme efficace pour charger dynamiquement les images d'arrière-plan d'un ensemble d'objets. <li>
et ont des problèmes d'efficacité. Mon code actuel ressemble à ceci :
function elementInView($elem, vps, vpe) {
var elempos = $elem.position();
var pagestart = elempos.top + vps;
var pageend = elempos.top + vps + $elem.height();
var offset = 78 - Math.max(0,vps-pagestart) - Math.max(0,pageend-vpe);
// I want to update all items that are within 200 pixels of
// the current viewport
return (vpe > 0 && offset > -200);
}
$('#container').bind('scroll', function() {
var $container = $(this);
var vps = $container.scrollTop();
var vpe = vps + $container.height();
$('li:not(.bgset)', '#container').each(function() {
var $this = $(this);
if (elementInView($this,vps,vpe)) {
$this.addClass('.bgset');
// Set the background-image (doesn't affect performance noticably.)
}
});
});
Cette opération prend entre 200 et 600 ms pour une liste de ~250 éléments, et ~1500 ms pour une liste de ~1500 éléments, ce qui la rend pratiquement inutilisable.
Quelqu'un voit-il des problèmes ou est-ce la meilleure façon de procéder ? J'ai essayé d'obtenir TOUS les <li>
au lieu de $('li:not(.bgset)'
mais cela n'a pas vraiment eu d'impact.
(La liste contient des images d'arrière-plan générées dynamiquement (qui ne sont pas mises en cache ET qui sont modifiées assez souvent), et le chargement de ~1500 d'entre elles ralentissait vraiment tout, c'est pourquoi j'ai essayé cette approche).
EDIT : J'ai oublié de mentionner que j'ai pensé à écrire un sélecteur jQuery personnalisé qui correspond aux éléments qui retournent true pour elementInView
Cette approche serait-elle préférable ?