Веб-приложения со сложной архитектурой компонентов на Ajax и программной логикой на основе парадигмы толстого клиента распространяются все быстрее и требуют от браузеров высокой производительности. Поэтому при проектировании нового интерфейса пользователя будет совсем не лишним поинтересоваться, а "потянет" ли его потенциальный клиент. Обратной задачей может быть выбор оптимального браузера уже для существующей корпоративной системы. В каждом из этих случаев было бы очень полезно определить и сопоставить производительность целевых приложений. Быстродействие любого современного браузера достаточно легко рассчитать, и сегодня я расскажу о том, как это сделать.
Несколько слов об архитектуре браузеров
Сердце всех браузеров - движок рендеринга (layout engine), основными задачами которого являются:
- Чтение HTML
- Формирование на основе HTML объектной модели документа (Document Object Model, DOM)
- Визуализация объектной модели
Составным блоком, отвечающим за интерпретацию разметки, является парсер HTML и CSS. В DOM присутствуют функции для создания, добавления и удаления элементов интерфейса (элементов DOM). DOM позволяет также осуществлять поиск элементов и реализует сложную событийную модель.
Объектная структура документа необходима для доступа к элементам страницы через JavaScript - язык сценариев для интерактивного изменения элементов сайта. Помимо JavaScript, с DOM можно работать из VBScript (только в Internet Explorer), Java, Flash и Silverlight. Код на JavaScript интерпретируется во время выполнения отдельным компонентом, который так и называется - интерпретатор JavaScript. Именно JavaScript занимает доминирующее положение, а его интерпретатор встроен во все современные браузеры. Когда парсер HTML встречает в разметке тег <script> или значение атрибута элемента, начинающееся c "javascript:", он передает JavaScript-интерпретатору содержимое тега в первом случае и значение атрибута во втором. Таким образом, составляемые тесты должны быть нацелены на определение производительности как самого движка, так и двух других составных частей браузера - DOM и интерпретатора JavaScript.
Нужно отметить, что есть приложения, которые не поддерживают JavaScript и не строят DOM, например, браузер Lynx.
Реализация тестов и их обоснование
В основу тестов, как правило, ложатся несколько требовательных к ресурсам операционной системы задач, наиболее часто встречающихся при разработке веб-приложений. В современных продуктах на основе Ajax и DHTML ключевое место занимает взаимодействие с DOM, когда сайт фактически рендерится после загрузки всей страницы. Например, элементы навигации по ресурсу, как правило, создаются после загрузки страницы для исключения ошибки прерывания операции (Operation Aborted) в Internet Explorer 6, который все еще очень популярен. Поэтому важно знать, насколько быстро движок браузера позволяет создавать элементы DOM динамически, т.е. интерактивно обновлять страницу. Существуют программные компоненты, например, иерархические списки, которые в любом случае требуют значительных ресурсов для отрисовки и функционирования. Они даже могут использовать различные стратегии, чтобы отложить рендеринг на более позднее время (так называемая отложенная или "ленивая" инициализация). Примером является компонент dijit.Tree из набора Dojo Toolkit, который рендерит ветви и листья дерева только при необходимости их отображения. Один из представленных ниже тестов как раз и генерирует дерево, определяя скорость работы обозревателя с DOM и скорость рендеринга (данный тест определяет совместную работу DOM и движка).
_runEnginePerfTest:function() { var startDate = new Date(); for (var i = 0, n = 500; i < n; i++) { var el = document.createElement('div'); el.innerHTML = '<span><img/><a>test link</a></span>'; document.getElementById('_testPool').appendChild(el); } document.getElementById('_testPool').innerHTML = ''; return parseInt((new Date()) - startDate); }
Следующий тест для DOM просто определяет время поиска элемента по документу. Только эти два простых теста могут достаточно точно смоделировать большинство операций с DOM, являющихся неотъемлемой частью большинства современных web-приложений.
_runDOMPerfTest:function() { var startDate = new Date(); for (var i = 0, n = 10000; i < n; i++) { var o = document.getElementById('_browserInfo'); while(o) { o = o.parentNode; } } return parseInt((new Date()) - startDate); }
Оставшиеся два теста оценивают скорость выполнения таких задач, как сложение строк и поиск по регулярным выражениям интерпретатором JavaScript. Конкатенация строк часто используется для динамического формирования HTML, а регулярные выражения незаменимы при выполнении шаблонных операций, например, подсветки ключевых слов на странице. Эти задачи являются самыми ресурсоемкими, но используются довольно часто.
_runStringPerfTest:function() { var startDate = new Date(); var a = []; for (var i = 0, n = 400; i < n; i++) { a.push('test item'); a.join('\n'); } return parseInt((new Date()) - startDate); } _runRegexPerfTest:function() { var startDate = new Date(); var a = []; var search = document.body.innerHTML; for (var i = 0, n = 10; i < n; i++) { var r = new RegExp('\\b(\\w)+\\b', 'g'); search.match(r); } return parseInt((new Date()) - startDate); }
Запуск тестов осуществляется с помощью следующих функций. Читатель также может посмотреть полный код примеров (www.narthex-daemon.net/create-browser-test2.daemon164) и полученную страницу для тестирования браузеров (www.narthex-daemon.net/browsertest).
run:function() { var o = this; setTimeout(function() { document.getElementById('_runButton').disabled = true; document.body.style.cursor = 'wait'; var t = 0; t+=o.runPerfMetric('_domPerf',o._runDOMPerfTest); t+=o.runPerfMetric('_enPerf',o._runEnginePerfTest); t+=o.runPerfMetric('_jsPerf',o._runRegexPerfTest,'1'); t+=o.runPerfMetric('_jsPerf',o._runStringPerfTest,'2'); document.getElementById('_totalValue').innerHTML= t+' миллисекунд'; }, 1); } runPerfMetric:function(_id, _metric, _postfix) { document.getElementById(_id+'Text').style.display=''; var n = 10; var t = 0; for (var i = 0; i < n; i++) { t += _metric(); } var value = parseInt(t/n); document.getElementById(_id+'Result').style.display=''; document.getElementById(_id+'Value'+(_postfix||'')).innerHTML= value+' миллисекунд'; return value; }
Оценка достоверности результатов
тестов
Полученные результаты должны быть точными, иначе они не имеют никакой цены. Поэтому я хочу их сравнить с данными, предоставляемыми аналогичной, только более серьезной, службой Futuremark Peacekeeper (www.futuremark.com/peacekeeper). В тестировании приняли участие следующие браузеры: Opera 10, Mozilla Firefox 3.5, Apple Safari 4, Internet Explorer 8 и Google Chrome 3.
Для начала я получу интегральные оценки производительности четырех браузеров, найдя среднее взвешенное значений оценок по четырем тестам. Затем я пройду процедуру тестирования на Futuremark Peacekeeper и нормализую полученные значения. Теперь у меня есть два набора оценок, а мне необходимо узнать, насколько они близки друг к другу. Набор не велик, и даже на глаз можно определить, что оценки близки. Для определения статистической взаимосвязи двух или нескольких случайных величин в статистике существует такой показатель, как коэффициент корреляции. В Microsoft Excel данная функция доступна как CORREL (КОРРЕЛ). В данном случае коэффициент корреляции можно использовать лишь с оговоркой, поскольку выборка слишком мала и состоит из пяти значений. Рассчитанный коэффициент корреляции составлял от 0,96 до 0,99, в зависимости от начальных значений, что говорит о том, что два набора оценок очень близки (сильная связь оценок определяется значением 1.0). В моей реализации каждый тест прогоняется 10 раз, чтобы уменьшить погрешность измерений, однако погрешность все равно присутствует, что и объясняет различие коэффициента корреляции.
Выводы
Самый главный вывод заключается в том, что для получения вполне точной оценки быстродействия браузера на фоне конкурентов достаточно выполнить несколько простых функций на JavaScript. Для этого совсем не обязательно тратить 5-10 минут на полный анализ, который проводит Futuremark Peacekeeper, используя, по сути, те же задачи поиска элемента по DOM, рендеринг, работу со строками и т.д.
Матрица числовых оценок | |||||
Метрика\Браузер | Mozilla Firefox 3.5.2 | Opera 10 | Apple Safari 4 | Google Chrome 3.0.195.21 | Internet Explorer 8 |
Многократное обращение к элементам DOM | 53 | 32 | 16 | 28 | 438 |
Многократное добавление элементов в DOM | 84 | 9 | 9 | 12 | 131 |
Регулярные выражения | 105 | 222 | 80 | 28 | 81 |
Конкатенация строк | 17 | 55 | 6 | 13 | 9 |
Матрица нормированных оценок | |||||
Метрика\Браузер | Mozilla Firefox 3.5.2 | Opera 10 | Apple Safari 4 | Google Chrome 2.0.172.43 | Internet Explorer 8 |
Многократное обращение к элементам DOM | 0.0935 | 0.0564 | 0.0282 | 0.0494 | 0.7725 |
Многократное добавление элементов в DOM | 0.3429 | 0.0367 | 0.0367 | 0.0490 | 0.5347 |
Регулярные выражения | 0.2035 | 0.4302 | 0.1550 | 0.0543 | 0.1570 |
Конкатенация строк | 0.1700 | 0.5500 | 0.0600 | 0.1300 | 0.0900 |
Интегральная оценка | 81 | 107 | 28 | 28 | 155 |
Нормированные интегральные оценки | 0.2025 | 0.2684 | 0.0700 | 0.0707 | 0.3885 |
Результаты Futuremark Peacekeeper | 1698 | 1547 | 2807 | 2707 | 654 |
Обратные оценки Peacekeeper | 0.0006 | 0.0006 | 0.0004 | 0.0004 | 0.0015 |
Нормированные оценки Peacekeeper | 0.1687 | 0.1852 | 0.1021 | 0.1058 | 0.4381 |
Коэффициент корреляции | 0.99 |
По данным моего теста и Futuremark Peacekeeper, результирующее ранжирование браузеров по производительности выглядит так: Apple Safari 4 (с минимальным отрывом), Google Chrome 3, Mozilla Firefox 3.5, Opera 10, Internet Explorer 8, причем оценки для Firefox и Opera очень близки. Кроме того, имея статистику результатов по каждому тесту в отдельности, также можно сделать и выводы о быстродействии каждого из компонентов браузеров. Например, JavaScript-интерпретатор в Opera 10 является самым медленным, но по скорости работы с DOM браузер уступает лишь Apple Safari 4 и обгоняет Google Chrome 3, который считается самым быстрым обозревателем, по мнению Peacekeeper.
В следующий раз я проведу анализ производительности более широкого набора браузеров как на платформе Windows, так и в среде Linux.
Narthex,
www.narthex-daemon.net
Горячие темы