Java, UX, HTML, CSS, WEB-design

Анализ сетевых характеристик с использованием JavaScript и DOM, часть 1

[ad_1]

  • Филип Теллис

  • 0 Комментарии

Анализ сетевых характеристик с использованием JavaScript и DOM, часть 1

  • 9 минут чтения

  • Кодирование, JavaScript, Производительность

Краткое резюме ↬

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

В этой статье мы рассмотрим некоторые методы манипулирования JavaScript для определения различных сетевых характеристик из браузера — характеристик, которые ранее были доступны только приложениям, напрямую взаимодействующим с операционной системой. Многое из этого было обнаружено при создании проекта Boomerang для измерения реальной производительности пользователей.

Еще после прыжка! Продолжить чтение ниже ↓

Что вообще в сети?

Сеть имеет много уровней, но веб-разработчики среди нас больше всего заботятся о HTTP, работающий поверх TCP и IP (также известный как набор интернет-протоколов). Несколько слоев ниже этого, но по большей части то, работает ли он на медных, оптоволоконных или почтовых голубях, не влияет на слои или характеристики, которые нас интересуют.

Сетевая задержка

Сетевая задержка обычно представляет собой время, необходимое для отправки сигнала по сети и получения ответа. Его также часто называют временем приема-передачи или временем пинга, потому что это время, о котором сообщает ping команда. Хотя это интересно сетевым инженерам, занимающимся диагностикой сетевых проблем, веб-разработчиков больше волнует время, необходимое для отправки HTTP-запроса и получения ответа. Поэтому мы определим задержку HTTP как время, необходимое для выполнения наименьшего возможного HTTP-запроса и получения ответа с незначительным временем обработки сервером (т. е. единственное, что делает сервер, — это отправляет ответ).

Классный совет: Свет и электричество распространяются по волокну и меди со скоростью 66 % скорости света в вакууме, или 20 × 108 километров в секунду. Хорошее приближение сетевой задержки между точками A и B: четыре раза время, которое требуется свету или электричеству для преодоления расстояния. Карта кабелей Грега — хороший ресурс для определения длины и пропускной способности подводных сетевых кабелей. Я оставлю это вам, чтобы собрать эти кусочки вместе.

Пропускная способность сети

Пропускная способность сети говорит нам, насколько хорошо используется сеть. У нас может быть 3-мегабитное сетевое соединение, но эффективно мы используем только 2 мегабита, потому что сеть много времени простоя.

DNS

DNS немного отличается от всего остального, что нас волнует. Он работает через UDP и обычно происходит на уровне, прозрачном для JavaScript. Мы посмотрим, как лучше всего определить время, необходимое для поиска DNS.

Конечно, в сети есть еще много чего, но определение этих характеристик с помощью JavaScript в браузере становится все сложнее.

Измерение задержки в сети с помощью JavaScript

HTTP-запрос на получение

Моей первой мыслью было, что измерение задержки просто влечет за собой отправку одного пакета в каждую сторону и синхронизацию. Это довольно легко сделать в JavaScript:


var ts, rtt, img = new Image;
img.onload=function() { rtt=(+new Date - ts) };
ts = +new Date;
img.src="https://www.smashingmagazine.com/1x1.gif";

Мы запускаем таймер, затем загружаем GIF размером 1 × 1 пиксель и измеряем, когда он onload событие срабатывает. Сам GIF имеет размер 35 байт и поэтому помещается в один пакет TCP даже с добавленными заголовками HTTP.

Это вроде как работает, но дает противоречивые результаты. В частности, при первой загрузке изображения это займет немного больше времени, чем последующие загрузки, даже если мы убедимся, что изображение не кэшируется. Взгляд на TCP-пакеты, проходящие по сети, объясняет, что происходит, как мы увидим в следующем разделе.

TCP Handshake и HTTP Keep-Alive

Квитирование TCP: SYN-ACK/SYN-ACK

При загрузке веб-страницы, изображения или любого другого веб-ресурса браузер открывает TCP-соединение с указанным веб-сервером, а затем создает HTTP-запрос. GET запрос по этому соединению. Детали TCP-соединения и HTTP-запроса скрыты как от пользователей, так и от веб-разработчиков. Однако они важны, если нам нужно проанализировать характеристики сети.

При первом открытии TCP-соединения между двумя хостами (в нашем случае браузером и сервером) им необходимо «рукопожатие». Это происходит путем отправки трех пакетов между двумя хостами. Хост, который инициирует соединение (в нашем случае браузер), сначала отправляет SYN-пакет, что означает: «Давайте SYNc. Я хотел бы поговорить с вами. Вы готовы поговорить со мной?» Если другой хост (в нашем случае сервер) готов, он отвечает ACK, что означает «Я ПОДТВЕРЖДАЮ ваш SYN». Кроме того, он отправляет собственный SYN, что означает: «Я тоже хочу выполнить SYNc. Вы готовы?» Затем веб-браузер завершает рукопожатие своим собственным ACK, и соединение устанавливается. Соединение может завершиться ошибкой, но процесс, лежащий в основе ошибки соединения, выходит за рамки этой статьи.

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

Когда мы перебрасываем HTTP через TCP, у нас теперь есть HTTP-клиент (обычно браузер), который инициирует TCP-соединение и отправляет первый пакет данных ( GET просьба, например). Если мы используем HTTP/1.1 (что сегодня делают почти все), то по умолчанию будет использоваться HTTP keep-alive (Connection: keep-alive). Это означает, что через одно и то же соединение TCP может выполняться несколько HTTP-запросов. Это хорошо, потому что это означает, что мы уменьшаем накладные расходы на рукопожатие (три дополнительных пакета).

Теперь, если у нас не включена конвейерная обработка HTTP (а большинство браузеров и серверов отключают ее), эти запросы будут выполняться последовательно.

HTTP-поддержка

Теперь мы можем немного изменить наш код, чтобы учесть время рукопожатия TCP и соответственно измерить задержку.


var t=[], n=2, tcp, rtt;
var ld = function() {
   t.push(+new Date);
   if(t.length > n)
     done();
   else {
     var img = new Image;
     img.onload = ld;
     img.src="https://www.smashingmagazine.com/1x1.gif?" + Math.random()
                         + '=' + new Date;
   }
};
var done = function() {
  rtt=t[2]-t[1];
  tcp=t[1]-t[0]-rtt;
};
ld();

С помощью этого кода мы можем измерить как задержку, так и время рукопожатия TCP. Есть вероятность, что TCP-соединение уже было активным и первый запрос прошел по этому соединению. В этом случае два времени будут очень близки друг к другу. Во всех остальных случаях rttдля которого требуется два пакета, должно составлять примерно 66% от tcp, для которого требуется три пакета. Обратите внимание, что я говорю «приблизительно», потому что дрожание сети и разные маршруты на уровне IP могут привести к тому, что два пакета в одном и том же TCP-соединении пройдут через разное время.

Вы заметите, что мы проигнорировали тот факт, что первое изображение могло также потребовать поиска DNS. Мы рассмотрим это во второй части.

Измерение пропускной способности сети с помощью JavaScript

Опять же, нашим первым побуждением в этом тесте было просто загрузить большое изображение и измерить, сколько времени это займет. потом size/time должен сказать нам пропускную способность.

Для целей этого кода предположим, что у нас есть глобальный объект с именем imageс подробными сведениями об URL-адресе и размере изображения в битах.


// Assume global object
// image={ url: …, size: … }
var ts, rtt, bw, img = new Image;
img.onload=function() {
   rtt=(+new Date - ts);
   bw = image.size*1000/rtt;    // rtt is in ms
};
ts = +new Date;
img.src=image.url;

Как только этот код завершит выполнение, у нас должна быть пропускная способность сети в килобитах в секунду, сохраненная в bw.

К сожалению, это не так просто из-за так называемого медленного старта TCP.

Медленный старт

Чтобы избежать перегрузки сети, оба конца TCP-соединения начнут медленно отправлять данные и будут ждать подтверждения (пакета ACK). Помните, что пакет ACK означает: «Я ПОДТВЕРЖДАЮ, что вы мне только что прислали». Каждый раз, когда он получает ACK без тайм-аута, он предполагает, что другой конец может работать быстрее и будет отправлять больше пакетов, прежде чем ждать следующего ACK. Если ACK не приходит в ожидаемый период времени, он предполагает, что другой конец не может работать достаточно быстро, и поэтому отступает.

Размеры окна TCP для медленного старта

Это означает, что наш вышеприведенный тест пропускной способности был бы в порядке, если бы наше изображение было достаточно маленьким, чтобы поместиться в текущее окно TCP, которое в начале установлено на 2. Хотя это нормально для медленных сетей, быстрая сеть действительно не будет Не обижайтесь на такое маленькое изображение.

Вместо этого мы попробуем отправлять изображения увеличивающегося размера и измерять время загрузки каждого из них.

Для целей кода глобальный image теперь объект представляет собой массив со следующей структурой:


var image = [
    {url: …, size: … }
];

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


var i=0;
var ld = function() {
   if(i > 0)
      image[i-1].end = +new Date;
   if(i >= image.length)
      done();
   else {
      var img = new Image;
      img.onload = ld;
      image[i].start = +new Date;
      img.src=image[i].url;
   }
   i++;
};

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

Наш код теперь выглядит так:


var i=0;
var ld = function() {
   if(i > 0) {
      image[i-1].end = +new Date;
      clearTimeout(image[i-1].timer);
   }
   if(i >= image.length ||
         (i > 0 && image[i-1].expired))
      done();
   else {
      var img = new Image;
      img.onload = ld;
      image[i].start = +new Date;
      image[i].timer =
            setTimeout(function() {
                       image[i].expired=true
                    },
                    image[i].timeout);
      img.src=image[i].url;
   }
   i++;
};

Это выглядит намного лучше — и работает намного лучше. Но мы увидим большую разницу между несколькими прогонами. Единственный способ уменьшить ошибку измерения — запустить тест несколько раз и получить суммарное значение, например медиану. Это компромисс между тем, насколько точным вы должны быть, и тем, как долго вы хотите, чтобы пользователь ждал, прежде чем тест завершится. Достижение пропускной способности сети на порядок часто является настолько близким, насколько вам нужно. Знание скорости соединения пользователя около 64 Кбит/с или 2 Мбит/с полезно, но гораздо менее полезно определить, точно ли это 2048 или 2500 Кбит/с.

Резюме и ссылки

Это все для части 1 этой серии. Мы рассмотрели, как пакеты, составляющие веб-запрос, проходят между браузером и сервером, как это меняется со временем, и как мы можем использовать JavaScript и немного статистики, чтобы сделать обоснованные предположения о характеристиках сети, которая мы работаем с.

В следующей части мы рассмотрим DNS и разницу между IPv6 и IPv4 и API WebTiming. Мы хотели бы знать, что вы думаете об этой статье и что бы вы хотели увидеть во второй части, так что дайте нам знать в комментариях.

А пока вот список ссылок на ресурсы, которые помогли составить этот документ.

  • Анализ сетевых характеристик с использованием JavaScript и DOM, часть 2
  • Эффективность веб-сайта: что нужно знать и что можно сделать
  • Дизайн, управляемый данными, в реальном мире
  • «Размеры изображений пропускной способности», таблица Google. Это основано на исследовании, проведенном при создании Boomerang.
  • Boomerang Проект Boomerang на GitHub, где реализовано многое из этого.
Сокрушительная редакция
(аль)



[ad_2]
Source: https://smashingmagazine.com

Заключение

Вы ознакомились с статьей — Анализ сетевых характеристик с использованием JavaScript и DOM, часть 1

Пожалуйста оцените статью, и напишите комментарий.

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован.

Краткое описание по статье Анализ сетевых характеристик с использованием JavaScript и DOM, часть 1

Название: Анализ сетевых характеристик с использованием JavaScript и DOM, часть 1 . Краткое описание: [ad_1] ⭐ Филип Т . Дата публикации: 20.02.2022 . Автор: Алишер Валеев .

Для чего создан сайт Novosti-Nedeli.ru

Данный сайт посвящен новостям мира и мира технологий . Также тут вы найдете руководства по различным девайсам.

Сколько лет сайту?

Возраст составляет 3 года

Кнопка «Наверх»