IE8 (javascript): очень медленно загружать большой список опций в элементе SELECT - PullRequest
3 голосов
/ 09 марта 2012

Я загружаю элемент SELECT с 6000 элементами, используя методы createElement и add.Код показан ниже, и также может быть доступен здесь .В IE8 загрузка списка занимает около 16 секунд, а для его очистки - примерно столько же времени.В IE9 и Firefox время загрузки составляет <2 секунды, а время очистки - <1 секунда.Любые идеи о том, как я могу улучшить скорость в IE8? </p>

Спасибо.

<script type="text/javascript">
window.onload = loadList;

function loadList() {
    clearList();
    var start = new Date().getTime();
    var o = document.getElementById("listLookupAvailableItems")
    for (var i = 0; i < 6000; i++) {
        var option = document.createElement("option");
        option.text = 'ABCDF ' + i;
        option.value = option.text;
        o.add(option, o.options[null]);
    }
    log('Load time: ' + (new Date().getTime() - start));
}
function clearList() {
    var start = new Date().getTime();
    document.getElementById("listLookupAvailableItems").options.length = 0;
    log('Clear time: ' + (new Date().getTime() - start));
    return false;
}
function log(txt) {
    document.getElementById('infoPanel').innerHTML += '</br>' + txt;
}
</script>

Ответы [ 3 ]

10 голосов
/ 09 марта 2012

Я предполагаю, что эта конкретная операция DOM просто очень медленная в IE8. В общем, манипулирование DOM - самый медленный тип операции в любом браузере. Чтобы обойти это, я обычно пытаюсь найти способы объединить свои изменения в одном обновлении DOM (например, добавить HTML-пакет из 6000 строк в таблицу вместо индивидуального добавления 6000 строк в таблицу).

В этом примере единственным способом сделать это, вероятно, будет создание всех элементов <option> в виде HTML, а затем использование innerHTML для их вставки в <select>. Посмотрите этот пример jsfiddle: http://jsfiddle.net/pseudosavant/bVAFF/

У меня нет IE8 для тестирования, но он намного быстрее даже для Firefox (22 мс против 500 мс) для меня.

Обновление

Похоже, он не работал с innerHTML в IE для загрузки списка, но он работал для его очистки. Загрузка работает с использованием jQuery $(o).html(html);. Я обновил пример jsfiddle, и он работает в IE9, и, надеюсь, сейчас в IE8.

Javascript:

$(document).ready(function(){
    loadListBatch();
});

function loadListBatch() {
    clearListBatch();
    var start = new Date().getTime();
    var o = document.getElementById("listLookupAvailableItems")
    var html = "";
    for (var i = 0; i < 6000; i++) {
        html += "<option value='"+'XYZ' + i+"'>"+'XYZ ' + i+"</option>";
    }
    // o.innerHTML = html; // Only one DOM operation, but still doesn't work in IE
    $(o).html(html); // Using jQuery to insert the HTML makes it work with IE
    console.log('Load time: ' + (new Date().getTime() - start));
}

function clearListBatch() {
    var start = new Date().getTime();
    document.getElementById("listLookupAvailableItems").innerHTML = ""; // It was already only one DOM call, but this is faster it seems.
    console.log('Clear time: ' + (new Date().getTime() - start));
    return false;
}
3 голосов
/ 16 июня 2013

Если вы поддерживаете IE7 / IE8, вам следует минимизировать манипуляции JavaScript с DOM.Поэтому, если вы добавляете, вставляете или удаляете узлы, вам нужно минимизировать манипулирование DOM в целом.Лучшее решение - массовое обновление элементов.

Итак, если у вас есть список выбора и вы выполняете JQuery.append (), вы получите лучшую производительность, если объедините всю строку параметров перед добавлением.

var str = $('<option value="x">Item 1</option>' + '<option value="y">Item 2</option>');
$('#selectMenu').append(str);

//or in a loop
var array = ['orange','apple','grapes','mangoes'];
var str = '';

for (var x= 0; x < array.length; x++) {
    str = str + '<option value="' + x + '">' + x + '</option>';
}
$('#selectMenu').append(str);

Дополнительно, еслиВы хотите увидеть, насколько медленно JavaScript выполняет IE8 и запускает тест SunSpider JS.Firefox 22 и Chrome 27 - около 300 мс, а IE8 - около 4000 мс.Это многое говорит о том, почему ваши скорости JS медленные.Интересно, что IE10 теперь занимает менее 200 мс.http://www.webkit.org/perf/sunspider/sunspider.html

0 голосов
/ 04 июля 2019

У меня была очень похожая ситуация.

У меня есть набор входов с 1700+, поэтому я предоставил опцию «фильтр», которая копировала бы выбор и применяла фильтр на основе помимо скопированного списка.(Он «открывает» диалоговое окно, которое расширяет раскрывающийся список до списка, занимающего почти 80% экрана)

Незаметно копирование сработало в других браузерах, но в IE заняло 8-15 секунд.

Решение, основанное на предыдущих ответах, а также на этом посте ( Узнайте о медленном (и быстром) способе добавления элементов в DOM ) заключалось в добавлении всех элементов вСтрока HTL, затем присваивает ее внутреннему HTML нового объекта, который еще не является частью DOM.И, наконец, замена объекта из DOM на новый.

Это, очевидно, уменьшает количество операций «перекомпоновки», выполняемых браузером, что, скорее всего, является причиной такой низкой производительности.

Некоторым тестом до реализации этого стиля было выполнение полного цикла for без добавления параметров в список, и в таком тесте код выполнялся очень быстро, было ясно, что selectElement.add (optionElement) был медленнымpart.

Вот пример того, как закончилась моя функция:

    function fillselector(IdSelect){
        var selector = document.getElementById(IdSelect);
        if( !selector ){
            alert('Original select element not found.');
            return;
        }
        var lista = document.getElementById('selectFilter_lista');
        if( !lista ){
            alert('Copied list element not found.');
            return;
        }

        var filterText = noSpecialChars(document.getElementById('selectFilter_text').value);
        var options =''
        for (var i = 0; i < selector.length; i++){
            if (filterText == '' || noSpecialChars(selector[i].text).indexOf(filterText) != -1 ){
                //Commented code works but is painfuly slow on IE
                //var option = document.createElement("option");
                //option.value = selector[i].value;
                //option.text = selector[i].text;
                //lista.add(option);

                options += '<option value="'+selector[i].value+'">'+selector[i].text+'</option>';
            }
        }
        var newList = document.createElement('select');
        newList.id='selectFilter_list';
        newList.className='selectFilter_list';
        newList.size = 20;
        newList.ondblclick= function(){closeselector(IdSelect, true);}
        newList.innerHTML = options;
        newList.value = selector.value;
        var listParent = lista.parentElement; //<div> that only contains the <select>
        listParent.removeChild(lista);
        listParent.appendChild(newList);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...