Многие сайты измеряют время формирования странички, хотя на самом деле надо измерять время у пользователя. Тут рассказывается как это делать, и почему доставка страничек может занимать 10 секунд, при ping 100ms
7. Первый байт быстрого* сервера
-500 500 1500 2500 3500
Новосибирск
Владивосток
Алматы
Киев
Астана
Екб
Стамбул
Минск
Анкара
Спб
Москва
50%
70%
90%
95%
8. Посл. байт быстрого* сервера (60kb)
0 500 1000 1500 2000 2500 3000 3500
Новосибирск
Киев
Алматы
Владивосток
Астана
Екб
Москва
Спб
Стамбул
Минск
Анкара
50%
70%
90%
95%
9. … наглая ложь, и статистика
• Не все браузеры поддерживают
– На мобилках только Chrome
• Считают разное
– firstPaintTime/msFirstPaint*
• Подвержено bias
10. До первого байта
0 200 400 600 800 1000 1200 1400
Chrome/Windows
Firefox/Windows
MSIE/Windows
Opera/Windows
Safari/Macintosh
YaBrowser/Windows
11. Особенности HTTPS
• Должно быть медленней
– время на handshake
• Первый байт быстрее
– aртефакт?
• Становится быстрее*
– What?!
*без НДС
23. TCP за 1 слайд
• rtt – время туда и обратно.
ping ~ rtt.
• ACK – подтверждение
доставки
• cwnd – сколько можно
отослать без
подтверждения
24. Скорость доставки
• На каждые CWND пакетов
нам нужно rtt времени.
• cwnd = 10, rtt=100, 145kb/s
• cwnd = 100, rtt=50, 2900kb/s
• cwnd медленно растет, пока
все хорошо, сильно падает,
когда пакет теряется.
25. TCP - Summary
• Новейшие технологии 70-х
• Для деления канала, не
для latency
• Для проводов
• Потеря -> congestion
33. Безумный пример
• Игнорируем cwnd, шлем все 40 пакетов
каждую 1ms следующий.
• Получаем selective ack, досылаем то, что
потерялось.
• Страница на хорошем канале придет за 1-2
rtt, на плохом будет хуже.
• Сейчас такое сделать нельзя* в QUIC
можно
* внутри CDN примерно так все и ходит, cwnd
учитывается, но он запредельного размера.
34. Итоги
• Задержку доставки сервер делает
сам из-за ограничений протоколов
• Серебряной пули нет, но место
для оптимизаций есть.
• Делая оптимизации следите за
метриками Timing API и tcpdump
38. Пару слов о HTTP
• Новейший протокол 90-х
• Второй запрос в
соединении = лишний rtt.
• Количество соединений
ограничено.
• Фиксится SPDY/HTTP2
39. GPRS/Edge/LTE
• Первые два просто медленные с
большим RTT
• сами разбираются ретрансмитами
(см. HARQ), может страдать Latency
• Ретрансмит внутри LTE выглядит для
TCP как самопроизвольное временное
возрастание rtt. Будет ли лишний
ретрансмит от TCP?
• Мелкий декларируемый application
window у мобильников
40. QUIC
• Сейчас революционного ничего нет.
• Вытаскивает в user-space то, что
сейчас зашито в ядре
– Можно сделать разную политику передачи в
зависимости от user agent.
• Если вы пишите приложение под
iPhone/Android, то играться с
протоколами можно прямо сейчас.
Editor's Notes
Многие компании следят за скоростью формирования страниц.Многие ей гордятся и пишут на видном месте.Что же они измеряют?
По данным броузера 625ms != 430 ms
На предыдущей страничке написано серверное время которое пользователя на самом деле волнует мало.
Серверное время пригодно только для того, чтобы программисты выясняли кто круче.
Вопрос что мерять, неожиданно сложный на него нет однозначного ответа. Загрузка не атомарное событие, а очень даже сложный процесс. Одну циферку получить сложно.
Например когда вы загружаете войну и мир, у вас часто она загружается несколько минут, но читать вы можете сразу. Т.е. страничка юзабельна до полной загрузки.
На многих сайтах сразу грузится навигация, т.к. она в кэше, а контент грузится позже.
Для каждого конкретного сайта тем не менее можно найти консенсус, например для выдачи яндекса это прорисовка первого сниппета. Только это нельзя измерить.
Если из ваших инструментов только молоток все ваши проблемы похожи на гвозди.
На самом деле весь developer tools в JS не доступен.
Доступно то, что на экране.
Есть предложение мерять скорость java script на клиенте, загружать результаты обратно, и уже строить клиентские метрики.
Очевидно у клиентов, а не на вашем тестовом комьютере
Очень упрощено, много событий выкинуто, dns, tcp handshake.
Совсем не рассмотрено время загрузки ресурсов
Что из этого выбрать KPI для нашего сайта? Хотим одну цифру.
Одну цифру выбрать нельзя.
Доставка первого байта моментально отвечающего сервера
Доставка последнего байта моментально отвечающего сервера.
Чтобы не делать тестовый стенд, мы взяли какую-то не быструю страничку яндекса и вычли серверное время из результата.
Есть ложь, наглая ложь и статистика. То что вы получаете будет статистикой.
Нужно понимать что у вас смещенная выборка не со всех броузеров.
У вас два разных события отрисовки, которые конечно означают разное.
Смотрите какой охрененно быстрый броузер Safari. Разве мы не за это любим Apple?
Голосование:
Кто согласен что Apple делает самые крутые компы и софт?
А кто считает, что тут херня нарисована?
(правы люди проголосовавшие за второй пункт, Safari в основном находится в москве, и у интернет специалистов, у которых интернет быстрый)
handshake скорее всего считается за первый байт.
Тут понятная анимация т.к. все уже забыли что сдесть нарисовано.
График требует осознания. По вертикали две точки, зеленая это время до первого байта, черная это время передачи.
По горизонтали номер запроса. Запросы сортированы по времени передачи.Из-за этого черные точки выстроились в линию.У 30% запросов время первого байта искусственно завышено. Зато потом документ приходит сразу.Ответ тут такой это разные системы DPI, вот такой явный эффект это антивирусы.
(но почему-то https все равно быстрее даже по последнему байту).Антивирусы (подтверждено),
DPI (не подтверждено, не будет заметно так явно как антивирусы т.к. время загрузки не нулевое). Теория про 443 порт вне фильтров. Ссылка про парсинг DPI на карте.
Сервер знает о доставке всех пакетов.
Ему приходит ACK с этой информацией.
Даже для тех у кого нет Timing API
Тулза разбирающая tcpdump-ы в статистику. open source версия многое отломано.
В яндексе работала в mapreduce environment, поддержка https недоделана, отчеты временно выкинуты.
Не совсем законченный продукт
(картинка)Есть nginx, с одной стороны от него пользователь, с дугой стороны какой-то backend.
Снимем на nginx tcpdump, с обоих интерфейсов внешнего и внутреннего, у нас есть request_id и мы умеем приклеивать внешний запрос к внутреннему.
Попробуем понять измерить “время до последнего байта” по tcpdump, а потом понять, что происходит все это время.
Основная задержка которая происходит при доставке происходит на вашем сервере и заключается в том что сервер придерживает пакеты.
Серьезно. Вы оптимизируете ваш серверный код на 100ms и это круто, а Ваш сервер сервер задерживает пакеты на 500ms. Нахрена он это делает?
Для того чтобы понять почему именно надо маленько знать как tcp устроен.
Наверное сложно в 1 слайде рассказать как работает TCP, по хорошему наверное нужно 10 слайдов, рассказывать не хочется т.к. будет скучно тем кто знает.
Поэтому расскажу 3 термина которые нужны для понимания.
1) Rtt время туда и обратно. Ограниченно скоростью света и тормозами девайсов.
1) Другая сторона шлет нам пакетики в ответ на получение наших пакетиков. Не на каждый пакет. Если бы мы ждали подтверждение предыдущего пакета перед посылом следующего то мы могли бы посылать 1000/rtt пакетов в секунду. Пакет примерно 1450 байт. Т.е. При ping=100 мы бы могли протолкнуть максимум 14.5кб в секунду. Поэтому мы ждем подтверждения не каждого пакета.
2) Cwnd сколько пакетов можно послать без подтверждения. Если мы на широком канале(например мы сервер) то на каждые CWND пакетов мы тратим один rtt.
Протокол старый сделан в 70-х.
Он универсальный = потрясающе хреновый для всего
Вообще он сделан для того чтобы поровну поделить канал в не очень быстрой сети
Т.е. он пихает пакетики увеличивая скорость и считает что если пакетик потерялся значит скорость превышена. Про ситуации, что пакетик потерялся просто так, а не из-за скорости данный протокол не верит. Ну т.е. правда, в медных проводах такого почти не происходит.
Оптимизирован для thruput(притом группового) не для latency ни разу.
Вот так работат wifi кто не знал, многие люди считают, что он ходит сквозь стены. Да ходит но только где нет металла, а там либо арматура либо сетка.
Тут постановка проблемы, когда мы складываем проводную сеть на rtt100 с потерей 0% и wifi c rtt1 с потерей 5% мы получаем канал с потерей 5% и rtt=100
В первую очередь блокирующий размер, неблокирующий можно не уменьшать.
CDN полезны даже для динамики, т.к. Рвут канал на два независимых.
Идея для стартапа – wifi роутер с прозрачным proxy, на обычный роутер такую прошивку поставить нельзя, там памяти столько что хватит на одну картинку.
Если кто будет делать сначала почитайте про Bufferbloat чтобы понять что проблема не такая простая.
Т.е. когда к вам кто-то пришел можно ему послать 10 пакетов = 14.5кб, потом надо ждать подтверждение.
Откуда взялось число 10? Оно какое-то подозрительно круглое для того, чтобы быть научно обоснованным.
Ну и наврядли мы мы серьезно думаем, что оно одинаково хорошо для человека на gprs, и на 1Gb оптике, в соседней комнате и на другом материке?
Краткая история возникновения, там сначала было 2, потом было 4, а потом решили сделать 10. Экспоненциальный прогресс на лицо.
Все это приводит к тому, что отдавая морду в 60кб нам нужно ждать 3-4 rtt, т.е. 300-500ms
Результаты экспериментов initial cwnd=20. Вообще для морды это помогло, для поиска результаты были странные что-то перетряхнуло, где-то стало быстрее где-то медленней.
Замечу что это initial cwnd, т.е. Если его указать неправильно TCP все равно его приведет в нужное состояние.
Прямого контроля над cwnd у нас нет, если только вы не готовы в ядро залезть. Учитывая что cwnd надо скорее всего контролировать по разному в зависимости от user agent
Например сайт с 60 ресурсами типа картинок и css при ограничении в 6 соединений влетает на 10rtt (проверить правда ли про 6 в хроме).
Правда это уже не очень важно т.к. страничка скорее всего отобразится и так, но на старте с css и прочим все равно будет веселуха.
Вот почему много, кто предпочитает все инлайнить, например google, даже для SPDY почему-то.
Про LTE я на самом деле мало знаю, но в отличие от wifi там есть встроенные ретрансмиты для данных уровнем ниже чем TCP.
Мне кажется что когда протокол под TCP делает ретрансмиты то для TCP это выглядит как рандомное изменение Latency
От чего “современный протокол TCP(tm)” должен херачить тоннуб лишних ретрансмитов, которые засирают и так неширокий мобильный канал.
Я слышал об оборудовании которое TCP пересобирает для мобильщиков но точно не знаю.
Тут вполне нормально реализовать какой-нибудь machine learning который в зависимости от типа клиента по разному ему выплевывает пакетики.
Идеальная ситуация что мы например посылаем всю страницу сразу, но с перерывами в 2-5 ms между пакетиками, чтобы они успевали пролезать в повод.
Важное замечание что если вы пишите мобильное приложение, то вы контролируете клиентскую сторону тоже, можете прямо сейчас пользоваться.