Статьи

Скорость как функция — часть 2

Содержание этой статьи было первоначально написано Крисом Келли в блоге New Relic .  

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

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

Обзор новых реликвий

Эта диаграмма показывает общее время запроса от крупной компании электронной коммерции. (Показано с их разрешения, конечно.) Среднее время ответа составляет 3,3 с. Первые два слоя, синие и желтые, представляют собой время рендеринга внешнего интерфейса. Третий слой коричневого цвета — это время, проведенное в сети. И последний слой, показанный фиолетовым, — это сервер приложений. Время сервера приложений включает в себя все, от вызовов базы данных до рендеринга шаблона, и занимает в среднем всего 112 мс. Таким образом, из всех 3300 мс запроса только 3,3% расходуется на сервере приложений. Конечно, это только потому, что приложение было точно настроено, имеет хорошее кэширование, а база данных имеет правильную загрузку и индексы. Тем не менее, это показывает, что есть вероятность улучшения за пределами прикладного уровня. По факту,большинство потребительских веб-приложений проводят 60–80% времени на внешнем уровне. И именно там мы проведем наше время в этом посте.

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

Keynote ознакомился с данными о производительности во время отключения Facebook в конце мая. Они обнаружили, что даже такие компании, как CNN и Expedia, слишком тесно связаны с внешними сервисами. Посмотрите на таблицу ниже.

Keynote Facebook Outage

Вы увидите, что по мере того, как время отклика Facebook (пурпурная линия) возрастает, увеличивается и время отклика для страниц CNN и Expedia, содержащих виджет Facebook. Сравните это с USA Today (голубая линия), время отклика которого оставалось неизменным во время отключения. USA Today создала свои страницы с помощью соответствующих автоматических выключателей, чтобы сторонние сервисы не прерывали правильную загрузку своих страниц.

Простая правда о Facebook

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

CSS — ваш новый худший враг
Вы можете не осознавать этого, но ваша (постоянно растущая) коллекция стилей CSS может затягивать время загрузки вашей страницы. Стоян Стефанов провел отличное исследование влияния CSS на критический путь . Он показывает, что браузеры будут блокировать рендеринг (показывая пользователю белую страницу смерти), пока весь экранный CSS не будет загружен. Некоторые браузеры, за исключением Opera и Webkit, даже блокируют рендеринг, пока все другие таблицы стилей также не будут загружены — даже если они не используются!

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

И хотя может показаться, что самое простое решение — просто поместить свою таблицу стилей печати в глобальный заголовок и назвать ее днем, помните, что вы передаете эти стили всем, независимо от их использования. Если есть возможность, создайте отдельный макет для печатного содержимого, который загружает таблицу стилей печати. Мобильные пользователи являются наиболее быстро растущим сегментом веб-трафика, и их пропускная способность очень высока. Вы должны исключить таблицу стилей печати при раздаче страниц этим пользователям, поскольку маловероятно, что они будут печатать со своего устройства (извините, AirPrint).

Ваш CSS, вероятно, растет пропорционально вашему сайту. Когда вы добавляете новые функции и страницы, вы, вероятно, добавляете больше стилей. Однако обратное вряд ли будет справедливо. Если вы удалите функцию, стили, скорее всего, будут зависать. Наличие неиспользованных стилей имеет два эффекта. Во-первых, вы переносите ненужный контент в браузер, занимая драгоценное сетевое время. Во-вторых, и что более важно, механизм CSS браузера берет каждый стиль и ищет дерево документа HTML, пока не найдет совпадение. Если совпадений не найдено, стиль отбрасывается. Когда ваша таблица стилей заполнена неиспользуемыми селекторами, анализатор тратит время на поиск совпадений. Опять же, это оказывает значительное влияние на мобильных пользователей с устройствами, оснащенными ограниченным процессором. Хорошая организация ваших таблиц стилей может помочь вам легко изменить их при изменении функций. Инструменты какSass , LESS и конвейер ресурсов Rails (или его эквивалент в других языках) действительно могут помочь в этой организации.

Чем меньше, тем быстрее
Хотя неиспользуемые селекторы тратят впустую циклы процессора, они также тратят время сети. После того, как вы очистите свои таблицы стилей, вы захотите сделать их как можно меньше для отправки клиенту. Все CSS должны быть уменьшены и сжаты перед отправкой их в браузер. Препроцессоры CSS, такие как Sass и Django Compressor , могут взять на себя тяжелую работу из этого в противном случае неуклюжего процесса. Комбинируйте минимизированные таблицы стилей со сжатием на стороне сервера, и у вас получится машина для доставки в экономном стиле

Сжатие Gzip, которое может сэкономить до 40% пространства и в основном бесплатное в Nginx и Apache. Чтобы добавить сжатие gzip в конфигурацию Nginx, просто добавьте следующие директивы:

http {
  ...
  gzip on;
  gzip_disable "MSIE [1-6]\.(?!.*SV1)";

Обратите внимание, что мы отключили сжатие для браузеров, которые не могут получать ресурсы gzip, например IE 6. Существует множество других настроек, которые вы можете настроить для своего сервера, поэтому обязательно прочитайте полную документацию по модулю Gzip . Добавить сжатие в Apache 2 с помощью модуля Deflate так же просто.


AddOutputFilterByType DEFLATE text / css

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

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

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