У меня есть этот объект javascript, который содержит список городов, а также данные о зависимости от состояния.
var cityList = {
'1' : ['CITY_CODE_A','City A', '2','11','2'],
'2' : ['CITY_CODE_B','City B','','11',''],
'3' : ['CITY_CODE_C','City C', '','11','']
};
var stateList = {
'11' : ['STATE_CODE_A', 'State A'],
'12' : ['STATE_CODE_B', 'State B'],
'13' : ['STATE_CODE_C', 'State C'],
'14' : ['STATE_CODE_D', 'State D']
};
В зависимости от выбранного состояния ключ передается функции, которая соответствует ключу со значениями (элемент индекса 3 в массиве) в списке городов, а если найден, то формируется тег параметра <select>
. Вот код:
$.each(cityList, function(key, value) {
if(selectedVal == value[3]){
$("select[id='"+selectid+"']").append('<option value="'+value[0]+'" code="'+key+'">' +value[1] + '</option>');
}
});
Теперь, когда этот список городов вырастет до 50 тыс. Записей (2 МБ), штат штата имеет 50 тыс. Городов (тестирование производительности), приведенный выше код занимает 2 минуты, чтобы загрузить раскрывающийся список городов на компьютере под управлением Windows 7, на котором выполняется код локально. Пробовал с native for
/in
-loop, но не получил удовлетворительного результата.
Любые идеи о том, как сократить время? Нужно ли мне менять структуру объектов JS?
Изменение: @downvoters, не могли бы вы объяснить, почему вы считаете это неправильным? Но сначала попробуйте запустить этот тест.
Если вы хотите получить города для определенного состояния, вы можете создать карту, где ключевыми являются идентификаторы состояний,
var cityList = {
11 : [ ['CITY_CODE_A','City A', '2','11','2'], ['CITY_CODE_B','City B','','11',''] ],
12 : [ ['CITY_CODE_C','City C', '2','12','2'], ['CITY_CODE_D','City D','','12',''] ]
}
Теперь вам нужно только citylist[ selectedVal ]
$.each(cityList[selectedVal], function(key, value) {
$("select[id='"+selectid+"']").append('<option value="'+value[0]+'" code="'+key+'">' +value[1] + '</option>');
});
Чтобы оптимизировать его дальше, вы должны избегать манипулирования DOM (добавление элементов <option>
) в цикле и вместо этого буферизировать:
var $selectEl = $('<select />');
$.each(cityList[selectedVal], function(key, value) {
$selectEl.append('<option value="'+value[0]+'" code="'+key+'">' +value[1] + '</option>');
});
$selectEl.attr( 'id', selectid );
$("select[id='"+selectid+"']").replaceWith( $selectEl );
Я также являюсь другом лучшего использования поиска вместо 50k прокручиваемых предметов. Но чтобы ответить на ваш вопрос, я бы улучшил ваш код, используя:
var html = '';
$.each(cityList, function (key, value) {
html += '<option value="' + value[0] + '" code="' + key + '">' + value[1] + '</option>'
});
$("select[id='1']").append(html);
Это ускорит создание вашего option
потому что DOM будет изменен только один раз, а не в 50k раз, как вы сказали в своем примере. (Короткая демонстрация)