aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/performance/navigation_and_resource_timings/index.html
blob: bd6c3327d3a260f0f3ed593170f61430a032fa5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
---
title: Время загрузки страницы и ресурсов
slug: Web/Performance/Navigation_and_resource_timings
tags:
  - Производительность
translation_of: Web/Performance/Navigation_and_resource_timings
---
<p><span class="seoSummary"><strong>Тайминги навигации (Navigation timings) </strong>- это показатели, указывающие временные метки, в которые произошли события навигации. <strong>Тайминги ресурсов (Resource timings) </strong>- это детальные показатели по времени загрузки ресурсов. </span></p>

<p>В этой статье мы рассмотрим как <a href="/en-US/docs/Web/API/PerformanceTiming">Performance Timing API</a>, так и Performance Entry API. И хотя первый API считается устаревшим, он все ещё поддерживается всеми браузерами, он прост и о нем полезно знать. В свою очередь, Performance Entry API является более продвинутым инструментом, который позволяет не только получить более сложные данные, но и позволяет разработчику измерять другие показатели, в дополнение к данным о навигации и загрузке ресурсов.</p>

<h2 id="Performance_Timing_API"><strong>Performance Timing</strong> API</h2>

<p><a href="/en-US/docs/Web/API/PerformanceTiming">PerformanceTiming API</a> - это JavaScript API для измерения времени загрузки страницы. Этот API считается устаревшим, но поддерживается во всех браузерах. На текущий момент рекомендуется использовать <a href="/en-US/docs/Web/API/PerformanceNavigationTiming">performanceNavigationTiming</a> API.</p>

<p><a href="/en-US/docs/Web/API/PerformanceTiming">PerformanceTiming API </a>предоставляет собой read only данные в виде объекта, где значениями полей являются числа, указывающие на количество миллисекунд, которые прошли к моменту срабатывания того или иного события. Как показано на изображении ниже, процесс навигации можно разбить на следующие этапы: <code><a href="/en-US/docs/Web/API/PerformanceTiming/navigationStart">navigationStart</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/unloadEventStart">unloadEventStart</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/unloadEventEnd">unloadEventEnd</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/redirectStart">redirectStart</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/redirectEnd">redirectEnd</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/fetchStart">fetchStart</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/domainLookupStart">domainLookupStart</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/domainLookupEnd">domainLookupEnd</a></code>, <a href="/en-US/docs/Web/API/PerformanceTiming/connectStart">c<code>onnectStart</code></a> , <code><a href="/en-US/docs/Web/API/PerformanceTiming/connectEnd">connectEnd</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/secureConnectionStart">secureConnectionStart</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/requestStart">requestStart</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/responseStart">responseStart</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/responseEnd">responseEnd</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/domLoading">domLoading</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/domInteractive">domInteractive</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/domContentLoadedEventStart">domContentLoadedEventStart</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/domContentLoadedEventEnd">domContentLoadedEventEnd</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/domComplete">domComplete</a></code>, <code><a href="/en-US/docs/Web/API/PerformanceTiming/loadEventStart">loadEventStart</a></code>, и <code><a href="/en-US/docs/Web/API/PerformanceTiming/loadEventEnd">loadEventEnd</a></code>.</p>

<p><img alt="Navigation Timing event metrics" src="https://mdn.mozillademos.org/files/16620/Screen_Shot_2019-05-03_at_1.06.27_PM.png"></p>

<p>Благодаря этим метрикам и небольшим вычислениям мы можем определить важные показатели, например <a href="/en-US/docs/Glossary/time_to_first_byte">время до первого байта (time to first byte</a>), скорость загрузки страницы, поиска записи dns и даже узнать, является ли соединение безопасным.</p>

<p>Чтобы получить доступ к этим данным, обратитесь к следующему объекту:</p>

<pre>let time = window.performance.timing</pre>

<p>Мы можем использовать эти данные, чтобы понять, как быстро работает приложение:</p>

<p><img alt="entering window.performance.timing in the console lists all the timings in the PerformanceNavigationTiming interface" src="https://mdn.mozillademos.org/files/16824/navigatortiming.png"></p>

<p>Описание показателей:</p>

<table>
 <thead>
  <tr>
   <th>Показатель</th>
   <th>Пояснение</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{domxref("PerformanceTiming.navigationStart","navigationStart")}}</td>
   <td>
    <p>Момент, когда предыдущий документ в том же контексте (табе) запускает событие unload. Если предыдущего документа не было, значение этого показателя будет таким же, как и <code>PerformanceTiming.fetchStart</code>.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.secureConnectionStart","secureConnectionStart")}}</td>
   <td>
    <p>Началась установка (handshake) безопасного соединения. Если безопасного соединения нет, то значение равно <code>0</code>.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.redirectStart","redirectStart")}}</td>
   <td>Начало первого HTTP редиректа. Если никаких редиректов не было, или один из редиректов перевёл документ на другой origin, то значение равно <code>0</code>.</td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.redirectEnd","redirectEnd")}}</td>
   <td>
    <p>Последний HTTP редирект завершён, то есть последний байт HTTP-ответа был получен. Если никаких редиректов не было, или один из редиректов перевёл документ на другой origin, то значение равно <code>0</code>.</p>
   </td>
  </tr>
  <tr>
   <td>
    <p>{{domxref("PerformanceTiming.connectStart","connectStart")}}</p>
   </td>
   <td>
    <p>Запрос на открытие соединения отправлен в сеть. Если транспортный уровень модели OSI сообщает об ошибке и установка соединения запускаются заново, то возвращается время старта последней попытки соединения. Если используется постоянное соединение, то значение показателя будет таким же, как и <code>PerformanceTiming.fetchStart</code>.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.connectEnd","connectEnd")}}</td>
   <td>
    <p>Момент, когда соединение открыто для передачи данных. Если транспортный уровень модели OSI сообщает об ошибке и установка соединения запускаются заново, то возвращается время  завершения последней попытки соединения. Если используется постоянное соединение, то значение показателя будет таким же, как и <code>PerformanceTiming.fetchStart</code>. Соединение считается открытым, когда завершены все этапы установление безопасного соединения, например TLS Handshake или SOCKS Authentication.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.domainLookupEnd","domainLookupEnd")}}</td>
   <td>
    <p>Поиск домена завершён. Если используется постоянное соединение, или используются данные, сохраненные в локальном кэше, то значение показателя будет таким же, как и <code>PerformanceTiming.fetchStart</code>.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.domainLookupStart","domainLookupStart")}}</td>
   <td>Начался поиск домена. Если используется постоянное соединение, или используются данные, сохраненные в локальном кэше, то значение показателя будет таким же, как и <code>PerformanceTiming.fetchStart</code>.</td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.fetchStart","fetchStart")}}</td>
   <td>
    <p>Браузер готов к загрузке документа с помощью HTTP-запроса. Этот этап всегда <strong>срабатывает до проверки</strong> кэша приложения.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.requestStart","requestStart")}}</td>
   <td>
    <p>Браузер посылает запрос на получение документа с сервера или из кэша. Если транспортный уровень сообщает об ошибке отправки запроса, а соединение переоткрывается - этот показатель будет перезаписан данными нового запроса.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.responseStart","responseStart")}}</td>
   <td>
    <p>Браузер получает первый байт ответа от сервера, кэша или локального ресурса.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.responseEnd","responseEnd")}}</td>
   <td>
    <p>Браузер получает последний байт ответа от сервера, кэша или локального ресурса. Если соединение закрывается раньше получения последнего байта - значение параметра указывает на момент закрытия соединения.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.domLoading","domLoading")}}</td>
   <td>
    <p>Парсер HTML начинает работу. В этот момент {{domxref('Document.readyState')}} изменяется на <code>'loading'</code> и срабатывает событие {{DOMxRef("Document.readystatechange_event", "readystatechange")}}.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.unloadEventStart","unloadEventStart")}}</td>
   <td>
    <p>Срабатывает событие {{DOMxRef("Window.unload_event", "unload")}}&gt;, что говорит о времени, когда предыдущий документ начал выгружаться. Если предыдущего документа не было или переход к текущей странице подразумевал изменение origin (в т.ч. из-за редиректов), значение параметра равно <code>0</code>.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.unloadEventEnd","unloadEventEnd")}}</td>
   <td>
    <p>Обработчик события  <code><a href="/en-US/docs/Web/Events/unload">unload</a></code> завершил свою работу. Если предыдущего документа не было или переход к текущей странице подразумевал изменение origin (в т.ч. из-за редиректов), значение параметра равно <code>0</code>.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.domInteractive","domInteractive")}}</td>
   <td>
    <p>HTML парсер завершил работу над основным документом. В этот момент <a href="/en-US/docs/Web/API/Document/readyState"><code>Document.readyState</code></a> изменяется на <code>'interactive'</code> и срабатывает событие <code><a href="/en-US/docs/Web/Events/readystatechange">readystatechange</a></code></p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.domContentLoadedEventStart","domContentLoadedEventStart")}}</td>
   <td>
    <p>Момент сразу перед тем, как парсер запускает событие <code><a href="/en-US/docs/Web/Events/DOMContentLoaded">DOMContentLoaded</a></code>. Это событие запускается после того, как все скрипты, которые должны исполниться сразу после парсинга, выполнены.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.domContentLoadedEventEnd","domContentLoadedEventEnd")}}</td>
   <td>
    <p>Момент сразу после исполнения всех скриптов, которые должны были исполниться.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.domComplete","domComplete")}}</td>
   <td>
    <p>Парсер HTML завершил работу над основным документом. В этот момент <a href="/en-US/docs/Web/API/Document/readyState"><code>Document.readyState</code></a> изменяется на <code>'complete'</code> и срабатывает событие <code><a href="/en-US/docs/Web/Events/readystatechange">readystatechange</a></code>.</p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.loadEventStart","loadEventStart")}}</td>
   <td>
    <p>Событие <code><a href="/en-US/docs/Web/Events/load">load</a></code> было отправлено текущему документу. Если это событие на момент измерения не было отправлено документу, значение параметра равно <code>0.</code></p>
   </td>
  </tr>
  <tr>
   <td>{{domxref("PerformanceTiming.loadEventEnd","loadEventEnd")}}</td>
   <td>
    <p>Обработка события <code><a href="/en-US/docs/Web/Events/load">load</a></code> завершена, то есть загрузка завершена. Если это событие ещё не произошло или не было послано документу, значение параметра равно <code>0</code>.</p>
   </td>
  </tr>
 </tbody>
</table>

<h3 id="Вычисление_таймингов">Вычисление таймингов</h3>

<p>Мы можем использовать все эти значения, чтобы вычислить, сколько времени потребовалось на тот или иной этап:</p>

<pre class="brush: js">let
    dns  = time.domainLookupEnd - time.domainLookupStart,
    tcp  = time.connectEnd - time.connectStart,
    ssl != time.<code>secureConnectionStart</code>,</pre>

<h3 id="Время_до_первого_байта">Время до первого байта</h3>

<p><a href="/en-US/docs/Glossary/time_to_first_byte">Время до первого байта (Time to First Byte)</a> - это время между <code>navigationStart</code> и <code>responseStart</code> (момент, когда получен первый байт от сервера / кэша). Доступно в <code>performanceTiming</code> API</p>

<pre class="brush: js">let ttfb = time.responseStart - time.navigationStart;
</pre>

<h3 id="Время_загрузки_страницы">Время загрузки страницы</h3>

<p><a href="/en-US/docs/Glossary/Page_load_time">Время загрузки страницы (Page load time)</a> - это время между <code>navigationStart</code> и моментом, когда событие <code>load</code> отправлено текущего документу. Доступно только в <code>performanceTiming</code> API</p>

<pre class="brush: js">let pageloadtime = time.loadEventStart - time.navigationStart;</pre>

<h3 id="Время_поиска_записи_DNS">Время поиска записи DNS</h3>

<p>Время поиска записи DNS (DNS lookup) - это время между <code><a href="/en-US/docs/Web/API/PerformanceResourceTiming/domainLookupStart">domainLookupStart</a></code> и <code><a href="/en-US/docs/Web/API/PerformanceResourceTiming/domainLookupEnd">domainLookupEnd</a></code>. Оба эти параметра доступны как в <code>performanceTiming</code>, так и в <code>performanceNavigationTiming</code>.</p>

<pre class="brush: js">let dns  = time.domainLookupEnd - time.domainLookupStart;</pre>

<h3 id="TCP">TCP</h3>

<p>Время установки соединения <a href="/en-US/docs/Glossary/TCP">TCP</a> - это время между началом и окончанием попытки соединения:</p>

<pre class="brush: js">tcp  = time.connectEnd - time.connectStart;</pre>

<h3 id="Установка_безопасного_подключения_SSL_negotiation">Установка безопасного подключения (SSL negotiation)</h3>

<p><code><a href="/en-US/docs/Web/API/PerformanceResourceTiming/secureConnectionStart">secureConnectionStart</a></code> будет равен <code>undefined</code>, если SSL не доступен, <code>0</code> если <a href="/en-US/docs/Glossary/https">https</a> не используется или если временная метка доступна и используется. Другими словами, если безопасное соединение было использовано, то значение<code> secureConnectionStart</code> будет правдиво (<a href="/en-US/docs/Glossary/Truthy">truthy</a>), а время между<code> secureConnectionStart</code> и <code>requestStart</code> будет больше 0.</p>

<pre class="brush: js">ssl = time.requestStart - time.<code>secureConnectionStart;</code></pre>

<h2 id="Performance_Entry_API">Performance Entry API</h2>

<p>Основные показатели производительности, рассмотренные выше, считаются устаревшими, но полностью поддерживаются современными браузерами. Взамен предлагается использовать {{domxref('PerformanceEntry', 'Performance Entry API')}}, который предоставляет инструмент для пометок и измерений времени одновременно с событиями navigation и загрузкой resource. Вы также можете создавать свои маркеры:</p>

<pre class="brush: js">performance.getEntriesByType('navigation').forEach((navigation) =&gt; {
  console.dir(navigation);
});

performance.getEntriesByType('resource').forEach((resource) =&gt; {
  console.dir(resource);
});

performance.getEntriesByType('mark').forEach((mark) =&gt; {
  console.dir(mark);
});

performance.getEntriesByType("measure").forEach((measure) =&gt; {
  console.dir(measure);
});

performance.getEntriesByType('paint').forEach((paint) =&gt; {
  console.dir(paint);
});

performance.getEntriesByType('frame').forEach((frame) =&gt; {
  console.dir(frame);
});</pre>

<p>В некоторых браузерах вы можете использовать<code> performance.getEntriesByType('paint')</code>, чтобы запросить измерения для  <code>first-paint</code> и <code>first-contentful-paint</code>. Мы используем  <code>performance.getEntriesByType('navigation')</code> и  <code>performance.getEntriesByType('resource')</code> для запроса данных по навигации и загрузки ресурсов, соответственно.</p>

<h2 id="Navigation">Navigation</h2>

<p>Когда пользователь запрашивает веб-приложение,<a href="/en-US/docs/Learn/Performance/Populating_the_page:_how_browsers_work"> браузер должен получить некоторые мета-данные</a>, чтобы начать загрузку. Для этого пользовательский агент проходит серию шагов, такие как поиск записи DNS ({{glossary('DNS')}} lookup), TCP рукопожатие {{glossary('TCP handshake')}}, и установку безопасного соединения (SSL negotiation). Как только браузер установил соединение, происходит первый полезный запрос данных на сервера. Как только начинают поступать данные от сервера, браузер начинает парсить полученные данные, строит DOM, CSSOM, создает деревья рендера (render trees), чтобы в конце концов отрендерить страницу. В тот момент, когда браузер перестает парсить входящие данные, документ переходит в интерактивную стадию. Если в документе существуют отложенные к загрузке ресурсы (deferred scripts), которые должны быть обработаны, браузер парсит их. После этого запускается событие <a href="/en-US/docs/">DOMContentLoaded</a>, после которого готовность страницы завершена. Теперь документ может обрабатывать пост-загрузочные задачи. После этого документ маркируется, как полностью загруженный.</p>

<pre>let navigationTimings = performance.getEntriesByType('navigation');</pre>

<p>Метод <code>performance.getEntriesByType('navigation')</code> возвращает массив <a href="/en-US/docs/Web/API/PerformanceEntry">PerformanceEntry</a>, в котором содержатся объекты Navigation Timing.</p>

<p><img alt="The results of when performance.getEntriesByType('navigation'); is entered into the console for this document" src="https://mdn.mozillademos.org/files/16825/perfgentrybytypenavigation.png" style="height: 628px; width: 897px;"></p>

<p>Из этих данных можно многое извлечь. На изображении выше вы видите, что помимо самих таймингов, данные содержат имя документа и некоторую другую полезную информацию.</p>

<pre>let timing = performance.getEntriesByType('navigation')[0];</pre>

<h3 id="Протокол">Протокол</h3>

<p>Мы можем проверить протокол, который используется дл получения ресурсов:</p>

<pre>let protocol = <span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="cm-variable">timing</span>.<span class="cm-property">nextHopProtocol</span></span></span></span></pre>

<p>В текущем случае в ответ будет <span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="cm-property"><code>h2</code> для <code>http/2</code>.</span></span></span></span></p>

<h3 id="Сжатие">Сжатие</h3>

<p>Чтобы узнать, как эффективно сжимаются данные при передаче, мы можем разделить  <span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><code><span class="cm-property">transferSize</span></code><span class="cm-property"> на <code>decodedBodySize</code></span>, а затем вычесть результат из 100%. Для текущей страницы сжатие составляет до 74%.</span></span></span></p>

<pre><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="cm-keyword">let</span> <span class="cm-def">compressionSavings</span> <span class="cm-operator">=</span> <span class="cm-number">1</span> <span class="cm-operator">-</span> (<span class="cm-variable">timing</span>.<span class="cm-property">transferSize</span> <span class="cm-operator">/</span> <span class="cm-variable">timing</span>.<span class="cm-property">decodedBodySize</span>)</span></span></span></pre>

<p><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="cm-number">Мы могли бы использовать</span></span></span></span></p>

<pre><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="cm-keyword">let</span> <span class="cm-def">compressionSavings</span> <span class="cm-operator">= </span><span class="cm-number">1</span> <span class="cm-operator">-</span> (<span class="cm-variable">timing</span>.<span class="cm-property">encodedBodySize</span> <span class="cm-operator">/</span> <span class="cm-variable">timing</span>.<span class="cm-property">decodedBodySize</span>)</span></span></span></pre>

<p><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body">но <code>transfersize</code> так же включает в себя байты заголовков.</span></span></span></p>

<p>Для сравнение, мы можем посмотреть на вкладку Network, где увидим, что было передано <span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body">22.04KB для файла, который в разархивированном виде занимает 87.24KB. </span></span></span></p>

<p><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><img alt="View of the bytes transferred and the size via the network tab" src="https://mdn.mozillademos.org/files/16826/bytesdownloaded.png" style="height: 107px; width: 709px;"></span></span></span></p>

<p><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body">Если мы проверим вычисления, то результат получится схожим: </span></span></span><code>1 - (22.04 / 87.24) = 0.747</code>. Тайминги навигации позволяют нам получить такие данные программно.</p>

<p>Обратите внимание, что это данные для одного единственно документа, а не для всех ресурсов вместе взятых. В то же время, длительность загрузки, события-обработчики и тайминиги построения DOM / CSSOM влияют на продолжительность загрузки всего приложения, не только одного конкретного ресурса. Клиентские приложения, выполняющиеся в браузере, могут выглядеть быстрее, если данные объемом 300КБ вы передаете сжатыми до 100КБ, но это все не значит, что JavaScript, CSS или другие медиа-ресурсы не раздувают приложение и не делают его медленнее. Проверка уровня сжатия - это очень важно, но не менее важно проверять длительность парсинга ресурсов и время между тем, как завершен DOMContentLoaded и DOM готов к работе. Может случиться так, что время парсинга скриптов и обработка скриптами результатов в основном потоке (main thread) приведет к зависанию интерфейса.</p>

<h3 id="Время_запроса">Время запроса</h3>

<p>API не предоставляет все измерения, которые разработчик хочет получить. Например, как долго продлилось выполнение запроса? Отдельного поля в объекте данных нет. Однако, мы можем использовать измерения, чтобы вычислить то, что нам нужно.</p>

<p>Чтобы определить время ответа, вычтите время старта запроса из времени старта получения ответа. Запрос стартует ровно в тот момент, когда клиент запрашивает ресурс с сервера (или из кэша). Ответ начинается ровно в тот момент, когда клиент получает первый байт.</p>

<pre class="brush: js">request = <a href="/en-US/docs/Web/API/PerformanceNavigationTiming/responseStart"><code>timing.responseStart</code></a> - <a href="/en-US/docs/Web/API/PerformanceNavigationTiming/requestStart"><code>timing.requestStart</code></a></pre>

<h3 id="Длительность_события_загрузки">Длительность события загрузки</h3>

<pre class="brush: js">load = <a href="/en-US/docs/Web/API/PerformanceNavigationTiming/loadEventEnd"><code>timing.loadEventEnd</code> - <code>timing.loadEventStart</code></a> </pre>

<h3 id="DOMContentLoaded_event">DOMContentLoaded event</h3>

<p>Длительность события DOMContentLoaded определяется разностью моментов, когда клиент запускает событие DOMContentLoaded и когда это событие завершено. Старайтесь держать эту величину меньше 50ms - тогда ваш интерфейс будет отзывчивым.</p>

<pre class="brush: js">DOMContentLoaded = <a href="/en-US/docs/Web/API/PerformanceNavigationTiming/domContentLoadedEventEnd"><code>timing.domContentLoadedEventEnd</code></a> - <a href="/en-US/docs/Web/API/PerformanceNavigationTiming/domContentLoadedEventStart"><code>timing.domContentLoadedEventStart</code></a></pre>

<h3 id="Длительность_Duration">Длительность (Duration)</h3>

<p>В объекте данных есть поле Длительность (<code>Duration</code>). Длительность - это разница между <a href="/en-US/docs/Web/API/PerformanceNavigationTiming/loadEventEnd">PerformanceNavigationTiming.loadEventEnd</a> и <a href="/en-US/docs/Web/API/PerformanceEntry/startTime">PerformanceEntry.startTime</a> properties.</p>

<p>Интерфейс PerformanceNavigationTiming, кроме того, дает информацию о том, какой тип навигации вы измеряете, возвращая <code>navigate</code>, <code>reload</code>, <code>back_forward</code> или <code>prerender</code>.</p>

<h2 id="Resource">Resource</h2>

<p>В то время, как тайминги навигации измеряют производительность загрузки и парсинга основного файла HTML, этот файл служит лишь точкой входа для загрузки других ресурсов. Поэтому нам так же важно знать, как быстро загружаются дополнительные ресурсы. Для измерения этих данных нужно использовать Resource Timing. Большая часть измерений в этом объекте похожи: здесь и поиск домена в DNS, и TCP установка соединения и т.д.</p>

<p><img alt="Graphic of Resource Timing timestamps" src="https://mdn.mozillademos.org/files/12093/ResourceTiming-TimeStamps.jpg"></p>

<p>Для того, чтобы получить эти данные, выполните команду:</p>

<pre class="syntaxbox"><code><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="cm-variable">performance</span>.<span class="cm-property">getEntriesByType</span>(<span class="cm-string">"resource"</span>)</span></span></span></code></pre>

<h2 id="См._также">См. также</h2>

<ul>
 <li>{{domxref("PerformanceNavigationTiming")}}</li>
 <li>{{domxref("PerformanceResourceTiming")}},</li>
 <li>{{domxref("PerformanceMark")}}</li>
 <li>{{domxref("PerformanceMeasure")}}</li>
 <li>{{domxref("PerformancePaintTiming")}}</li>
</ul>