Ответ 1
Вы можете попробовать использовать textContent
вместо innerText
, я думаю, что это должно быть быстрее. Кроме того, синхронизация генерации списков и циклов отдельно указала бы, есть ли проблема в генерации списков.
У меня есть список HTML из примерно 500 элементов и над ним расположен фильтр. Я начал с использования jQuery, чтобы отфильтровать список, когда я набрал букву (временный код добавлен позже):
$('#filter').keyup( function() {
var jqStart = (new Date).getTime();
var search = $(this).val().toLowerCase();
var $list = $('ul.ablist > li');
$list.each( function() {
if ( $(this).text().toLowerCase().indexOf(search) === -1 )
$(this).hide();
else
$(this).show();
} );
console.log('Time: ' + ((new Date).getTime() - jqStart));
} );
Однако после ввода каждой буквы (в частности, первой буквы) была пара секундной задержки. Поэтому я подумал, что это может быть немного быстрее, если я использую простой Javascript (недавно я читал, что функция jQuery each
особенно медленная). Здесь мой JS-эквивалент:
document.getElementById('filter').addEventListener( 'keyup', function () {
var jsStart = (new Date).getTime();
var search = this.value.toLowerCase();
var list = document.querySelectorAll('ul.ablist > li');
for ( var i = 0; i < list.length; i++ )
{
if ( list[i].innerText.toLowerCase().indexOf(search) === -1 )
list[i].style.display = 'none';
else
list[i].style.display = 'block';
}
console.log('Time: ' + ((new Date).getTime() - jsStart));
}, false );
К моему удивлению, простой Javascript до 10 раз медленнее, чем эквивалент jQuery. Версия jQuery занимает около 2-3 секунд, чтобы фильтровать каждую букву, в то время как версия Javascript занимает 17 + секунд! Я использую Google Chrome на Ubuntu Linux.
Это не для чего-то действительно важного, поэтому он не должен быть суперэффективным. Но я делаю что-то действительно немое с моим Javascript здесь?
Вы можете попробовать использовать textContent
вместо innerText
, я думаю, что это должно быть быстрее. Кроме того, синхронизация генерации списков и циклов отдельно указала бы, есть ли проблема в генерации списков.
Другая лучшая практика для скорости javascript - кэширование list.length
в переменной и вызов переменной:
l = list.length;
for (var i=0;i<l;i++):{ code here}
И, возможно, время с jsperf было бы лучше.
Здесь я немного переработал ваш код:
var filter = document.getElementById( 'filter' ),
ablist = document.querySelector( '.ablist' );
filter.addEventListener( 'keyup', function () {
var re, elems, i, len, elem;
re = RegExp( this.value, 'i' );
elems = ablist.children;
for ( i = 0, len = elems.length; i < len; i += 1 ) {
elem = elems[i];
elem.style.display =
elem.textContent.search( re ) > -1 ? 'list-item' : 'none';
}
}, false );
Живая демонстрация: http://jsfiddle.net/MVFxn/
Изменения:
i
, нет необходимости в toLowerCase
,'.ablist'
, querySelector
должен быть самым быстрым способом захвата (поскольку он прерывает запрос, когда он находит первый такой элемент),children
уже ссылается на них удобно.Мне бы очень хотелось узнать, как этот код работает на вашей странице...
Я использовал while
вместо for
и сделал некоторые незначительные улучшения. Здесь - окончательный код.
var list = list = document.querySelectorAll('ul.ablist > li');
document.getElementById('javascriptFilter').addEventListener( 'keyup', function () {
var jsStart = (new Date).getTime(),
search = this.value.toLowerCase(),
i = list.length - 1,
listItem,
result;
while( i >= 0 )
{
listItem = list[i];
if ( listItem.textContent.toLowerCase().indexOf(search) === -1 )
listItem.style.display = 'none';
else
listItem.style.display = 'block';
i--;
}
result = ((new Date).getTime() - jsStart);
console.log(['Time: ', result, '<br />'].join(''));
}, false );