Обведённые на картинке задержки вызваны использованием CDN.
Немного истории
Как и многие технологии, CDN появились по необходимости. При развитии интернет-каналов у пользователей Сети, появились сервисы онлайн-видео. Естественно, что видео-контент требует на порядки большей пропускной способности по сравнению с обычным контентом сайтов (картинки, текст, и CSS или JS-код).
При попытке параллельной трансляции видео-потока множеству клиентов с одного сервера узким местом скорее всего станет интернет-канал сервера. Как правило, достаточно несколько тысяч потоков, чтобы забить типичный канал сервера. Конечно, могут быть и другие ограничения по ресурсам, но сейчас они не важны. Также важно, что расширить канал сервера слишком дорого (а иногда и невозможно), да и нецелесообразно. Нагрузка на канал при трансляциях будет иметь циклический характер.
Проблему ограничения канала отдельного сервера отлично решает CDN. Клиенты подключаются не к серверу напрямую, а к узлам сети CDN. В идеальной ситуации, сервер отдаёт один поток узлу CDN, а дальше сеть использует собственные ресурсы для доставки этого потока множеству пользователей. С точки зрения экономики мы платим только за фактически потреблённые ресурсы (это может быть пропускная способность или трафик) и получаем отличную масштабируемость нашего сервиса. Использование CDN для доставки тяжелого контента полностью оправдано и логично. Хотя стоит заметить, что крупнейшие игроки в этой области (например, Netflix) строят свои CDN вместо использования крупных коммерческих CDN (Akamai, Cloudflare, Fastly и т.д.)
По мере развития веба, сами веб-приложения стали сложнее и тяжелее. На первый план вышла проблема скорости загрузки. Энтузиасты скорости сайтов достаточно быстро вывели несколько основных проблем, которые приводили к медленной загрузке сайтов. Одной из них были задержки в сети (RTT — round trip time или время ping). Задержки влияют на множество процессов в загрузке сайта: установку TCP-соединения, запуск TLS-сессии, загрузку каждого отдельно ресурса (картинки, JS-файла, HTML-документа и т. д.)
Проблема усугублялась тем, что при использовании прокола HTTP/1.1 (до появления SPDY, QUIC и HTTP/2 это был единственный вариант) браузеры открывают не более 6 TCP-соединений к одному хосту. Всё это приводило к простою соединения и неэффективному использованию пропускной способности канала. Проблема частично решалась доменным шардингом – созданием дополнительных хостов для преодоления лимита на количество соединений.
Тут появляется вторая способность CDN – сокращение задержек (RTT) за счет большого количества точек и близости узлов к пользователю. Расстояние здесь играет решающую роль: скорость света ограничена (около 200 000 км/сек в оптоволокне). Значит, каждая 1000 км пути добавляет 5 мс задержек или 10 мс в RTT. Это минимальные расходы времени на передачу, так как есть еще задержки на промежуточном оборудовании. Так как CDN обычно умеет кэшировать объекты на своих серверах, мы можем выиграть от загрузки таких объектов через CDN. Необходимые условия для этого: наличие объекта в кэше близость точки CDN к пользователю в сравнении с сервером веб-приложения (origin server). Важно понимать: географическая близость узла CDN не гарантирует низкие задержки. Маршрутизация между клиентом и CDN может быть построена таким образом, что клиент будет подключаться к хосту в другой стране, а возможно и на другом континенте. Здесь вступают в действие взаимоотношения операторов связи и сервиса CDN (пиринг, наличие стыков, участие в IX и т. д.) и политика маршрутизации трафика самой CDN. Например, Cloudflare при использовании двух начальных планов (бесплатного и дешевого) не гарантирует отдачу контента с ближайшего узла – выбор хоста будет производиться для достижения минимальной стоимости.
Многие ведущие интернет-компании привлекают интерес общественности (веб-разработчиков и владельцев сервисов) к теме скорости загрузки и работы сайтов. Среди этих компаний Yahoo (инструмент Yslow), AOL (WebPageTest) и Google (сервис Page Speed Insights), которые разрабатывают свои рекомендации по ускорению сайтов (прежде всего они касаются клиентской оптимизации). Позднее появляются новые средства тестирования скорости сайтов, которые также дают советы по увеличению скорости сайтов. В каждом из этих сервисов или плагинов присутствует неизменная рекомендация «Используйте CDN». В качестве объяснения эффекта CDN как правило указывается сокращение сетевых задержек. К сожалению, не все готовы разбираться в том, как именно достигается эффект ускорения от CDN и как его можно измерить, поэтому рекомендация принимается на веру и используется как постулат. На самом деле, далеко не все CDN одинаково полезны.
Использование CDN сегодня
Для оценки полезности применения CDN их нужно классифицировать. Что можно встретить сейчас на практике (примеры в скобках конечно же не исчерпывающие):
- Бесплатные CDN для раздачи JS-библиотек (MaxCDN, Google. Yandex).
- CDN сервисов по клиентской оптимизации (например Google Fonts для шрифтов, Cloudinary, Cloudimage для картинок).
- CDN для статики и оптимизации ресурсов в CMS (есть в Битриксе, Wordpress и других).
- CDN общего назначения (StackPath, CDNVideo, NGENIX, Мегафон).
- СDN для ускорения сайтов (Cloudflare, Imperva, Айри).
Ключевое различие этих типов состоит с следующем: какая часть трафика проходит через CDN. Типы 1-3 это доставка только части контента: от одного запроса до нескольких десятков (обычно картинок). Типы 4 и 5 это полное проксирование трафика через CDN.
На практике это означает количество подключений, которые используются для загрузки сайта. При использовании HTTP/2 мы используем одно TCP-подключение к хосту для обработки любого количества запросов. Если мы разделяем ресурсы на основной хост (origin) и CDN, то необходимо разводить запросы по нескольким доменам и создавать несколько ТСP-соединений. В худшем случае это: DNS (1 RTT) + TCP (1 RTT) + TLS (2-3 RTT) = 6-7 RTT. В этой формуле не учитываются задержки в мобильных сетях на активацию радио-канала устройства (если он не был активен) и задержки на сотовой вышке.
Вот как это выглядит на водопаде загрузки сайта (выделены задержки для подключения к CDN при RTT 150 мс):
Если CDN покрывает весь трафик сайта (кроме сторонних сервисов), то мы можем использовать единственное TCP-соединение, экономя задержки на подключении к дополнительным хостам. Конечно, это касается HTTP/2-соединений.
Дальнейшие различия определяются функциональностью конкретной CDN – для первого типа это всего лишь хостинг статического файла, для пятого это изменение нескольких типов контента сайта с целью оптимизации.
Возможности CDN по ускорению сайта
Давайте опишем полный спектр возможностей CDN по ускорению сайтов, без оглядки на функциональность отдельных типов CDN, а потом посмотрим что из этого реализовано в каждом из них.
1. Сжатие текстовых ресурсов
Самая базовая возможность и понятная возможность, тем не менее часто реализована плохо. Наличие сжатия декларируют все CDN в качестве своей фичи по ускорению. Но если посмотреть подробнее, то выясняются недоработки:
- могут использоваться низкие степени для динамического сжатия – 5-6 (например, для gzip максимум — 9);
- в статическом сжатии (файлы в кэше) не используются дополнительные возможности (например, zopfi или brotli со степенью 11)
- нет поддержки эффективного сжатия brotli (экономия примерно 20% по сравнению с gzip).
Если вы используете CDN, стоит проверить эти несколько пунктов: взять файл, который пришёл с CDN, зафиксировать его размер в сжатом виде и пережать вручную для сравнения (можно использовать какой-нибудь онлайн-сервис с поддержкой brotli, например всёсжать.рф).
2. Установка заголовков клиентского кэширования
Также простая фича по ускорению: поставить заголовки для кэширования контента клиентом (браузером). Наиболее актуальный заголовок cache-control, устаревший – expires. Дополнительно может использоваться Etag. Главное, чтобы max-age у cache-control был достаточно большим (от месяца и более), если вы готовы закэшировать ресурс максимально жестко, можно добавить опцию immutable.
CDN могут занижать значение max-age, вынуждая пользователя чаще загружать статику повторно. С чем это связано: с желанием увеличить трафик в сети или повышением совместимости с сайтами, которые не умеют сбрасывать кэш – не понятно. Например, значение времени кэширования в заголовках Cloudflare по умолчанию составляет 1 час, что очень мало для неизменяемой статики.
3. Оптимизация картинок
Так как CDN берёт на себя функции кэширования и отдачи картинок, логично будет оптимизировать их на стороне CDN и в таком виде отдавать пользователям. Сразу оговоримся, эта возможность доступна только для CDN типов 2, 3 и 5.
Оптимизировать изображения можно различными путями: использованием продвинутых форматов сжатия (например, WebP), более эффективными кодировщиками (MozJPEG) или просто очисткой лишних метаданных.
В целом есть два типа таких оптимизаций: с потерей качества и без потери качества. CDN обычно стремятся использовать оптимизацию без потерь – для того, чтобы избежать возможных жалоб клиентов на изменение качества картинок. В таких условиях выигрыш будет минимальным. В реальности часто уровень качества JPEG значительно превышает необходимый и можно смело проводить рекомпрессию с более низким показателем качества, без ущерба для восприятия пользователями. С другой стороны, определить уровень качества и настройки универсально для всех возможных веб-приложений сложно, поэтому CDN используют более консервативные настройки по сравнению с теми, которые можно применить с учетом контекста (назначение картинок, тип веб-приложения и т.д.)
4. Оптимизация TLS-соединения
Большинство трафика сегодня передаётся по TLS-соединениям, а это значит, что мы тратим дополнительное время на TLS-согласование. За последнее время разработаны новые технологии ускорения этого процесса. Например, это EC-криптография, TLS 1.3, кэш сессий и тикеты (session tickets), аппаратное ускорение шифрования (AES-NI) и т. д. Правильная настройка TLS позволяет сократить время соеднинения до 0-1 RTT (не считая DNS и TCP).
При наличии современного софта внедрить такие практики не сложно на собственных мощностях.
Далеко не все CDN внедряют лучшие практики по TLS, проверить это можно путём замера времени TLS-соединения (например в Webpagetest). Идеально для нового соединения — 1RTT, 2RTT — средний уровень, 3RTT и больше – плохо.
Также нужно заметить, что даже при использовании TLS на уровне CDN, сервер c нашим веб-приложением также должен обрабатывать TLS, но со стороны CDN, потому что трафик между сервером и CDN проходит в публичной сети. В худшем случае мы получим двойные задержки TLS-подключения (первая к хосту CDN, вторая между ним и нашим сервером).
Для некоторых применений стоит обратить внимание на вопросы безопасности: обычно трафик расшифровывается на узлах CDN, а это потенциальная возможность для перехвата трафика. Вариант работы без раскрытия трафика обычно предлагается в топовых тарифных планах за отдельную плату.
5. Сокращение задержек подключения
Главное преимущество CDN, о котором все говорят: низкие задержки (меньшее расстояние) между хостом CDN и пользователем. Достигается путём создания географически распределённой архитектуры сети, в которой хосты располагаются в точках концентрации пользователей (городах, точках обмена трафиком и т. д.)
На практике, приоритеты для разных сетей могут находится в конкретных регионах. Например, российские CDN будут иметь больше точек присутствия в России. Американские прежде всего будут развивать сеть в США. Например, один из крупнейших CDN Cloudflare имеет только 2 точки в России — Москва и Санкт-Петербург. То есть, максимально мы можем сэкономить около 10 мс задержки по сравнению с прямым размещением в Москве.
Большинство западных CDN вообще не имеют точек в России. Подключившись к ним вы можете только увеличить задержки для вашей российской аудитории.
6. Оптимизация контента (минификация, структурные изменения)
Самый сложный и технологичный пункт. Изменение контента при доставке может быть очень рискованным. Даже если взять минификацию: сокращение исходного кода (за счет лишних пробелов, неважных конструкций и т. д.) может повлиять на его работоспособность. Если говорить о более серьёзных изменениях – переносе JS-кода в конец HTML, объединение файлов и подобных – риск нарушить функциональность сайта еще выше.
Поэтому лишь некоторые CDN из типа 5 занимаются этим. Конечно, автоматизировать все нужные для ускорения изменения не получится – требуется ручной анализ и оптимизация. Например, удаление неиспользуемого или дублирующего кода относится как раз к ручным задачам.
Как правило, все подобные оптимизации управляются настройками и самые опасные отключены по умолчанию.
Поддержка ускоряющих возможностей по типам CDN
Итак, давайте посмотрим, какие из потенциальных возможностей по ускорению предоставляют различные типы CDN.
Для удобства, повторим классификацию.
- Бесплатные CDN для раздачи JS-библиотек (MaxCDN, Google. Yandex).
- CDN сервисов по клиентской оптимизации (например Google Fonts для шрифтов, Cloudinary, Cloudimage для картинок).
- CDN для статики и оптимизации ресурсов в CMS (есть в Битриксе, Wordpress и других).
- CDN общего назначения (StackPath, CDNVideo, NGENIX, Мегафон).
- СDN для ускорения сайтов (Cloudflare, Imperva, Айри).
Теперь сопоставим фичи и типы CDN.
Возможность | Тип 1 | Тип 2 | Тип 3 | Тип 4 | Тип 5 |
---|---|---|---|---|---|
Сжатие текста | +– | – | +– | +– | + |
Заголовки кэша | + | + | + | + | + |
Картинки | – | +– | +– | – | + |
TLS | – | – | – | +– | + |
Задержки | – | – | – | + | + |
Контент | – | – | – | – | + |
В этой таблице «+» используется для индикации полной поддержки, «–» — отсутствие, «+–» – частичная поддержка. Конечно, возможны отклонения от этой таблицы в реальности (например, какой-нибудь CDN общего назначения внедрит фичи по оптимизации картинок), но для общего представления она полезна.
Итоги
Надеюсь, прочитав эту статью у вас появится более ясная картина относительно рекомендации «используйте CDN» для ускорения сайтов.
Как и в любом деле, нельзя верить маркетинговым обещаниям какого-либо сервиса. Эффект нужно измерять и проверять в реальных условиях. Если вы уже используете какой-то CDN, проверьте его на предмет эффективности по критериям, описанным в статье.
Возможно, использование CDN прямо сейчас замедляет загрузку вашего сайта.
В качестве общей рекомендации можно остановиться на следующем: изучите свою аудиторию, определите её географические рамки. Если ваша основная аудитория сосредоточена в радиусе 1-2 тысяч километров, вам не требуется CDN по основному назначению – снижению задержек. Вместо этого, вы можете разместить свой сервер ближе к пользователям и настроить его должным образом, получая большинство оптимизаций, описанных в статье (бесплатно и постоянно).
В случае, если ваша аудитория действительно географически распределена (радиус более 3000 километров), использование качественной CDN действительно будет полезно. Однако, нужно заранее понимать, что именно сможет ускорить ваша CDN (см. таблицу возможностей и их описание). Ускорение сайта при этом всё равно остаётся комплексной задачей, которая не решается подключением CDN. Помимо указанных оптимизаций за бортом CDN остаются самые эффективные средства ускорения: оптимизация серверной части, продвинутые изменения клиентской части (удаление неиспользуемого кода, оптимизация процесса рендеринга, работа с контентом, шрифтами, адаптивностью и т.д.)
Комментарии (14)
pae174
11.10.2019 16:37+1Resource Hints (preconnect) обнулил бы эту задержку, судя по диаграмме — фазы dns/connect/tls выполнялись бы параллельно с загрузкой остатка самой страницы. www.w3.org/TR/resource-hints
Nickmob Автор
11.10.2019 16:43Для первых ресурсов это не поможет. Для тех, которые внизу ватерфола — да. Первые ресурсы и так запускаются на загрузку браузером как можно раньше, то есть браузер увидит эти хинты почти одновременно с обнаружением их в HTML.
ky0
11.10.2019 19:53+2Не очень-то понятно, почему на первом скрине все соединения долго обрабатывают SSL-хэндшейк, хотя по идее так должно быть только с первым. На втором: 360 мсек для DNS-запроса — это катастрофа. К сути статьи это, конечно, имеет опосредованное отношение, просто бросилось в глаза.
Nickmob Автор
11.10.2019 22:22Как раз понятно: браузер одновременно инициирует несколько соединений (это HTTP 1.1), при этом никаких тикетов или кэша сессий на этот момент нет, поэтому полный хэндшейк.
В DNS-запросе никакой катастрофы нет — это 2RTT, в идеале было бы 1RTT (150 мс).ky0
12.10.2019 00:20Я к тому, что в 2019 году говорить, что CDN плохо помогают, не используя /2.0 и нормальные DNS-серверы — это такое…
Nickmob Автор
12.10.2019 10:05В данном случае использование HTTP/2 не поможет — задержка останется ровно такой же (только будет создано не 6 коннектов, а один). Насчет нормального DNS-сервера — вообще у CF «самый быстрый в мире» DNS — или вы про резолвер?
keydon2
12.10.2019 04:35+1Дальнейшие различия определяются функциональностью конкретной CDN – для первого типа это всего лишь хостинг статического файла, для пятого это изменение нескольких типов контента сайта с целью оптимизации.
Открою масонскую тайну — первый, третий и четвертый тип CDN это одно и то же.
Четвертый и пятый отличаются не принципиально, добавляется преобразование контента во время транзита (сюда же и «защита от копирования», которое вы почему-то не указали), по сути это отдельный вид услуг, непосредственно к CDN не относящийся. Т.е. вы тут намешали разные классификации (по бесплатности, по доп.услугам, по контенту), которые могут комбинирваться с друг другом (а не противопоставляться).
Если мы разделяем ресурсы на основной хост (origin) и CDN, то необходимо разводить запросы по нескольким доменам и создавать несколько ТСP-соединений.
Сути это не меняет (создается несколько соединений), но технически можно не разделять по доменам, зависит от балансировки. Например можно со своего домена отдавать айпишник CDN хоста.
В худшем случае это: DNS (1 RTT) + TCP (1 RTT) + TLS (2-3 RTT) = 6-7 RTT. В этой формуле не учитываются задержки в мобильных сетях на активацию радио-канала устройства (если он не был активен) и задержки на сотовой вышке.
Так вы сравниваете «прогретое» соединение (с рассчетом что пользователь обязательно посетил вашу страницу на origin) и непрогретое на cdn.
Если это прямая ссылка на изображение (например в соцсети), то с CDN скорее всего загрузится быстрее, чем ссылка на то же изображение с origin и не с большим количеством RTT.
На практике же CDN используют для уменьшения времени начала и окончания загрузки контента, а не замеров абстрактных RTT. Потери на RTT на непрогретых соединениях минимальны (на практике, в большинстве случаев), а ускорение на остальных аспектах гораздо существеннее выиграша в несколько RTT + снижение трафика на origin, что тоже существенная экономия на масштабировании.
Наиболее актуальный заголовок cache-control, устаревший – expires.
С чего это expires устаревший?
Может быть полезно знать, что в cache-control можно указать перевалидацию только для прокси tools.ietf.org/html/rfc7234#section-5.2.2.7.
Для некоторых применений стоит обратить внимание на вопросы безопасности: обычно трафик расшифровывается на узлах CDN, а это потенциальная возможность для перехвата трафика. Вариант работы без раскрытия трафика обычно предлагается в топовых тарифных планах за отдельную плату.
Это вообще про что? Расшифрование какого трафика? Более того, CDN может зашифровывать трафик.
Если вы уже используете какой-то CDN, проверьте его на предмет эффективности
А лучше перед использованием!
Если ваша основная аудитория сосредоточена в радиусе 1-2 тысяч километров, вам не требуется CDN по основному назначению – снижению задержек. Вместо этого, вы можете разместить свой сервер ближе к пользователям и настроить его должным образом, получая большинство оптимизаций, описанных в статье (бесплатно и постоянно).
Суть в предоставлении сервиса. Если вы хотите и можете размещать и поддерживать сервера по всей географии своей аудитории, настраивать правильно кэширование, балансировку, выбирать и договариваться о пиринге и находить время на исследование и оптимизацию всего этого, то поздравляю, вы можете создать свой CDN. Но у CDN сервиса больше клиетов, больше закупок, больше пользователей, можно мощности перераспределять между клиетами, у него больше возможностей для увеличения эффективности.
Ну и географические расстояния не равны сетевым замерам. Вполне реальная (хоть и редкая) ситуация, когда с CDN узла в том же городе контент раздается для некоторых абонентов (а то и для всех) лучше, чем с origin (по разным причинам). Хотя конечно предназначение CDN именно в распределенности.Nickmob Автор
12.10.2019 10:26Открою масонскую тайну — первый, третий и четвертый тип CDN это одно и то же.
Четвертый и пятый отличаются не принципиально, добавляется преобразование контента во время транзита (сюда же и «защита от копирования», которое вы почему-то не указали), по сути это отдельный вид услуг, непосредственно к CDN не относящийся. Т.е. вы тут намешали разные классификации (по бесплатности, по доп.услугам, по контенту), которые могут комбинирваться с друг другом (а не противопоставляться).
Согласен, здесь скорее не чистая классификация CDN как систем, а их сценариев использования со стороны потребителя.
С чего это expires устаревший?
Может быть полезно знать, что в cache-control можно указать перевалидацию только для прокси tools.ietf.org/html/rfc7234#section-5.2.2.7.
При наличии cache-control с max-age заголовок expires игнорируется. Устаревший он потому, что появился раньше и сейчас заменяется cache-control. MDN и RFC
Это вообще про что? Расшифрование какого трафика? Более того, CDN может зашифровывать трафик.
Трафика между origin и хостом CDN. Он сначала будет расшифрован на узле CDN, потом заново зашифрован и отправлен в браузер пользователя. Но узел CDN имеет доступ к открытому тексту (HTML, например).
keydon2
12.10.2019 15:59Трафика между origin и хостом CDN. Он сначала будет расшифрован на узле CDN, потом заново зашифрован и отправлен в браузер пользователя. Но узел CDN имеет доступ к открытому тексту (HTML, например).
Если контент должен быть доступен только одному пользователю, то нет смысла его кэшировать и пускать через CDN.
Если он доступен всем (пускай и зашифрован), то все равно мы решаем давать ли ключ конечному пользователю на расшифрование или нет.
CDN приходится в любом случае доверять, ведь что будет раздаваться по вашей CDN ссылке, будет решать CDN, независимо от того имеется ли доступ к открытому тексту или нет. Но это касается и остальных сторонних сервисов.
suffix_ixbt
12.10.2019 16:48+1Абсолютно согласен. Для «обычного» сайта использование CDN замедляет отдачу контента. У себя настроил всё что надо — статику пожал заранее gzip 9 level и btotli 11, включил в nginx TCP Fast Open и TLS 1.3 0-RTT (early_data), скрипты и стили собранные в два файла отдаются http/2 server push. А через CDN будет всё медленне тупо.
keydon2
13.10.2019 15:22Блин, Вась, где ты раньше был? Я думал, что нужно смотреть на настройки кэширования, на распределенность аудитории, на нагрузку, утилизацию каналов и рентабельность расширения всего этого добра, тестировать, сравнивать с разными CDN из регионов где мало-мальски значимое количество пользователей сидят (+из региона где гендиректор отпуск проводит). А надо было тебе позвонить и ты бы сразу объяснил что «для обычного сайта через CDN будет всё медленне тупо». Слушай, Вась, а мой сайт на битриксе, он «обычный»?
suffix_ixbt
13.10.2019 15:33+1То что ваш сайт на Битрикс это как-то влияет на то «обычный» он или нет? Странно как-то это подчёркивание.
Ну да ладно — у меня тоже на Битриксе сайт — и он «обычный». Хорошо — давайте расшифрую что в моём понимании «обычный» — «небольшая» посещаемость, от 75% аудитории расположено в том же регионе / городе где сейчас сервер (как правило это Москва).
firk
Во-первых, при правильной настройке это "второе подключение" используется только при первом посещении сайта, а дальше всё это оказывается в кеше браузера.
Во-вторых, на картинке в начале статьи задержки вызваны вовсе не cdn'ом. Потому что из неё же видно что браузер и не пытался грузить всё через одно соединение а открыл к кажому запросу своё, пусть даже они и в одинаковом домене. И чей это домен — cdn или основной — тут роли не играет. Единственная задержка которая там реально из-за cdn это резолв домена который там зелёным цветом и очень маленький.
Nickmob Автор
Так загрузка с холодным браузером (без кэша и подключения) и есть самый критичный момент в скорости, который нужно тестировать.
Задержки вызваны тем, что используется частичная загрузка с CDN (в данном случае с самодельного и без HTTP/2), но картинку это никак не меняет. Избежать этих задержек можно было загрузкой всего контента с одного домена по HTTP/2.