Пример веб-производительности

http://chimera.labs.oreilly.com/books/1230000000545/ch10.html
  • Перевод
В любой сложной системе процесс оптимизации по большей части состоит из распутывания связей между различными слоями системы, каждый из которых обладает собственным набором ограничений. До сих пор мы рассматривали ряд отдельных сетевых компонентов детально — различные физические средства и протоколы передачи данных. Сейчас мы можем обратить наше внимание на более широкую, всеобъемлющую картину оптимизации веб-производительности:

  • влияние задержки и пропускной способности на веб-производительность;
  • ограничения, которые протокол TCP накладывает на HTTP;
  • особенности и недостатки самого протокола HTTP;
  • тенденции развития веб-приложений и требования к производительности;
  • ограничения браузеров и возможность оптимизации.

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


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


Гипертекст, веб-страницы и веб-приложения


В результате эволюции Интернета за последние несколько десятилетий мы получили три разных подхода к представлению информации в сети:

  • гипертекстовый документ.
  • веб-страница с различными формами медиа-контента.
  • интерактивное веб-приложение.

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

Гипертекстовые документы

Гипертекст лежит в основе всемирной паутины в виде обычного текста с некоторыми базовыми возможностями форматирования и поддержкой гиперссылок.

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

Веб-страница

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

Веб-приложение

Добавление JavaScript, позднее введение поддержки революционных Dynamic HTML (DHTML) и AJAX встряхнуло индустрию и превратило простые веб-страницы в интерактивные веб-приложения, что позволило реагировать на запросы пользователя непосредственно в браузере. Все это проложило путь для первых реализаций полноценных браузерных приложений. Например, Outlook Web Access (c этого началась поддержка XMLHTTP в IE 5). Можно сказать, что это стало началом новой эры сложных связей между скриптами, каскадными таблицами стилей и разметки.

Сессия в HTTP 0.9 может быть представлена из запроса одного документа, которого достаточно для корректного отображения гипертекста. Один документ, одно TCP-подключение, затем сброс соединения. Исходя из вышеизложенного, нетрудно представить процесс оптимизации, он был очень прост. Все, что требовалось — это улучшить производительность одного HTTP-запроса для недолгого TCP-подключения.

Появление веб-страниц изменило эту формулу. От запроса/получения одного документа мы перешли к запросу документа и зависимых от него ресурсов. В HTTP 1.0 было введено понятие метаданных (заголовки), в HTTP 1.1 понятие расширяется с указанием различных директив, которые ориентированы на производительность. К примеру, строго определенное кеширование, KeepAlive и многое другое. Таким образом, мы получаем несколько одновременных TCP-подключений и ключевым показателем производительности document load time уже не является. Принято оценивать page load time, сокращенно PLT.

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

Следовательно, такой параметр, как page load time, который раньше имел определяющее значение при анализе веб-производительности, уже не является достаточным для оценки производительности. Мы больше не создаем просто веб-страниц, мы строим изменчивые, динамические, интерактивные веб-приложения.

Вместо PLT сейчас нас интересуют ответы на следующие вопросы:
  • Каковы основные этапы в процессе загрузки приложения?
  • Когда именно требуется первый запрос от пользователя?
  • Какие именно запросы необходимы от пользователя?
  • Какова скорость вовлечения и конверсии каждого пользователя?

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

DOM, CSSOM, и JavaScript


Что именно мы подразумеваем под «сложной зависимостью скриптов, стилей и разметки» в современном веб-приложении? Чтобы ответить на этот вопрос, мы должны вникнуть в архитектуру браузера, понять, как разметка, стили и скрипты должны собраться вместе, чтобы нарисовать пиксели на экране.

Browser processing pipeline: HTML, CSS, Javascript
Процесс парсинга в браузере

Парсинг HTML-документа — это процесс сборки в соответсвии с объектной моделью документа (DOM). Также мы часто забываем, что используются еще и объектная модель каскадных таблиц стилей (CSS Object Model), которая строится по заданным правилам стилей и ресурсов. Эти двое объединяются и создается так называемый render tree, которого достаточно браузеру для визуализации чего-либо. Пока все хорошо. Но, к сожалению, именно сейчас мы должны представить нашего лучшего друга и одновременно врага: JavaScript. Выполнение скрипта может выдать синхронный doc.write, что блокирует парсинг и сборку DOM. В точности также скрипты могут запросить вычисляемые стили любого объекта и это блокирует выполнение CSS. Сборка DOM и объектов CSSOM часто переплетается: сборка DOM невозможна пока JS выполняется и выполнение JS не может продолжаться пока доступен CSSOM. Производительность приложения, особенно первая загрузка и “время для рендеринга” напрямую зависит от того насколько проблема связей между разметкой, стилями и скриптами будет успешно решена.

Кстати, помните это популярное правило — сначала стили, после скрипты?
Теперь вы понимаете почему! Выполнение скрипта блокируется на уровне стилей, поэтому отдайте CSS пользователю так быстро, как только сможете.

Анатомия современного веб-приложения


Что же все-таки такое современное веб-приложение? HTTP Archive может помочь нам ответить на этот вопрос. Этот проект отслеживает, как построен веб, периодически обращаясь к самым популярным сайтам (300 000 + от Alexa Top 1М) для записи и анализа количества ресурсов, которые используются, видов контента, заголовков и прочих метаданных.

В среднем для работы веб-приложения необходимо следующее:
  • 90 запросов, от 15 хостов, с 1311 КБ общего объема.
  • HTML: 10 запросов, 52 Кб
  • Изображения: 55 запросов, 812 КБ
  • JavaScript: 15 запросов, 216 Кб
  • CSS: 5 запросов, 36 Кб
  • Другое: 5 запросов, 195 Кб

Пока вы это читали цифры изменились и выросли еще, есть стабильная и надежная тенденция роста без признаков остановки. В среднем, современное веб-приложение занимает больше 1 Мб и состоит примерно из 100 разных ресурсов, которые поставляются более чем с 15 разных хостов!

Average transfer size and number of requests (HTTP Archive)
Средний размер и число запросов (HTTP Archive)

В отличие от настольных решений, веб-приложение не требует отдельного процесса установки. Введите URL, нажмите Enter и готово! Однако, настольные приложения можно установить только однажды и забыть в дальнейшем о процессе установки. Когда веб-приложения “устанавливается” всякий раз, когда мы посещаем тот или иной адрес в сети — происходит загрузка ресурсов, сборка DOM и CSSOM, выполнение js-скриптов. Неудивительно, что веб-производительность — горячая и злободневная тема для обсуждения!
Сотни ресурсов, мегабайты данных, десятки хостов, все это должно объедениться в сотни миллисекунд и дать возможность мгновенной работы в Сети.

Скорость, производительность, и человеческое восприятие


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

Время и ожидание пользователя:
  • 0-100 мс — мгновенно
  • 100-300 мс — слегка уловимая задержка
  • 300-1000 мс — ощутимая задержка
  • 1000+ мс — пользователь переключает контекст на что-то еще
  • 10 000+ мс — задача отклоняется

Мы можем назвать работу приложения мгновенной, если ответ на действие пользователя предоставляется в течение сотен миллисекунд. Через секунду и более внимание пользователя рассеивается и взаимодействие с приложением уже не столь плотное. Если проходит 10 секунд, а обратной связи не было, то чаще всего от задачи просто отказываются.
Сложите задержку сети из-за поиска DNS, открытия TCP-подключения и еще нескольких передач туда и обратно и многое, если не все, из указанных миллисекунд будет потрачено просто на сетевое взаимодействие. Не удивительно, что многие пользователи, особенно когда дело касается мобильной или беспроводной сети, требуют более высокую производительность веб-браузера!

Веб-производительность в долларах и центах

Скорость это особенность вашего приложения. Нет смысла улучшать показатели загрузки просто ради скорости. Исходя из исследований Google, Microsoft и Amazon можно сделать вывод, что все они переводят показатели веб-производительности в доллары и центы. Например, задержка 2000 мс на страницах Bing не позволила Microsoft получить доход с каждого пользователя больше на 4,3%!

Исследования более 160 организаций показывают, что дополнительная секунда времени загрузки приводит к потерям в 7% конверсии, 11% от просмотров страниц, удовлетворенность клиентов понижается на 16%.

Быстрый сайт дает больше просмотров, высокий уровень вовлеченности и конверсии. Но не верьте нам на слово! Лучше укрепите веру практическим путем, оцените как производительность вашего сайта влияет на конверсию.

Анализируем график загрузки данных: эффект водопада


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

WebPageTest.org — это свободный проект, который предосталяет веб-сервис для тестирования производительности веб-страниц. Одна из особенностей в том, что тестирование происходит с нескольких локаций. В виртуальной машине запускается браузер, который может быть настроен для работы с рядом подключений. Результаты тестистирования доступны сразу в наглядном веб-интерфейсе, что делает WebPageTest незаменимым инструментом для веб-разработчика.

Для начала важно понять, что каждый HTTP-запрос состоит из нескольких отдельных стадий: поиск DNS, открытие TCP-подключения, TLS-обмен (опционально), отправка HTTP-запроса и затем загрузка контента.

Components of an HTTP request (WebPageTest)
Компоненты HTTP–запроса (WebPageTest)

Тщательный анализ показывает, что время загрузки главной страницы Yahoo! занимает 683 мс, что интересно — более 200 мс потрачено ожиданиeм сети, что составляет 30% от общего времени! Тем не менее, запрос документа – это только начало. Как мы знаем, современное веб-приложение нуждается и в других разнообразных ресурсах.

Yahoo.com resource waterfall
График загрузки страницы Yahoo.com

Для загрузки домашней страницы Yahoo! браузер запрашивает 52 ресурса с 30 разных хостов. Размер ресурсов составляет 486 KB в общей сложности.

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

Таким образом, порядок запросов и получения контента определяется в значительной мере разметкой. Браузер может изменять приоритеты запросов, но дополнительное открытие каждого ресурса в документе создает на графике так называемый “эффект водопада”.

Далее, обратите внимание, что элемент “Начать рендеринг” (вертикальная зеленая линия) расположен гораздо раньше, чем заканчивается загрузка ресурсов. Это говорит о том, что визуализация содержимого начинается на раннем этапе, что позволяет пользователю быстро начать взаимодействовать со страницей, когда ее загрузка еще не завершена. К слову, отметка “Загрузка документа окончена” также расположена раньше, чем фактическое окончание загрузки всех ресурсов. Другими словами, пользователь можем заниматься своими делами, но загрузка дополнительного контента (к примеру реклама или виджеты) будет продолжаться в фоновом режиме.

Указанная выше разница между началом рендеринга, отметкой “документ загружен” и фактическим завершение загрузки контента, отлично свидетельствует о том, что необходимо верно понимать контекст при обсуждении метрик веб-производительности. Какой из этих трех показателей является правильным для отслеживания? Секрет в том, что однозначного ответа нет: каждое веб-приложение использует разные подходы к загрузке контента. Yahoo! решили оптимизировать страницы так, чтобы пользователь мог работать, не дожидаясь, когда загрузка будет завершена. При этом им пришлось уяснить точное понимание важности и приоритетности ресурсов, что может быть загружено раньше, а что позднее.

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

Сетевой график — это мощный инструмент, который может помочь в тестировании оптимизации любой страницы и приложения. Предыдущий график ресурсов часто называют анализом фронт-энда приложения. Однако многих это вводит в заблуждение. Это может показать, что вся проблема производительности заключается только в клиенте. Тем не менее, несмотря на то, что выполнение JS, CSS и процесс рендеринга является критическим и ресурсоемким этапом, работа над откликом сервера и уменьшение сетевых задержек имеет не менее важное значение для оптимизации производительности. В конце концов, сколько бы сил вы не вложили в оптимизацию содержимого, в этом мало пользы, если ресурс недоступен в сети!

Для демонстрации этого, мы перейдем в connection view на графике от WebPageTest.

Yahoo.com connection view
Сетевой график (connection view) Yahoo.com

В отличие от графика ресурсов, где каждая запись описывает конкретный HTTP-запрос, на сетевом графике показано каждое TCP-соединение. В этом примере все 30 из них используются для загрузки ресурсов главной страницы Yahoo!.. Что-нибудь выделяется? Стоит обратить внимание, что время загрузки, которое выделено синим цветом, является лишь малой долей общего времени соединения. Можно увидеть, что было 15 запросов поиска DNS, 30 раз происходило открытие TCP-соединения и множество сетевых задержек вызванных ожиданием первого байта ответа.

На последок мы оставили самое интересное. Настоящим сюрпризом для многих может стать то, что находится в нижней части сетевого графика: рассматривается использование пропускной спобности канала. За исключением нескольких коротких пакетов, использование доступного канала выглядит очень незначительным: мы не ограничены пропускной способностью нашего канала! Это аномалия или ошибка браузера? К сожалению, ни один ответ не явлется правильным. Оказывается, мы ограничены не шириной канала. Проблема в задержках между клиентом и сервером.

Столпы эффективности: Вычисление, Визуализация, Распространение


Выполнение веб-приложения, прежде всего, включает в себя три задачи: выборка ресурсов, построение страницы и визуализация, а также выполнение JavaScript. Этапы визуализации и выполнения сценариев следуют однопоточной, чередующейся модели исполнения; выполнение параллельных модификаций полученной объектной модели документа (DOM) невозможно. Следовательно, оптимизация как визуализация и выполнение сценариев, работающих одновременно, как мы видели в “DOM, CSSOM, and JavaScript”, имеет решающее значение.

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

Скорость работы Интернет становится все быстрее с каждым днем, так не решится ли эта проблема сама собой? Да, наши приложения становятся больше, но если глобальная средняя скорость уже 3,1 Мбит («Пропускная способность на границе сети”) и продолжает расти, то о чем беспокоиться, не так ли? К сожалению, как вы могли бы предположить, и как показывает пример Yahoo!, если бы это было так, то вы бы не читали эту статью. Давайте посмотрим внимательнее.

Большая пропускная способность не имеет (большого) значения

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

Потоковое видео высокой четкости с домашней страницы Yahoo! ограничено пропускной способностью. Загрузка и визуализация домашней страницы Yahoo! ограничивается задержкой.

В зависимости от качества и кодировки видео, которое вы пытаетесь воспроизвести, вам может понадобиться где угодно от нескольких сотен килобит до нескольких Мбит мощности пропускной способности, например, 3+ Мбит для видеопотока HD 1080p. Такая скорость передачи данных теперь в пределах досягаемости для многих пользователей, о чем свидетельствуют растущая популярность сервисов потокового видео, таких как Netflix. Почему же тогда загрузка гораздо более маленького веб-приложения могла бы стать такой проблемой для соединения, способного на потоковое воспроизведение фильма в высоком разрешении?

Задержки, как горлышко производительности

Давайте посмотрим на результаты количественного анализа времени загрузки страниц в зависимости от изменения пропускной способности канала и задержек, выполненного Mike Belshe, одним из создателей протокола SPDY и одним из разработчиков протокола HTTP 2.0:

Page load time vs. bandwidth and latency
В первом тесте задержки в загрузке страницы достаточно постоянные, хотя пропускная способность канала увеличивается с 1 до 10 мегабит в секунду. Заметьте, что апгрейд канала с 1 до 2 мегабит дает значительный прирост скорости загрузки, чего не происходит так значительно далее. Апгрейд с 5 до 10 мегабит дает только 5% ускорения загрузки в каждую итерацию.

Тем не менее, эксперимент с задержками показывает нам совсем другую картину: на каждые 20 миллисекунд задержки мы получаем линейное уменьшение скорости загрузки страницы!

Чтобы ускорить Интернет в целом, мы должны посмотреть на способы уменьшения задержек. Что, если мы сможем уменьшить кросс-атлантические задержки со 150 до 100 мс? Это даст больший эффект для скорости доступа в Интернет, чем увеличение пропускной способности канала с 3.9 мбит до 10 или даже до гигабита. Другой подход к уменьшению времени загрузки страницы должен уменьшить количество запросов, требуемых для загрузки страницы. Сегодня веб-страницы требуют значительного количества соединений между клиентом и сервером. Количество запросов в оба конца связано в значительной мере со служебным обменом данными для начала коммуникации между клиентом и сервером (например в DNS, TCP, HTTP) и так же на это влияет например медленный старт TCP. Если мы сможем улучшить протоколы для передачи данных с меньшим количеством соединений, мы так же сможем увеличить скорость загрузки страниц. Это одна из целей SPDY.
Mike Belshe.


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

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

Синтетические и пользовательские тесты производительности

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

В общих чертах, синтетическое тестирование применяется к любому процессу в управляемых условиях измерения: локальный процесс сборки запускается через ПО проверки производительности, нагрузка тестируется против промежуточной инфраструктуры или набора гео-распределенных серверов, которые периодически запускают набор скриптованных действий и логгируют вывод. Каждый из этих тестов может проверять разные части инфраструктуры (к примеру, пропускную способность сервера приложения, производительность базы данных, тайминг DNS и т.д.), и служит устойчивой основой для определения падения производительности в конкретном компоненте системы.

Хорошо настроенное синтетическое тестирование предоставляет контроллируемое и воспроизводимое окружение тестирования, что делает его отлично подходящим для выявления и исправления падений производительности до того, как они дойдут до конечного пользователя. Подсказка: определите ключевые показатели производительности и выделите „бюджет“ (мощность) для каждого, как часть вашего синтетического тестирования. Если „бюджет“ превышен, бейте тревогу!

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

Некоторые способствующие этому факторы включают в себя:
  • Сценарий и выбор страниц: копировать пути навигации реального пользователя сложно.
  • Кэш браузера: производительность может широко варьироваться в зависимости от кэша пользователья
  • Посредники: производительность может варьироваться в зависимости от промежуточных прокси и кэшей.
  • Разнообразие железа: широкий спектр производительности CPU, GPU, и памяти.
  • Разнообразие браузеров: широкий спектр версий браузеров, новых и старых.
  • Соединение: постоянно меняющаяся скорость и частота реальных подключений.

Объединение этих и аналогичных факторов означает, что в дополнение к синтетическому тестированию, мы должны улучшать нашу стратегию производительности вместе с измерениями со стороны реальных пользователей (real-user measurment, RUM), чтобы определить текущую производительность нашего приложения для конечного пользователя. Хорошая новость состоит в том, что W3C Web Perfomance Working Group упростили эту часть нашего процесса сбора данных, представив API тайминга навигации (Navigation Timing Api), который теперь поддерживается между многими соверменными десктопными и мобильными браузерами.

User-specific performance timers exposed by Navigation Timing
Специфические для пользователя счетчики производительности Navigation Timing

Реальное преимущество Navigation Timing заключается в том, что оно раскрывает массу ранее недоступных данных, таких как время соединения DNS и TCP с высокой точностью (в микросекундах) с помощью стандартизированного объекта perfomance.timing в каждом браузере.

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

Анализ информации пользовательских измерений

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

Page load time (skewed) and response time (multimodal) distributions for igvita.com
Скорость загрузки страницы и времени ответа igvita.com

Изображение показывает пример обоих типов выдачи на одном сайте: искаженный вывод времени загрузки страницы и смешанная выдача ответа сервера (2 режима для формирования сервером кэшированной и некэшированной страницы).

Убедитесь, что ваш инструментарий аналитики может предоставить корректные показатели статистики для вашей иформации о производительности. Предыдущие данные были получены от аналитики Google, которая предоставляет гистограмму внутри стандартных отчетов о скорости сайта. Аналитика автоматически получает данные Navigation Timing (скорости навигации), когда установлен трэкер аналитики. Аналогично, существует широкое разнообразие различных вендоров аналитического ПО, которые предлагают получение и отчеты о Navigation Timing.

В дополнение к стандартизации навигационного тайминга, W3C Performance Group так же стандартизировали еще два набора API — User Timing (пользовательский тайминг) и Resource Timing (тайминг ресурсов). Тогда как Navigation Timing показывает производительность только для корневого документа, Resource Timing предоставляет аналогичную информацию о производительности для каждого ресурса на странице, позволяя получить полный профайл производительности страницы. Подобно, User Timing предоставляет простой JavaScript API для отметки и измерить показатели производительности, специфичные для конкретного приложения, при помощи все тех же точных таймеров:
function init() {
  performance.mark("startTask1"); 1
  applicationCode1(); 2
  performance.mark("endTask1");

  logPerformance();
}

function logPerformance() {
  var perfEntries = performance.getEntriesByType("mark");
  for (var i = 0; i < perfEntries.length; i++) { 3
    console.log("Name: " + perfEntries[i].name +
                " Entry Type: " + perfEntries[i].entryType +
                " Start Time: " + perfEntries[i].startTime +
                " Duration: "   + perfEntries[i].duration  + "\n");
  }
  console.log(performance.timing); 4
}

1. Сохраняем отметку с ассоциированным именем.
2. Исполняем код приложения.
3. Повторяем и логгируем данные измерений.
4. Выводим обьект Navigation Timing конкретной страницы.

Сочетание Navigation, Resource и User timing API предоставляет все инструменты нужные для измерения производительности в реальном времени, больше нет никаких оправданий того, почему вы сделали что-либо неправильно. Мы оптимизируем то, что мы измеряем. Синтетическое тестирование и RUM являются дополнительными подходами, они помогут вам определить все проблемные места производительности и дадут представление о том, как пользователь воспринимает ваше приложение.

Пользовательская и основанная на особенностях приложения метрика — ключ к созданию прочной стратегии оптимизации производительности. Нет универсального способа измерить и определить качество пользовательского опыта. Вместо этого, для каждого приложения необходимо определить конкретные этапы развития приложения. Этот процесс требует сотрудничества между всеми сторонами проекта: владельцами, дизайнерами и разработчиками.

Оптимизация браузера


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

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

Document-aware optimization

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

Speculative optimization

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

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

Есть четыре метода, используемые большинством браузеров:

Предварительный выбор ресурсов и определение приоритетов их загрузки

HTML, CSS и JS могут передавать дополнительную информацию для сетевого стека для сообщения относительного приоритета каждого ресурса: ресурсы, которые не позволяют получить другие ресурсы, будут запрашиваться в первую очередь, в то время как низкоприоритетные запросы будут поставлены в очередь.

Предварительное разрешение DNS

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

Предварительное открытие TCP-подключения

После связывания домена с ip хоста браузер может предварительно открыть TCP-соединение, ожидая HTTP-запроса. Если соединение подтверждается, таким же образом можно совершить TCP-рукопожатие.

Предварительный рендеринг

Некоторые браузеры позволяют отрисовать страницы в скрытой вкладке и когда пользователь инициирует запрос, вкладка перестает быть скрытой.

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

Каким же образом можно помочь браузеру? Для начала, нужно обратить внимание на структуру каждой страницы:

  • Ресурсы подобные CSS и JS должны отдаваться как можно раньше.
  • CSS должны отдаваться как можно раньше, чтобы разблокировать рендеринг и выполнение JavaScript.
  • Не слишком важные JavaScript следует отдавать позже, чтобы избежать блокирования сборки DOM и CSSOM.
  • HTML парсится постепенно, поэтому документ необходимо периодически очищать для улучшения производительности.


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

<link rel="dns-prefetch" href="//hostname_to_resolve.com"> 1
<link rel="subresource"  href="/javascript/myapp.js"> 2
<link rel="prefetch"     href="/images/big.jpeg"> 3
<link rel="prerender"    href="//example.org/next_page.html"> 4

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

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

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

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

Документ HTML парсится постепенно. Это означает, что сервер может и должен очищать размеченный документ как можно чаще. Это позволит клиенту перейти к пропущенным важным ресурсам быстрее.

Google Search — один из лучших примеров. Пока браузер клиент разбирает разметку заголовка, поисковый запрос отправляется в поисковый индекс, а остальная часть документа, которая включает результаты поиска, доставляется пользователю, как только результаты будут готовы. На данный момент, динамические части заголовка, такие как имя вошедшего в систему пользователя, заполняются с помощью JavaScript.

Успешного использования Infobox и InfoboxCloud! Пусть сайты и приложения работают быстро и надежно!
Infobox 68,86
Компания
Поделиться публикацией
Комментарии 17
  • –11
    Представляю, как на это смотрят мои коллеги .Net'чики «мы так не можем, это слишком сложно» (
    • 0
      .NET–чики бывают очень разные:) Скиллы не так сильно зависят от стека разработки. Скорее от человека и его желания учиться и наиболее эффективно решать задачи. У .NET просто порог входа небольшой, но и там встречаются гуру. Статья скорее не про «слишком сложно». Это база и знать ее очень полезно.

      С уважением, Юрий Трухин,
      эксперт по облачным технологиям InfoboxCloud
      • 0
        Если так смотреть, то, на мой взгляд, порог выхода из .NET интереснее, нежели чем порог входа.
      • 0
        на самом деле они так никогда не говорят, но .NET MVC это даже близко не MVC, это попаболь и наследие 90ых
      • +13
        Целиком не осилил, много букв. Кроме мысли «latency важна для скорости работы сети», ещё что-то ценное есть?
        • +11
          Напоминает пятничные размышления джуниора о производительности. Предмет опуса не определен, охват широкий, глубина малая, структуры нет и т.д.
          • –8
            Думаю, Илья Григорик с вами не согласен, которого вы смело назвали джуниором www.igvita.com. С уважением, Юрий Трухин.
            • +5
              Шикарный ответ. Из всех аргументов только имена и регалии.

              Попытки обозначить предмет статьи:
              >Пример веб-производительности
              Примеров не наблюдалось. Методики определения производительности какой-то системы тоже. Заголовок явно левый.
              >Поэтому, прежде чем мы углубимся в рассмотрение и анализ передового современного опыта, важно сделать шаг назад и определить, в чем проблема на самом деле: что такое современное веб-приложение, какие инструменты у нас есть, как мы измеряем веб-производительность, и какие части системы помогают и мешают нашему прогрессу.
              Как и что мерить — первые вопросы должны быть. Здесь они не то что не раскрыты, само понятие производительности размыто.

              Ну и т.д. Даже ваш ответ смахивает на копию из внутренней почты %)
              • –2
                Если вы не заметили, статья — перевод главы, показавшейся нам и нашим пользователям очень важной, из книги «High Performance Browser Networking». Ссылка на оригинал доступна в конце статьи в футере по правилам Хабрахабра. Изменять оригинальный текст нельзя по правилам издательства. Если что-то можно перевести правильнее — с удовольствием поправим. Если у вас есть, что добавить к статье — Хабрахабр позволяет писать статьи и мы с удовольствием добавим ссылку на ваше добавление в конец статьи, если оно ценное.

                Критиковать всегда гораздо проще, чем что-то сделать.
                С уважением, Юрий Трухин.
                • +2
                  То что это перевод я вижу, и проблема не в переводе (хотя можно было добавить примечания уточняющие контекст). Само содержание неструктурированный поток мыслей. Пример я приводил.

                  > Критиковать всегда гораздо проще, чем что-то сделать.
                  Пожалуйста, без дет. садовских сцен. Вы и так не конструктивны, Юрий.
                  • 0
                    Ну так, если Вы изначально видите некоторые проблемы в статье, то не лучше было бы переписать её с нуля, а оригинал взять как основной источник? А не слепо идти по правилам хабра, что если это перевод, то и так потянет.
                  • +1
                    Хотите глубже — можете прочитать книжку Ильи http://chimera.labs.oreilly.com/books/1230000000545

                    Ну и видео поинтереснее статьи http://vimeo.com/71362583
                    • 0
                      Спасибо, Олег. Ценное замечание.
                      • +1
                        Вы забыли с уважением подписаться, Игорь Трухин.

                        (На самом деле: пожалуйста, не делайте так, это очень глупо выглядит).
                        • 0
                          Пусть, может в мем войдет.
              • 0
                Ожидал в конце статьи увидеть простую и важную мысль о том, что DNS-запросы, соединения, элементы страниц и все прочее кешируется браузерами, поэтому что действительно имеет значение — это низкое латенси работы веб-приложения и минимизация пинга между пользователем и сервером. Ведь кому как ни вам (хостеру) следует популяризовать эту простую мысль. Главного не увидел. Низачот.
                • 0
                  Это есть в других главах книги. Ну, а когда пользователь в первый раз заходит на сайт, у него кеша нет. И вообще с нынешними скоростями ограниченного в объёме кеша браузера просто не хватает на все сайты. Особенно это касается мобильных браузеров, где кеш очень мал, размера порядка 20 Мб.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое