Pull to refresh

Латентность при загрузке веб-страниц

Reading time 3 min
Views 35K
Пост «Кое-что о весе страницы» вызвал у меня желание написать маленькое дополнение. Многие замечают, что оптимизация размера веб-страниц становится менее актуальной в связи с увеличением пропускных способностей каналов. Рано или поздно все будут сидеть на гигабите, и будет совершенно неважно, весит ваша страница 100Кб или 250. Возможно, так оно и будет. Однако помимо скорости канала есть и другой параметр — задержка или латентность. И если пропускная способность каналов с развитием технологий может вырасти ещё очень сильно, то у латентности существует физический предел: это скорость света в оптоволокне — около 200 тысяч километров в секунду.

Хотя эта скорость очень велика, но всё же недостаточно, чтобы о ней забывать, ведь и планета у нас немаленькая. Wolfram Alpha не зря выдаёт на запросы по расстоянию время прохождения этого расстояния светом в волокне. Пусть у вас стоит сервер в Токио, а клиент пришёл из Рио-де-Жанейро. Если даже эти два города соединить оптоволокном по кратчайшей траектории на поверхности Земли, свет будет идти 86.7 мс.

Что это значит для вас? Предположим, пользователь открывает вашу страницу в браузере, например, из закладок. От того момента, когда он кликнул, до того, когда сигнал дойдёт до сервера, пройдёт минимум 86.7 мс. И ещё столько же, чтобы сигнал дошёл обратно. Ваша страница никак не может загрузиться быстрее 173.4 мс, даже если она мало весит и вообще закэширована клиентом (чтобы узнать, что она не менялась, всё равно придётся спросить сервер).

Казалось бы, 173.4 мс — мелочи жизни. Но не всё так просто. Многим страничкам требуются скрипты, стили и картинки, без загрузки которых страничка нефункциональна. Браузер не может начать всё это загружать, не загрузив сам HTML хотя бы чуть-чуть (ссылки-то на скрипты в HTML). А значит, нам потребуется уже 86.7 мс (запрос HTML) + 86.7 мс (получение HTML) + 86.7 мс (запрос всего остального) + 86.7 мс (получение всего остального) — минимум 346.8 мс.

Конечно, и 346.8 мс можно подождать. Бывает, однако, что для нормального отображения страницы требуется выполнить AJAX-запрос. К примеру, основной информационный блок у вас на странице может автоматически обновляться с сервера по AJAX. Чтобы не усложнять логику сервера, вы его не отдаёте при первоначальной загрузке страницы, а оставляете пустым, но сразу же вызываете функцию обновления. Таких сайтов множество. Скажем, на rts.micex.ru так загружаются индексы, котировки и прочие блоки. Теперь, если вы зашли посмотреть актуальные котировки, вам придётся подождать загрузки HTML, загрузки JS, а затем выполнения AJAX-запроса — минимум 520.2 мс. Полусекундная задержка уже некомфортна хотя, конечно, можно потерпеть.

Бывает однако и так, что некоторая информация подгружается AJAX-запросом, который ждёт результатов выполнения другого AJAX-запроса. Иногда это связано с непродуманностью взаимодействия между клиентом и сервером: чтобы послать следующий запрос, нужна информация из предыдущего. Гораздо чаще это связано с ленью разработчика, который не разобрался с функциями, позволяющими выполнить определённый код после завершения сразу нескольких запросов (или не написал сам таких функций, если предпочитает Vanilla JS), и поэтому просто посылает второй запрос в onreadystatechange первого.

Вот такую чудную картину загрузки демонстрирует стартовая страница одной системы онлайн-банкинга, которой я пользуюсь:

Здесь подгружаются дополнительные ресурсы и скрипты через 9 последовательных AJAX-запросов. Добавим к этому запрос на HTML и запрос скрипта, который всё это добро загружает — получается минимальная задержка при нашей расстановке клиента и сервера в 1.9 секунды. Вот ведь какая штука: хоть терабитный интернет по всей Земле проведите, сделайте бесконечно быстрые сервера и жёсткие диски, а пользователь из Рио-де-Жанейро всё равно будет ждать две секунды из-за кривых программистов.

Даже если предположить, что инженеры научатся посылать сигналы не по поверхности, а сквозь Землю и со скоростью света в вакууме (скажем, пускаем пучок релятивистских нейтрино, а на той стороне ставим детектор), латентность упадёт максимум вдвое. Но, я думаю, раньше интернет на Луну проведут, чем такое сделают. А с Луны такой сайт будет грузиться сами посчитайте, сколько.

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

Ну и очевидные полезные советы в заключение:
  • Старайтесь, чтобы ваш сайт был функционален и информативен уже после загрузки основного HTML. Главная страница YouTube как раз хороший тому пример.
  • Не получайте AJAX-запросом то, что вы хотите сразу показать пользователю. Сгенерируйте правильную страничку сразу.
  • Разумеется, можно и нужно не загружать ту информацию, которую пользователь не увидит, пока не совершит явного действия (прокрутит страницу, нажмёт «показать подробности» и т. д.). Но старайтесь исключить последовательные AJAX-запросы при реакции на эти действия. Либо уложитесь в один запрос, либо выполните все параллельно.
  • При возможности размещайте зеркала сайта в разных частях света и перенаправляйте пользователя на ближайшее.
Tags:
Hubs:
+92
Comments 91
Comments Comments 91

Articles