Статьи

Перевод: Николай Мациевский aka sunnybear
Опубликована: 23 апреля 2008

Оптимизация параллельных загрузок для минимизации издержек

Примечание: ниже находится перевод статьи "Optimize Parallel Downloads to Minimize Object Overhead", в которой авторы рассматривают параллельную загрузку объектов, и как она влияет на производительность веб-страницы. Мои комментарии далее курсивом.

Средняя веб-страница содержит более, чем 50 объектов (Krishnamurthy и Wills 2006), при этом издержки на число объектов доминируют над всеми остальными задержками при загрузке большинства веб-страниц (Yuan 2005). Браузеры, следуя рекомендациям спецификации HTTP 1.1, обычно устанавливают не более 2 одновременных соединений (это справедливо только для IE6/7, для Firefox и Opera этот параметр настраиваемый, составляет не меньше 4, по умолчанию. Для IE8, по словам Алекса Могилевского, скорее всего, будет 6) с одним хостом. При увеличении числа HTTP-запросов, требуемых для отображения страницы, с 3 до 23 время, затрачиваемое именно на «чистую» загрузку объектов, от общего времени загрузки падает с 50% до всего 14% (см. Рисунок 1).

Задержки при загрузке большого числа объектов

Рисунок 1: задержки при загрузке большого числа объектов

Если число объектов на странице превышает 4, то издержки на ожидание доступных потоков и разбор чанков для присланных объектов (describing the object chunks) превалируют над общим временем загрузки страницы (от 80% до 86% для 20 и 23+ объектов, соответственно) по сравнению со временем, уходящем на действительную загрузку данных. Время инициализации (description time) плюс время ожидания, вызванное ограничением на параллельные соединения, занимают от 50% до 86% от общего времени загрузки страницы. Chi и Li также указывают на то, что при увеличении числа подключаемых объектов сверх 10 время инициализации (или определения) возрастает до 80% и более от общего времени, уходящего на получение объектов (Chi и Li 2002). Стоит отметить, что вы можете существенно уменьшить издержки на доставку большого числа объектов (более, чем 12 на страницу) включением для сервера keep-alive режима и распределением запросов по нескольким хостам (Hopkins 2007).

Ограничение на параллельные загрузки «душит» браузеры

Спецификация HTTP, приблизительно 1999 года, рекомендует, чтобы браузеры и серверы ограничивали число параллельных запросов к одному хосту двумя (Fielding и др. 1999). Эта спецификация была написана задолго до существенного расширения каналов загрузки и была рассчитана на соединения с маленькой скоростью загрузки. Большинство браузеров поддерживают это ограничение на число потоков в спецификации, хотя переход на HTTP 1.0 увеличивает число параллельных загрузок до 4. Поэтому большинство браузеров серьезно ограничено этим параметром, если им приходится загружать большое число объектов с одного хоста (по словам Алекса Могилевского, в IE8 это число будет равно примерно 6 из-за существенных издержек на установление нового соединения, поэтому хотелось бы дополнительных комментариев: как именно число одновременных соединений с большим количеством хостов (или большого числа соединений с одним хостом) влияет на производительность). Существует два основных пути для обхода этого ограничения (не считая, конечно, тонкой настройки используемого клиентами браузера):

  • Отдавать ваши объекты с нескольких серверов
  • Создать несколько поддоменов для нескольких хостов

Использование нескольких серверов

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

images1.domain.com
images2.domain.com
images3.domain.com

Однако, каждый из этих поддоменов не обязан находится на отдельном сервере.

Использование нескольких хостов на одном сервере

Более элегантным (и практичным) решением будет настройка нескольких поддоменов, которые указывают на один и тот же сервер. Этот метод заставляет браузеры думать, что объекты отдаются с разных хостов, позволяя, таким образом, загружать одновременно более двух объектов с сервера. Например, вы можете выставить:

images1.domain.com domain.com
images2.domain.com domain.com
images3.domain.com domain.com

В записях вашей DNS-зоны. Теперь вы можете обращаться к разным объектам используя разные хосты, даже если объекты эти располагаются на одном сервере. Например:

<img src="http://images1.domain.com/i/balloon.png" alt="balloon">
<img src="http://images2.domain.com/i/flag.png" alt="flag">
<img src="http://images3.domain.com/i/star.png" alt="star">

Все эти URL указывают на:

domain.com/i/

Оптимальное число хостов для минимизации издержек на доставку объектов

Пара исследований, проведенных независимо Yahoo! и Gomez, продемонстрировали, как увеличение числа хостов способно уменьшить задержки при параллельных загрузках. А Steve Souders и Tenni Theurer из Yahoo! выложили отчет о результатах тестов в свом блоге Performance UI (Theurer и Souders 2007). Изменяя число доступных хостов наряду с размером объектов, инженеры из Yahoo! установили, что подключение двух хостов дает самый быстрый отклик для больших файлов (см. Рисунок 2). Theurer выложил график, который содержит более детальную статистику по времени отклика, числу хостов и размеру файлов.

Среднее время отклика в зависимости от числа хостов

Рисунок 2: Среднее время отклика в зависимости от числа хостов

Ryan Breen из Gomez провел ряд тестов в похожих условиях, используя те же самые методы. Он добился 40% ускорения при использовании трех хостов (см. Рисунок 3).

Общее время загрузки в зависимости от числа соединений (2 и 6)

Рисунок 3: Общее время загрузки в зависимости от числа соединений (2 и 6)

Заключение

Сейчас средняя веб-страница состоит из более, чем 50 объектов (для Рунета, по статистическим данным webo.in, кстати, ситуация весьма похожа, но число объектов колеблется в пределах 20–30), поэтому минимизация издержек на доставку объектов является весьма критичной для клиентской производительности. Также можно уменьшить число объектов на странице, если использовать технику CSS sprites, и объединения CSS или JavaScript файлов (а может, даже все в одном) на сервере. Так как в данный момент у пользователей достаточно быстрый канал, то можно достигнуть уменьшения времени загрузки до 40% (авторы немного занижают это число, только использование нескольких хостов способно увеличить скорость загрузки до 4 раз, а это сокращение на 75%). Вы можете использовать 2 или 3 хоста для обслуживания объектов с одного сервера, чтобы обмануть браузеры в их ограничениях на загрузку нескольких объектов параллельно.

Авторы не касаются еще одного, весьма интересного, момента в оптимизации времени загрузки путем увеличения числа параллельных потоков. Заключается он в выравнивании и увеличении размера одновременно загружаемых объектов, чтобы максимально использовать имеющиеся соединения. Например, если у вас есть 40 картинок по 5Кб, то гораздо выгоднее будет отдавать 10 картинок по 20Кб с двух хостов, чем 20 (по 10Кб) с 4 хостов или 40 с 8. Общие задержки в первом случае будут минимальными в силу максимизации эффективной скорости загрузки данных клиенту.

Можно пойти и дальше и загружать, например, 4 картинки по 50Кб в 4 потока, достигая просто феноменального ускорения. Однако, тут вступает в роль психологический фактор: пользователю будет не комфортно, если он будет видеть страницу вообще без картинок все то время, пока грузится 50Кб, и он может просто уйти с сайта.

Хочу подчеркнуть, что данный подход применим и к другим ресурсным (в том числе, и HTML-) файлам, однако, стоит помнить о весьма жестких ограничениях браузеров на загрузку CSS- и JavaScript-файлов (например, при отображении страницы IE грузит последние строго в один поток).

Материал для чтения

  • Breen, R., «Обходим ограничения браузера на число соединений для забавы и пользы», Ajax Performance, 18 декабря, 2006.

    Демонстрируется преимущество использования более двух соединений к одному хосту при оптимизации AJAX-приложений. Достигнуто 40% ускорение при загрузке за счет динамического программного назначения различных поддоменов для объектов.

  • Chi, C. и X. Li, «Исследование доступа к странице на основе загрузки объектов».

    Время соединения (connection time) занимает от 6 до 17% общей задержки при получении веб-объекта (от момента отправки запроса до получения первого байта).

  • Fielding, R. и др., «Протокол передачи гипертекста — HTTP/1.1», консорциум World Wide Web, Июнь 1999.

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

  • Krishnamurthy, B. и C. Wills, «Кошки-мышки: издержки на доставку содержания при доступе к веб-страницам», WWW 2006, 23–26 мая, 2006, Эдинбург, Шотландия.

    При помощи тестового окружения на основе браузера Firefox исследователи установили, что первые 100 сайтов по мнению Alexa в 13 категориях содержат большое количество внешних объектов, которые расположены, преимущественно, на популярных страницах. А блокировка этих объектов может уменьшить их размер и число на 25–30%, а общую задержку при загрузке страницы на 33%. На популярных сайтах содержится в среднем 52 объекта, 8,1 из которых являются рекламными объявлениями, загружаемыми с 5,7 серверов.

  • Theurer, T. и S. Souders, «Исследование производительности, часть 4: максимизация параллельных загрузок в Carpool Lane», блог пользовательских интерфейсов Yahoo!, 11 апреля, 2007.

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

  • Yuan, J., Chi, C.H. и Q. Sun, «Более точная модель для веб-загрузок», WWW 2005, 10–14 мая, 2005, Чиба, Япония.

    Исследователи показали, что время инициализации (Definition Time) и время ожидания (Waiting Time) объектов оказывает существенное влияние на общую задержку при загрузке веб-страниц, хотя это и тотально игнорируется большинством исследований объектного уровня. В зависимости от числа объектов на странице, эти времена в совокупности составляют от 50 до 85% общего времени загрузки. Если число объектов на странице превышает 4, то задержки такого рода доминируют над остальными.

Читать дальше

Перевод: Николай Мациевский aka sunnybear

Все комментарии (habrahabr.ru)