Добрый день. Я сейчас прохожу курс повышения квалификации - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?
|
Оптимизация структуры веб-страниц
5.1. Динамические стили: быстро и просто
В книге "Разгони свой сайт" уже затрагивалась тема быстрого добавления стилевых правил в исходный документ динамически, не затрагивая при этом стадию предзагрузки (когда у нас еще белый экран в браузере). В ней однако не был рассмотрен следующий вопрос: какой метод использовать для добавления массива CSS-пра-вил в сам HTML.
Естественно, что таких вариантов существует несколько, и дальше они все будут рассмотрены с точки зрения производительности в клиентском браузере.
5.1.1. Тестовое окружение
Поскольку скорость загрузки отдельного CSS-файла достаточно велика, а нам требуется рассмотреть, как его содержимое может повлиять на скорость его динамического применения к документу, — следовательно, нам нужны сотни или даже тысячи правил. В качестве отправной точки была опять взята главная страница Яндекса, стили которой были вынесены в отдельный файл и скопированы 10 раз. Это дало необходимую задержку (которая существенно больше погрешности, вносимой браузерами) и не сильно увеличило сжатый с помощью gzip файл.
5.1.2. XHR в <body>
Выполняется XMLHttpRequest к CSS-файлу, затем содержимое последнего вставляется через innerHTML в <body> документа. Случай был выбран просто как базовый, потому что большое число узлов в DOM-дере-ве делает такую операцию сразу менее эффективной, чем вставка в <head>. Да и стили внутри тела документа запрещены стандартами.
// чтобы не копировать всем известный код, запишем так: var xhr = new XMLHttpRequest; if (xhr) { xhr.onreadystatechange = function() { try { if (xhr.readyState == 4) { if (xhr.status == 200) { // вставим полученные данные прямо в <body> document.body.innerHTML += '<style type="text/css">' + xhr.responseText + '</style>'; } } } catch(e){} }; xhr.open("GET", 'styles.css?'+Math.random(), true); xhr.send(null); }Листинг 5.1.
Тут сразу возникает вопрос: как считать применение стилей? Ведь у браузера нет такого события. Немного подумаем и вспомним всем известный и раскритикованный подход с использованием offsetHeight. Он, конечно, будет не самым лучшим выбором, так как добавляет небольшую задержку (пропорциональную числу узлов), но это будет допустимо в рамках выбранного метода (число узлов постоянно для всех измерений).
Итак, для снятия времени применения CSS-правил использовалась следующая конструкция (которая запускалась сразу после обращения к внешнему файлу):
var start = new Date(); var _timer = setInterval(function(){ // находим известный элемент документа и проверяем, // применились ли к нему стили if (document.getElementById('neck').offsetHeight < 300) { // сообщаем о применении alert('CSS files loaded in '+(new Date() - start)); // убиваем таймер clearInterval(_timer); } }, 10);Листинг 5.2.
Конечно, на время загрузки влияют сетевые задержки. Для борьбы с ними (и не только) бралась серия из 15 замеров, и значения, превосходящие текущее среднее более чем в 2 раза, просто отбрасывались (для контроля 3-дельта-выбросов).
Все результаты приведены в конце раздела.
5.1.3. XHR в head
В этом случае код вставлялся уже в <head> и применялся ряд методов для разных браузеров (ибо не все хотели через innerHTML или innerText вставлять полученные данные).
var text = xhr.responseText; var head = document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; // для IE if (style.styleSheet) { style.styleSheet.cssText = text; } else { // для Safari/Chrome if (style.innerText == '') { style.innerText = text; // для остальных else { style.innerHTML = text; } } head.appendChild(style);Листинг 5.3.
5.1.4. Быстрый XHR в head
В следующем варианте проверялось прямое добавление стилевых правил к innerHTML в <head> (для тех браузеров, которые это поддерживают). Оказалось, что это вариант даже медленнее, чем предыдущий.
Если осуществлять это относительно обычного HTML-документа, то DOM-дерево изменяется быстрее (в IE6/7), поэтому на данный момент в общем случае практикуется именно такой подход.
var text = xhr.responseText; var head = document.getElementsByTagName('head')[0]; if (/WebKit|MSIE/i.test(navigator.userAgent)) { var style = document.createElement('style'); style.type = 'text/css'; if (style.styleSheet) { style.styleSheet.cssText = text; } else { style.innerText = text; } head.appendChild(style); } else { head.innerHTML += ''; }Листинг 5.4.
5.1.5. DOM-метод
И, наконец, хит сезона. Добавляем новый файл стилей прямо в <head> при помощи DOM-методов.
var link = document.createElement('link'); document.getElementsByTagName('head')[0].appendChild(link); link.setAttribute('type','text/css'); link.setAttribute('rel','stylesheet'); link.setAttribute('href','style.css');Листинг 5.5.
5.1.6. Результаты
Ниже приведена таблица по исследованным браузерам для всех вариантов. В ней указано время в миллисекундах, прошедшее от начала вызова внешнего файла до окончания применения всех стилей.
Браузер | XHR в <body> | XHR в <head> | Быстрый XHR в <head> | DOM |
---|---|---|---|---|
IE 6 | 482 | 379 | 342 | 335 |
IE 7 | 532 | 364 | 391 | 353 |
IE 8b2 | 370 | 326 | 301 | 284 |
FX 3 | 420 | 294 | 300 | 282 |
Opera 9 | 892 | 894 | 1287 | 764 |
Safari 3 | - | 308 | 286 | 296 |
Chrome | - | 349 | 335 | 367 |
5.1.7. Выводы
Как хорошо видно из таблицы, наиболее быстрым способом для динамического добавления стилей в документ являются DOM-методы почти во всех случаях. Для Safari/Chrome вставка через XHR и специальные методы оказываются быстрее (но не намного). Отдельно хочется отметить довольно медленную работу Opera в таких задачах: по возможности стоит избегать динамических стилей для этого браузера.
Естественно, тут речь идет о выигрышах лишь в десятки и сотни миллисекунд. Но если с самого начала применять самые оптимальные методы при разработке, то ситуаций, когда веб-приложение уже тормозит на несколько секунд (просто загружая процессор на пустом месте), можно будет с легкостью избежать. Ведь на том этапе, когда задержки станут явными, находить и устранять их намного сложнее, чем при изначальном проектировании.