Опубликован: 16.06.2010 | Уровень: специалист | Доступ: платный
Лекция 2:

Обзор методов клиентской оптимизации

< Лекция 1 || Лекция 2: 12345 || Лекция 3 >

1.5. Увеличение скорости отображения веб-страниц

Даже когда веб-страница и все внешние объекты загружены на компьютер пользователя, браузеру по-прежнему требуется время для того, чтобы разобрать страницу, интерпретировать код HTML и CSS, выполнить код JavaScript. Принимая во внимание особенности работы браузеров на этом этапе, можно достичь существенно более высокой скорости загрузки страницы.

1.5.1. Оптимизация верстки

Разбирая полученный HTML-код, браузер строит дерево документа, содержащее все элементы страницы. Затем, отыскав все взаимосвязимежду элементами этого дерева и CSS-селекторами, относящимися к данной странице, он применяет к документу стили.


Если на веб-странице присутствует большое количество элементов или объем CSS-кода достаточно велик, страница может прорисовываться с ощутимой задержкой. Когда объем кода уменьшить уже невозможно, более высокой скорости загрузки можно достичь за счет эффективной верстки. Основные рекомендации к верстке следующие.

  • Наиболее важное содержимое страницы должно находиться в самом начале HTML-документа. Так пользователи смогут начать взаимодействовать с этим содержимым раньше. I Актуальные размеры изображений и ячеек таблиц, содержащих большое количество данных, должны быть явно заданы при помощи HTML-аттрибутов или CSS-свойств. Это позволит избавиться от лишних перерисовок веб-страницы. Например, когда браузер загрузит изображение и определит его размер, ему не потребуется обновлять макет веб-страницы, для изображения уже будет зарезервировано необходимое пространство. Кроме того, точно заданные размеры изображения избавят браузер от избыточной операции масштабирования изображения на лету. I Следует отказаться от использования CSS-expressions для браузеров Internet ExpLorer. Expressions отрицательно влияют на производительность браузера и в большинстве ситуаций могут быть заменены более производительным JS-кодом, а иногда и вовсе альтернативной версткой. В ситуациях же, когда для требуемой функциональности сайта использования expressions не избежать, следует применять одноразовые expressions. I Следует использовать быстродействующие селекторы идентификаторов и селекторы классов. Поскольку большинство браузеров анализируют селекторы справа налево, с виду простой селектор #header .menu li a будет применяться дольше, чем аналогичный ему селектор #header .menu-item. В первом случае браузеру необходимо будет найти все ссылки на странице, проверить, находятся ли они в контексте элемента списка, элемента с классом menu и, наконец, элемента с идентификатором header. Второй вариант более предпочтителен, поскольку поиск элементов по классу и идентификатору выполнится существенно быстрее.
  • Универсальные, дочерние, соседние селекторы, селекторы атрибутов, псевдоклассов и псевдоэлементов должны применяться только в тех ситуациях, когда это действительно необходимо. Все эти разновидности CSS-селекторов существенно более ресурсоемки, чем селекторы идентификаторов или классов.

1.5.2. Особенности отображения веб-страниц

При изменении ряда свойств элементов веб-страницы, а также в некоторых других ситуациях браузеры производят перерасчет геометрии и положения элементов, находящихся в потоке веб-страницы, после чего заново перерисовывают страницу или ее часть. Если веб-страница достаточно сложна, ее обновление будет заметно для пользователя и неизбежно вызовет задержку в его работе со страницей.

Вот неполный список действий, вызывающих в большинстве браузеров перерисовку страниц или их частей:

  • изменение пользователем размера окна браузера или шрифта;
  • добавление или удаление CSS-кода (как встроенного, так и во внешнем файле);
  • манипуляции с элементами DOM-дерева;
  • изменение следующих свойств элементов страницы: class, font, display, visible, margin, padding, width, height;
  • активация псевдоклассов, таких, например, как :hover.

Учитывая эти особенности, можно свести к минимуму число перерисовок страниц, а для того чтобы скорость перерисовок была наивысшей, необходимо:

  • обеспечить минимальную глубину и минимальный размер DOM-дерева, так как часто изменения свойств какого-либо элемента вынуждают браузер перерисовать не только сам этот элемент, но также родительские и дочерние элементы, а иногда и всю ветвь целиком;
  • оптимизировать CSS-селекторы, обеспечить минимальный объем CSS-кода;
  • создавать сложные элементы, анимировать их и производить другие подобные манипуляции над элементами, располагая их вне потока и используя для этого свойства position: absolute и position: fixed ;
  • изменять классы и стили у элементов на максимальной глубине DOM-дерева, что позволит браузеру перерисовывать лишь часть страницы;
  • избегать использования таблиц в верстке, поскольку действия над их ячейками почти всегда вызывают необходимость перерасчитать и перерисовать всю таблицу целиком.

1.6. Оптимизация структуры веб-страниц


От структуры HTML-документа во многом зависит скорость загрузки страницы пользователем. Даже при одинаковом суммарном размере страниц и равном количестве внешних объектов две различные страницы могут загружаться за совершенно разное время. Причина в том, что отображение элементов частично загруженной страницы в большинстве браузеров осуществляется только после выполнения следующих шагов:

  1. получения HTML-документа;
  2. получения всех внешних объектов CSS, вызываемых в HTML-документе;
  3. получения всех внешних объектов JavaScript, вызываемых в HTML-документе внутри тега <head> ;
  4. получения всех внешних объектов JavaScript в HTML-документе внутри тега <body>, расположенных в потоке выше выводящегося элемента.

1.6.1. Особенности загрузки браузерами внешних объектов

Особенности загрузки кода CSS

В большинстве браузеров отображение страницы будет приостановлено до тех пор, пока все внешние CSS-файлы не будут загружены. Кроме того, теги <style>, встречающиеся на странице, будут порождать частичную или полную перерисовку страницы, иногда изменяя уже отобразившийся макет, с которым пользователь мог начать взаимодействовать.

Таким образом, более высокой скорости отображения страницы можно добиться, располагая в самом начале веб-страницы, в разделе <head>, все элементы <link>, содержащие вызовы файлов CSS-стилей, а также все встроенные стили, содержащиеся в тегах <style>.

Особенности загрузки кода JavaScript

Из-за того, что код JavaScript может изменять содержимое и макет веб-страницы, браузеры приостанавливают отображение элементов, следующих за JS-кодом, до тех пор, пока код не будет загружен и исполнен. Большинство браузеров при этом приостанавливают даже загрузку внешних объектов,следующих за таким JS-кодом. Однако если на момент начала загрузки JS-файла загрузка внешних объектов уже была начата, они будут загружены параллельно.

Подробный разбор возможной ситуации

В приведенном ниже примере на веб-странице загружаются два внешних файла CSS и JS.

<head>
<script type="text/javascript" src="script-1.js"></script> 
<link rel="stylesheet" type="text/css" href="style-1.css" /> 
<script type="text/javascript" src="script-2.js"></script> 
<link rel="stylesheet" type="text/css" href="style-2.css" /> 
</head>
Листинг 1.6.

При таком порядке следования в документе и при пустом кэше большинство браузеров будет вынуждено дождаться загрузки первого файла JavaScript, только потом начать загрузку следующих двух файлов CSS и JS и лишь по завершении загрузки второго файла JS загрузить последний файл стилей.

Всего лишь изменив порядок следования вызовов внешних объектов так, чтобы впереди были вызовы файлов CSS, можно получить ощутимый выигрыш в скорости загрузки.

<head>
<link rel="stylesheet" type="text/css" href="style-1.css" /> 
<link rel="stylesheet" type="text/css" href="style-2.css" />
<script type="text/javascript" src="script-1.js"></script> 
<script type="text/javascript" src="script-2.js"></script> 
</head>
Листинг 1.7.

В этой ситуации браузер может инициировать параллельную загрузку сразу трех внешних объектов — двух файлов стилей и первого файла JS. По окончанию их загрузки браузеру остается загрузить лишь один файл JavaScript, и итоговое время загрузки будет ощутимо ниже.

Как видно на приведенной ниже диаграмме, в первой ситуации загрузка каждого файла JavaScript блокирует получение остальных внешних объектов, создавая дополнительные задержки. Во второй же ситуации вместе с загрузкой первого файла JS происходит параллельная загрузка максимально возможного количества внешних объектов.

Диаграмма загрузки внешних объектов при различном порядке их вызовов

увеличить изображение
Рис. 1.12. Диаграмма загрузки внешних объектов при различном порядке их вызовов

Разумеется, экономия времени в каждом отдельном случае будет зависеть от размеров загружаемых объектов и их количества, однако пренебрегать этой особенностью не стоит.

Следует помнить, что данная особенность неактуальна в браузерах, поддерживающих параллельную неблокирующую загрузку внешних объектов. Перечень таких браузеров можно получить при помощи инструментов, описанных чуть ранее в этой лекции.

1.6.2. Стадии загрузки страницы

Во всех браузерах можно выделить несколько основных стадий загрузки страницы. Рассмотрим эти стадии.

  1. Предварительная загрузка — предварительное отображение частично загруженной страницы без части рисунков и, в ряде случаев, без интерактивности, без части JavaScript-сценариев.
  2. Полная загрузка страницы — отображение полностью загруженной страницы со всеми изображениями, с полностью функционирующими интерактивными частями страницы, полностью функционирующей логикой JavaScript.

Чтобы ускорить наступление предварительной загрузки, следует снизить число вызываемых в заголовке страницы файлов до минимума, применить к ним динамическое сжатие, или, для еще большего быстродействия — статическое сжатие. При использовании статического сжатия серверу не придется тратить дополнительное время на сжатие, он будет сразу готов отдать сжатый файл.

Загрузку файлов, не требующихся на стадии предварительной загрузки, имеет смысл перенести в стадию пост-загрузки.

Итогом первой стадии загрузки является доставленный и оформленный HTML-документ, с которым пользователь уже может взаимодействовать. Издержки на доставку всех файлов JavaScript должны быть сведены к минимуму, так как на этом этапе они только помешают, замедлив отображение основного содержимого страницы.

Оптимизация стадии полной загрузки

При правильной группировке загружаемых внешних объектов и за счет использования закэшированных браузером объектов эта стадия может наступать значительно быстрее.

Необходимо сконфигурировать веб-сервер так, чтобы при запросе любой другой страницы пришлось запрашивать минимум дополнительных объектов. Должен быть также продуман вопрос форсированного сброса кэша в ситуациях, когда это будет необходимо.

Также при запросе большого количества изображений браузер неизбежно столкнется с ограничением максимального количества соединений на хост, и для обхода этого ограничения необходимо настроить дополнительные серверы для выдачи статического содержимого. Число дополнительных хостов следует напрямую из числа статических файлов, поэтому надо определиться с ними на этапе автоматизации процесса публикации.

На этой же стадии можно использовать прием объединения изображений.

Оптимизация стадии пост-загрузки

К началу этой стадии у пользователя уже должна быть в распоряжении оформленная HTML-страница, на которой все ссылки и формы должны работать без JavaScript.

На этой стадии могут загружаться любые объекты, которые необходимые для этой или каких-либо других страниц.

При помощи специального обработчика JavaScript, который начинает работать на этой стадии, возможно к уже существующей функциональности страницы добавить расширенные возможности в виде подсказок,дополнительных данных с сервера, какой-либо анимации и т. д.

Этот обработчик может производить следующие операции:

  • находить необходимые элементы дерева объектов страницы, требующие динамического вмешательства, подключая все необходимые обработчики, события и т.д.;
  • проверять наличие необходимых JavaScript библиотек и по мере надобности загружать их, проверяя, чтобы один и тот же код не загружался дважды;
  • загружать в фоне внешние объекты, используемые на других страницах.

В случае применения технологии data:URI для уменьшения количества вызываемых объектов на этой стадии необходимо загружать файл CSS, содержащий все используемые на странице изображения в формате base-64.

Об отложенной загрузке ресурсов, не требующихся на момент первого отображения страницы, можно прочитать в пятой главе, а также в седьмой главе книги "Разгони свой сайт".

Прогрессивный подход

Во многих современных браузерах, в частности, в последних версиях браузера Safari, активно внедряется прогрессивная логика отображения страницы.

С одной стороны, браузер не ждет последовательной и полной загрузки всех блокирующих вывод страницы внешних объектов, а с другой — не отображает неформатированную веб-страницу. Сочетая преимущества сразу нескольких подходов, браузер определяет, в какой момент какую часть страницы можно отобразить, чтобы опыт пользователя был наилучшим.

Загрузка всех внешних объектов производится параллельно, и разбор содержимого не останавливается. При этом, если производится обращение к свойству стиля или макета, модуль JavaScript приостанавливает свою работу и ожидает загрузку всех незагруженных файлов CSS. Как только все стили загружены, выполнение сценария продолжается с того места, где оно было приостановлено.

1.6.3. Распределенное хранение контента (CDN)

У всех браузеров существует ограничение на количество соединений на один хост, находящееся в интервале от 2 до 8 соединений на хост. Для увеличения скорости загрузки внешних объектов можно применять распределенную систему хранения и доставки контента (CDN), организовав или арендовав систему хостов, находящихся на одном или нескольких физических серверах (географически распределенных, если это требуется). Часть хостов должны принимать и обрабатывать запросы пользователей, создавать и передавать результирующие HTML-документы. Остальные хосты должны использоваться только для передачи клиентом статических ресурсов. Благодаря такой схеме скорость доставки контента пользователям будет максимальной, в то же время нагрузка на хостинг веб-сайта может значительно снизиться.


Необходимо заметить, что разделять по нескольким хостам имеет смысл только изображения и файлы CSS, так как файлы JavaScript почти во всех браузерах загружаются строго последовательно.

Создать подобную систему распределенного хранения можно либо при помощи автоматического балансировщика, либо установив альтернативные пути к внешним объектам вручную.

Большое число дополнительных хостов может увеличить временные затраты браузера на установление соединений, поэтому в наибольшем количестве ситуаций предпочтительно использование не более 5 дополнительных хостов (1 основной хост и 4 для параллельной загрузки кэширу-емых объектов) без учета не контролируемых вами хостов, например рекламных. Это позволяет ускорить загрузку приблизительно на 60% в случае большого количества файлов.

Подробнее о системах распределенного хранения контента (CDN) рассказано в "Оптимизация структуры веб-страниц" .

< Лекция 1 || Лекция 2: 12345 || Лекция 3 >
Ольга Артёмова
Ольга Артёмова

Доброго времени суток!

Прошла курс, но почему-то диплом получить не могу, хотя курс значится завершенным, хотя обязательные два модуля пройдены. Как решить эту проблему?

Сертификация: оптимизация и продвижение web-сайтов.

Ярославй Грива
Ярославй Грива
Россия, г. Санкт-Петербург
Ёдгор Латипов
Ёдгор Латипов
Таджикистан, Кургантепа