Появление AJAX сильно изменило режим работы клиентов веб-приложений. Он позволяет пользователям сосредоточиться на своей работе, не беспокоясь о частом обновлении страниц. Теоретически технология AJAX позволяет в значительной степени сократить время ожидания операций пользователя и сэкономить трафик данных в сети. Однако это не всегда так. Пользователи часто жалуются, что снижается скорость отклика систем, использующих AJAX.
Автор много лет занимался исследованиями и разработками AJAX и участвовал в разработке Dorado, относительно зрелой платформы AJAX в Китае. По опыту автора, первопричиной такого результата является не AJAX. Во многих случаях снижение скорости отклика системы вызвано непродуманным дизайном интерфейса и недостаточно эффективными навыками программирования. Ниже мы разберем несколько аспектов, на которые необходимо обратить внимание в процессе разработки AJAX.
Правильное использование клиентского программирования и удаленных вызовов процедур.
Программирование на стороне клиента в основном основано на JavaScript. JavaScript является интерпретируемым языком программирования, и его эффективность работы немного ниже, чем у Java. В то же время JavaScript работает в строго ограниченной среде, например в браузере. Поэтому разработчики должны иметь четкое представление о том, какая логика может выполняться на стороне клиента.
То, как программирование на стороне клиента следует использовать в реальных приложениях, зависит от опыта и суждений разработчика. Многие проблемы здесь можно только понять. Из-за ограниченности места здесь мы кратко резюмируем следующие меры предосторожности:
Избегайте частого использования вызовов удаленных процедур, например, избегайте использования вызовов удаленных процедур в телах циклов.
Если возможно, используйте удаленный вызов процедур AJAX (асинхронный удаленный вызов процедур).
Избегайте выполнения тяжелых операций с данными на стороне клиента. Например: большие пакеты операций копирования данных, вычисления, требующие большого объема обхода данных и т. д.
Улучшить метод работы с объектами DOM.
При программировании на стороне клиента операции с объектами DOM чаще всего занимают процессорное время. При работе с объектами DOM разница в производительности между различными методами программирования часто очень велика.
Ниже приведены три фрагмента кода с одинаковыми результатами. Их функция — создать на веб-странице таблицу размером 10x1000. Однако скорость их бега сильно различается.
/* Код теста 1 — затраченное время: 41 секунда*/
var table = document.createElement("ТАБЛИЦА");
document.body.appendChild(таблица);
for(var я = 0; я <1000; я++){
вар строка = table.insertRow(-1);
for(var j = 0; j < 10; j++){
вар ячейка = objRow.insertCell(-1);
cell.innerText = "( " + i + " , " + j + " )";
}
}
/* Код теста 2 — затраченное время: 7,6 секунды*/
var table = document.getElementById("ТАБЛИЦА");
document.body.appendChild(таблица);
var tbody = document.createElement("TBODY");
table.appendChild(tbody);
for(var я = 0; я <1000; я++){
var row = document.createElement("TR");
tbody.appendChild(строка);
for(var j = 0; j < 10; j++){
var cell = document.createElement("TD");
row.appendChild(ячейка);
cell.innerText = "( " + i + " , " + j + " )";
}
}
/* Код теста 3 — затраченное время: 1,26 секунды*/
var tbody = document.createElement("TBODY");
for(var я = 0; я <1000; я++){
var row = document.createElement("TR");
for(var j = 0; j < 10; j++){
var cell = document.createElement("TD");
cell.innerText = "( " + i + " , " + j + " )";
row.appendChild(ячейка);
}
tbody.appendChild(строка);
}
var table = document.getElementById("ТАБЛИЦА");
table.appendChild(tbody);
document.body.appendChild(таблица);
Разница между «Тестовым кодом 1» и «Тестовым кодом 2» здесь заключается в том, что при создании ячеек таблицы используются разные методы API. Разница между «Тестовым кодом 2» и «Тестовым кодом 3» заключается в несколько разном порядке обработки.
Мы не можем проанализировать такую большую разницу в производительности между «Тестовым кодом 1» и «Тестовым кодом 2». На данный момент известно, что InsertRow и InsertCell — это API-интерфейсы для конкретных таблиц в DHTML, а createElement и AppendChild — это собственные API-интерфейсы W3C DOM. Первое должно быть инкапсуляцией второго. Однако из этого мы не можем сделать вывод, что собственный API DOM всегда лучше, чем API, специфичный для объекта. Рекомендуется выполнить несколько базовых тестов его производительности, если вам нужно часто вызывать API.
Разница в производительности между «Тестовым кодом 2» и «Тестовым кодом 3» в основном связана с разницей в порядке их сборки. Подход «Тестового кода 2» заключается в том, чтобы сначала создать самый внешний объект
. Подход «Тестового кода 3» заключается в том, чтобы сначала построить всю таблицу в памяти изнутри наружу, а затем добавить ее на веб-страницу. Цель этого — максимально сократить количество раз, когда браузер пересчитывает макет страницы. Всякий раз, когда мы добавляем объект на веб-страницу, браузер пытается пересчитать расположение элементов управления на странице. Поэтому, если мы сможем сначала создать весь объект, который нужно сконструировать в памяти, а затем сразу добавить его на веб-страницу. Затем браузер выполнит только перерасчет макета. Если суммировать это в одном предложении, то чем позже вы выполните addChild, тем лучше. Иногда, чтобы повысить эффективность работы, мы можем даже рассмотреть возможность использования RemoveChild для удаления существующего элемента управления со страницы, а затем снова поместить его на страницу после завершения построения. Увеличьте скорость накопления строк. При использовании AJAX для отправки информации мне часто может потребоваться собрать несколько относительно больших строк для завершения отправки POST через XmlHttp. Хотя предоставление такого большого объема информации может показаться неэлегантным, иногда нам приходится сталкиваться с такой необходимостью. Итак, насколько быстро происходит накопление строк в JavaScript? Давайте сначала проведем следующий эксперимент. Накопить строку длиной 30000. /* Код теста 1 — затраченное время: 14,325 секунды*/ вар стр = ""; для (вар я = 0; я <50000; я++) { стр += "ххххххх"; } Этот код занял 14,325 секунды, и результаты были не идеальными. Теперь изменим код на следующий вид: /* Код теста 2 — затраченное время: 0,359 секунды*/ вар стр = ""; для (вар я = 0; я <100; я++) { вар суб = ""; for (var j = 0; j < 500; j++) { суб += "ххххххх"; } ул += суб; } Этот код занимает 0,359 секунды! Результат тот же: все, что мы делаем, это сначала собираем несколько строк меньшего размера, а затем собираем их в строки большего размера. Этот подход может эффективно уменьшить объем данных, копируемых в память на более поздних этапах сборки строк. Зная этот принцип, мы можем дополнительно разобрать приведенный выше код для тестирования. Код ниже занимает всего 0,140 секунды. /* Код теста 3 — затраченное время: 0,140 секунды*/ вар стр = ""; for (var i1 = 0; i1 < 5; i1++) { вар стр1 = ""; for (var i2 = 0; i2 < 10; i2++) { вар стр2 = ""; for (var i3 = 0; i3 < 10; i3++) { вар стр3 = ""; for (var i4 = 0; i4 < 10; i4++) { вар стр4 = ""; for (var i5 = 0; i5 < 10; i5++) { str4 += "ххххххх"; } стр3 += стр4; } стр2 += стр3; } стр1 += стр2; } стр += стр1; } Однако описанный выше подход может быть не лучшим! Если информация, которую нам нужно отправить, находится в формате XML (на самом деле, в большинстве случаев мы можем попытаться собрать информацию, подлежащую отправке, в формате XML), мы также можем найти более эффективный и элегантный способ — использовать объекты DOM для сборки. символы для нас строка. В следующем абзаце сборка строки длиной 950015 занимает всего 0,890 секунды. /* Использование объектов DOM для сбора информации — затраченное время: 0,890 секунды*/ вар xmlDoc; если (тип браузера == BROWSER_IE) { xmlDoc = новый ActiveXObject("Msxml.DOMDocument"); } еще { xmlDoc = document.createElement("DOM"); } var root = xmlDoc.createElement("корень"); для (вар я = 0; я <50000; я++) { var node = xmlDoc.createElement("данные"); если (тип браузера == BROWSER_IE) { node.text = "xxxxxx"; } еще { node.innerText = "xxxxxx"; } root.appendChild(узел); } xmlDoc.appendChild (корень вар ул) ; Избегайте утечек памяти объектов DOM. |