В части 1 этой серии мы посмотрели, как работают базовые протоколы Web и как мы можем использовать JavaScript для оценки их характеристик производительности. В этой второй части мы рассмотрим DNS, IPv6 и новую спецификацию W3C для API Навигации.
DNS Разъяснения
Каждое устройство, подключенное к Интернету, идентифицируется по цифровому адресу, известному как IP-адрес. Двумя формами IP-адресов, замеченных в открытом Интернете, являются IPv4, который представляет собой 32-битное число, часто представленное как серия из четырех десятичных чисел, разделенных точками, 80.72.139.101
например, и IPv6, который представляет собой 128-битное число, представленное как серия множественных гексадецовых чисел разделены толстой кишки, 2607:f298:1:103::c8c:a407
например. .
Дальнейшее чтение на SmashingMag:
- Производительность веб-сайта: Что знать и что вы можете сделать
- Дизайн на основе данных в реальном мире
- Дорожная карта, чтобы стать a/ B тестирования экспертов
- Мультивариатное тестирование 101: Научный метод оптимизации дизайна
Эти адреса хороши для понимания компьютерами; они занимают фиксированное количество байтов и могут быть легко обработаны, но они трудно для людей, чтобы помнить. Они также не очень хороши для брендинга, и часто привязаны к географическому местоположению или поставщику услуг инфраструктуры (например, провайдеру или хостинг-провайдеру).
Чтобы обойти эти недостатки, была изобретена«Система доменных имен». В своей простейшем виде, DNS создает отображение между человеком читаемым именем, как » www.smashingmagazine.com
и его машина читаемый адрес ( 80.72.139.101
). DNS может содержать гораздо больше информации, но это все, что важно для этой статьи.
Сейчас мы сосредоточимся на задержке DNS и на том, как мы можем измерить ее с помощью JavaScript из браузера. Задержка DNS важна, потому что браузеру необходимо сделать поиск DNS для каждого уникального хоста, что он должен загружать ресурсы с — даже если несколько хостеров карта на тот же IP-адрес.
Измерение времени поиска DNS
Простой способ измерить время поиска DNS с JavaScript будет сначала измерить задержку хоста к хосту, используя его IP-адрес, а затем измерить его снова, используя его хост-имя. Разница между ними должна дать нам время поиска DNS. Мы используем методы, разработанные в части 1 для измерения задержки.
Проблема с этим подходом заключается в том, что если браузер уже сделал поиск DNS на этом хост-имя, то этот поиск будет кэшировать, и мы действительно не получить разницу. Что нам нужно, это подстановочный знак DNS записи, и веб-сервер прослушивания на нем. Карлос Буэно сделал большой рецензии об этом на блоге YDN несколько лет назад, и построил код, который использует бумеранг.
Прежде чем мы рассмотрим код, давайте взглянем на то, как DNS поиск работы со следующей (упрощенной) диаграммы:
Слева направо: Клиент здесь браузер, DNS-сервер (как правило) isP пользователя, корневой сервер имя знает, где искать большинство доменов (или кто спрашивает, если он не знает о них), и, наконец, авторитетный сервер, который является DNS сервера веб-сайтов владелец ite.
Каждый из этих слоев имеет свой собственный кэш, и этот кэш обычно прилипает до тех пор, пока TTL авторитетного сервера (известный как «Time To Live») говорит, что он должен; но не все серверы следуют спецификации (и это полная тема для себя).
Теперь давайте посмотрим на код:
var dns_time;
function start() {
var gen_url, img,
t_start, t_dns, t_http,
random = Math.floor(Math.random()*(2147483647)).toString(36);
// 1. Create a random hostname within our domain
gen_url = "http://*.foo.com".replace(/*/, random);
var A_loaded = function() {
t_dns = new Date().getTime() - t_start;
// 3. Load another image from the same host (see step 2 below)
img = new Image();
img.onload = B_loaded;
t_start = new Date().getTime();
img.src = gen_url + "image-l.gif?t=" + (new Date().getTime()) + Math.random();
};
var B_loaded = function() {
t_http = new Date().getTime() - t_start;
img = null;
// 4. DNS time is the time to load the image with uncached DNS
// minus the time to load the image with cached DNS
dns_time = t_dns - t_http;
};
// 2. Load an image from the random hostname
img = new Image();
img.onload = A_loaded;
t_start = new Date().getTime();
img.src = gen_url + "image-l.gif?t=" + (new Date().getTime()) + Math.random();
}
Давайте быстро пройдем через код. То, что мы сделали здесь:
- Создайте случайное имя хоста, закрепленное на нашем домене подстановочных знаков. Это гарантирует, что поиск хоста не кэширован никем.
- Загрузите изображение из этого узла и измерьте время, необходимое для его загрузки.
- Загрузите другое изображение из того же узла и измерьте время загрузки.
- Рассчитайте разницу между двумя измеренными временами.
Первый измеренный период времени включает время поиска DNS, время рукопожатия TCP и задержку сети. Второй измеряемый раз включает задержку сети.
Есть два недостатка этого подхода, хотя. Во-первых, он измеряет наихудшее время поиска DNS, т.е. время, необходимое для поиска DNS, если ваше хост-имя не кэшируется каким-либо промежуточным DNS-сервером. На практике это не всегда так. Существует не простой способ обойти, что без помощи браузеров, и мы получим, что позже в конце этой статьи.
Кроме того, что, вероятно, делает его трудным для большинства людей для реализации является создание подстановочного знака DNS записи. Это не всегда возможно, если вы не контролируете свои DNS-серверы. Многие поставщики общих хостингов не позволят настроить запись DNS подстановочного знака. Единственное, что вы можете сделать в этом случае, чтобы переместить хостинг-провайдеров, или, по крайней мере DNS провайдеров.
Измерение поддержки и задержки IPv6
Технически, измерение IPv6 не должно быть отдельной темой, однако, даже через десять лет после его введения, IPv6 принятие по-прежнему довольно низким. Провайдеры сдерживают, потому что не слишком много веб-сайтов предлагают поддержку IPv6, и владельцы веб-сайтов сдерживают, потому что не слишком многие из их пользователей имеют поддержку IPv6, и они не уверены, как это повлияет на производительность или пользовательский опыт.
Тест IPv6 в бумеранге поможет вам определить, есть ли у пользователей поддержка IPv6 и как их задержка IPv6 сравнивается с задержкой IPv4. Он не проверяет, если их поддержка IPv6 нарушается или нет (но см. Страницу теста IPv6 от Google, если вы хотите знать это).
В тесте IPv6 есть две части:
- Во-первых, мы проверяем, можем ли мы подключиться к хосте, используя его адрес IPv6, и если мы можем, мы измеряем, сколько времени это занимает.
- Далее мы пытаемся подключиться к имени хоста, которое разрешается только с адресом IPv6.
Первый тест говорит нам, если сеть пользователя может сделать IPv6 соединений. Второй говорит нам, если их DNS-сервер может искать записи AAAA. Нам нужно запустить тест в этом порядке, потому что мы не смогли бы правильно протестировать DNS, если соединения на уровне IP сбой.
Код очень похож на тест DNS, за исключением того, что нам не нужна запись подстановочного знака DNS:
var ipv6_url = "http://[2600:1234::d155]/image-l.gif",
host_url = "http://ipv6.foo.com/image-l.gif",
timeout: 1200,
ipv6_latency='NA', dnsv6_latency='NA',
timers: {
ipv6: { start: null, end: null },
host: { start: null, end: null }
};
var img,
rnd = "?t=" + (new Date().getTime()) + Math.random(),
timer=0, error = null;
img = new Image();
function HOST_loaded() {
// 4. When image loads, record its time
timers['host'].end = new Date().getTime();
clearTimeout(timer);
img.onload = img.onerror = null;
img = null;
// 5. Calculate latency
done();
}
function error(which) {
// 6. If any image fails to load or times out, terminate the test immediately
timers[which].supported = false;
clearTimeout(timer);
img.onload = img.onerror = null;
img = null;
done();
}
function done() {
if(timers['ipv6'].end !== null) {
ipv6_latency = timers.ipv6.end - timers.ipv6.start;
}
if(timers['host'].end !== null) {
dnsv6_latency = timers.host.end - timers.host.start;
}
}
img.onload = function() {
// 2. When image loads, record its time
timers['ipv6'].end = new Date().getTime();
clearTimeout(timer);
// 3. Then load image with hostname that only resolves to ipv6 address
img = new Image();
img.onload = HOST_loaded;
img.onerror = function() { error('host') };
timer = setTimeout(function() { error('host') }, timeout);
timers['host].start = new Date().getTime();
img.src = host_url + rnd;
};
img.onerror = function() { error('ipv6') };
timer = setTimeout(function() { error('ipv6') }, timeout);
this.timers['ipv6'].start = new Date().getTime();
// 1. Load image with ipv6 address
img.src = ipv6_url + rnd;
Да, этот код можно рефакторовать, чтобы сделать его меньше, но это затруднит объяснение. Это то, что мы делаем:
- Сначала мы загружаем изображение с узла, используя его адрес IPv6. Это проверяет, чтобы увидеть, что мы можем сделать сетевое подключение к адресу IPv6. Если ваша сеть, браузер или ОС не поддерживают IPv6, это сведет на нет, и событие onerror загорится.
- Если изображение загружается, мы знаем, что соединения IPv6 поддерживаются. Мы записываем время, которое мы будем использовать для измерения задержки позже.
- Затем мы пытаемся загрузить изображение с помощью хоста, который разрешается только с адресом IPv6. Важно, чтобы это хостатовое имя не решило с адресом IPv4 или этот тест может пройти, даже если dNS-сервер не может обрабатывать IPv6.
- Если это удастся, мы знаем, что наш DNS-сервер может искать и возвращать записи AAAA (эквивалент IPv6 A). Мы записываем время.
- А потом идти вперед и рассчитать задержку. Мы можем сравнить это с нашей задержкой IPv4 и задержкой DNS. Это также было бы подходящим местом для вызова любой функции обратного вызова, чтобы сказать, что тест завершен.
- Если какая-либо из загрузок изображения произвела событие onerror или если они приурочены, мы немедленно прекращаем тест. В этом случае любые тесты, которые не были запущены, имеют соответствующую переменную
ipv6_latency
dnsv6_latency
(или) набор «NA», не указывающие на поддержку.
Существуют и другие способы проверки поддержки IPv6 с помощью серверной стороны, например, чтобы ваш сервер установил файл cookie, в котором было указано, был ли он загружен через IPv4 или IPv6. Это работает хорошо, только если ваша страница тестирования и ваша страница изображения находятся на том же домене.
NavigationTiming API — это интерфейс, предоставляемый многими современными браузерами, который дает разработчикам JavaScript подробную информацию о времени, проведенном браузером в различных состояниях загрузки страницы. Спецификация все еще находится в состоянии проекта, но на дату этой статьи, Internet Explorer, Chrome и Firefox поддерживают его. Safari и Opera в настоящее время не поддерживают API.
Разработчики JavaScript получают доступ к объекту NavigationTiming через window.performance.timing
. Попробуйте это сейчас. Если вы используете Chrome, IE 9 «или Firefox 8» , откройте веб-консоль и проинспектировать содержимое window.performance.timing
.
На приведенной ниже диаграмме объясняется порядок событий, время которых отображается в объекте. Давайте посмотрим на некоторые из них:
Большее представление Источник изображения
Теперь элементы, которые мы были заинтересованы в измерении являются:
-
Время загрузки страницы Мы получаем полное время загрузки страницы, принимая разницу между
loadEventEnd
иnavigationStart
. Последний сообщает нам, когда пользователь инициировал загрузку страницы, либо нажав на ссылку, либо введя ее в URL-бар своего браузера. Последний говорит нам, когдаonload
мероприятие закончилось. Если мы не заинтересованы в времени выполненияonload
события, мы могли бы использоватьloadEventStart
вместо этого. -
Задержка сети/приложений Задержка сети — это время от браузера, искрометирующего загрузку, до момента, когда появился первый байт. Теперь, часть этой задержки может быть отнесена к приложению делать что-то перед отправкой байтов, но нет никакого способа узнать, что со стороны клиента. Мы используем разницу между
requestStart
иresponseStart
. -
Время подключения TCP Время подключения TCP является разница между
connectStart
иconnectEnd
, однако, если соединение над SSL, то это включает в себя время для переговоров SSL рукопожатие. Вы должны принять это во внимание, и использоватьsecureConnectionStart
вместо того,connectEnd
если она существует, и если вы заботитесь о разнице. -
Задержка DNS Задержка DNS – это разница между
domainLookupStart
иdomainLookupEnd
.
Важно: Мы используем комбинацию раз,
window.performance.timing
чтобы определить каждый из них.
Хотя это выглядит хорошо по большей части, и действительно говорит вам, что ваши пользователи испытывают, Есть несколько оговорок, чтобы быть в курсе. Если DNS уже кэширован, то задержка DNS будет 0
. Аналогичным образом, если браузер использует постоянное соединение TCP, то время подключения TCP будет 0
. Если документ зачитывается из кэша, то задержка сети будет 0
. Имейте в виду эти моменты и используйте их, чтобы определить, какая часть пользователей эффективно использует доступные кэши приложений.
Интерфейс Навигация Тайминг предоставляет нам гораздо больше таймер, но некоторые из них ограничены той же политики происхождения браузера. К ним относятся сведения о перенаправлениях и разгрузке предыдущей страницы. Другие таймеры, связанные с DOM, уже имеют эквивалентные события JavaScript, а именно readystatechange
события DOMComplete
и load
события.
Информационный ими идолдля сети
Другой интересный аиП, связанный с сетью, — API сетевой информации. Хотя это и не связано с производительностью, это помогает делать догадки в ожидаемой производительности сети. Этот API в настоящее время поддерживается только устройствами Android и подвергается воздействию через navigator.connection.type
объект. В частности, он говорит вам, является ли устройство в настоящее время с помощью Ethernet, Wi-Fi, 2G или 3G.
Статья, которую я настоятельно рекомендую читать будет кусок Дэвид Акхун, который показывает некоторые хорошие примеры по оптимизации на основе скорости подключения. И статья, и комментарии являются полезнымчтение.
Сводка
Хотя API навигации Синхронизации обеспечивает легкий доступ к точной информации о времени страницы, он по-прежнему недостаточно, чтобы нарисовать полную картину. Существует еще некоторое преимущество для оценки различных характеристик производительности с использованием методов, упомянутых ранее в этой серии.
Независимо от того, нужно ли нам поддерживать браузеры, которые в настоящее время не реализуют навигационные сроки или получить информацию о ресурсах, не включенных в текущую страницу, не забудьте узнать больше о пропускной способности сети пользователя или же их поддержка IPv6 лучше или хуже, чем их поддержка IPv4 — сочетание методов дает нам лучшую всестороннюю картину.
Все методы, представленные здесь были разработаны при написании Boomerang, хотя не все из них сделали его в код еще.
Ссылки
Следующие ссылки помогли в написании этой статьи и могут быть переданы для получения дополнительной информации по конкретным темам:
- Система доменных имен: Статья WikiPedia, объясняющая, что такое DNS и как она работает.
- RFC 1035: Спецификация DNS: Один из RFCs о DNS, это одна подробная спецификация и реализация.
- Wildcard DNS записи: WikiPedia статьи объясняя Wildcard DNS.
- IPv4: Статья WikiPedia о пересмотре 4 протокола IP-адресации.
- IPv6: Статья WikiPedia о пересмотре 6 протокола IP-адресации.
- Тестовая страница IPv6 от Google:сообщает, поддерживает ли ваш браузер, ОС и сетевой провайдер IPv6 и работает ли эта поддержка правильно или нет.
- Тоннели IPv6 hurricane Electric:Создайте туннель IPv6 над сетью IPv4, чтобы оказать себе поддержку IPv6 (наиболее полезную для тестирования) до того, как это сделать ваш интернет-пользователь.
- Спецификация NavTiming:спецификация проекта W3C для API NavTiming браузера.
- API сетевой информации: спецификация проекта W3C для API сетевой информации.
- «Использование navigator.connection на Android» написана Дэвидом Калхауном.
(Кредиты изображения на первой странице: Власта Джурисек)
(il) (ea)
Источник: smashingmagazine.com