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
|
---
title: Lazy loading
slug: Web/Performance/Lazy_loading
tags:
- Ленивая загрузка
- Производительность
translation_of: Web/Performance/Lazy_loading
---
<p><span class="seoSummary"><strong>Lazy loading (ленивая загрузка) </strong><span>- это стратегия, направленная на определение ресурсов как неблокирующих (не критических) для того, чтобы отложить загрузку этих ресурсов на тот момент, когда они действительно необходимы. Так можно сократить длину <a href="/ru/docs/Web/Performance/Critical_rendering_path">критических этапов рендеринга</a>, что приводит к уменьшению времени загрузки приложения.</span></span></p>
<p>Ленивая загрузка может происходить в разные моменты работы приложения, но, как правило, она запускается во время взаимодействия пользователя и системы, например, при скроллинге или навигации.</p>
<h2 id="Обзор"><span>Обзор</span></h2>
<p>Вместе с ростом web-приложений драматически вырос объем и размеры ресурсов, отправляемых клиентскому приложению. С 2011 по 2019 медианный рост размеров ресурсов вырос с <strong>~100KB</strong> до <strong>~400KB</strong> для настольных компьютеров и с <strong>~50KB</strong> до <strong>~350KB</strong> для мобильных. А размер изображений вырос вырос с <strong>~250KB</strong> до <strong>~900KB</strong> для настольных компьютеров и со <strong>~100KB</strong> до <strong>~850KB</strong> для мобильных.</p>
<p>Очевидно, что такое повышение объёмов способствует увеличению длительности загрузки приложения. Один из способов её сократить - это отложить загрузку ресурсов, которые не являются критически важными для приложения. Например, вы посещаете приложение интернет-магазина, которое состоит из списка товаров и корзины. Очевидно, что вам не нужны изображения товаров, которые сейчас находится за пределами экрана; очевидно так же, что вам не нужно грузить все данные о содержимом корзины до тех пор, пока пользователь не перешёл к ней.</p>
<h2 id="Стратегии">Стратегии</h2>
<p>Ленивая загрузка (Lazy loading) может применяться к разным ресурсам и разными подходами. </p>
<h3 id="Общий_подход"> Общий подход</h3>
<p id="Code_splitting"><strong>Разделение кода (code splitting)</strong><br>
JavaScript, CSS и HTML могут быть разделены на небольшие части, называемые чанками (chunks). При первоначальной загрузке приложения вы можете отправлять не цельное приложение, а только необходимые части, например, только каркас разметки. Данные для заполнения этого каркаса могут быть подгружены позже, например, с помощью AJAX. Есть два вида разделения кода:</p>
<ul>
<li>Разделение по точкам входа (entrypoint)</li>
<li>Динамическое (<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import">dynamic import()</a>)</li>
</ul>
<h3 id="JavaScript"> JavaScript</h3>
<p><strong>Указание типа "module</strong>"<br>
Любой тег скрипта с <code>type="module"</code> рассматривается как <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules">JavaScript module</a>, а его загрузка откладывается по умолчанию.</p>
<h3 id="CSS"> CSS</h3>
<p>По умолчанию, CSS рассматривается как блокирующий рендер (<a href="https://developer.mozilla.org/en-US/docs/Web/Performance/Critical_rendering_path">render blocking</a>) ресурс, так что браузер не отобразит контент, пока объектная модель CSS (<a href="https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model">CSSOM</a>) не будет завершена. Поэтому начальный CSS файл должен небольшим, чтобы быть доставленным так быстро, как это возможно. Рекомендуется использовать media-queries для того, чтобы вместо одного монолитного css-файла грузить специализированные</p>
<pre><link href="style.css" rel="stylesheet" media="all">
<link href="portrait.css" rel="stylesheet" media="orientation:portrait">
<link href="print.css" rel="stylesheet" media="print">
</pre>
<p>Также в целях ускорения CSS можно применять оптимизации (<a href="CSS performance optimization">CSS optimizations</a>).</p>
<h3 id="Шрифты"> Шрифты</h3>
<p>По умолчанию, загрузка шрифтов откладывается на тот момент, пока дерево рендера (render tree) не сформировано полностью. Это приводит к тому, что текст страницы может появиться не сразу.</p>
<p>Вы можете переопределить такое поведение и загрузить шрифты заранее, используя <code><link rel="preload"></code>, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display">CSS font-display свойство</a> или <a href="https://developer.mozilla.org/en-US/docs/Web/API/CSS_Font_Loading_API">Font Loading API</a>.<br>
<br>
Смотри также: <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link">Element Link</a></p>
<h3 id="Изображения"> Изображения</h3>
<p>Очень часто веб-страницы содержат множество изображений, загрузка которых заметно нагружает канал передачи данных и увеличивает длительность загрузки. Подавляющая часть этих изображений находятся за видимой областью экрана и не являются необходимым (<a href="https://developer.mozilla.org/en-US/docs/Web/Performance/Critical_rendering_path">non-critical</a>), а для взаимодействия с пользователем требуют действия (например, прокрутки до них).</p>
<p><strong>Атрибут Loading </strong><br>
Атрибут {{htmlattrxref("loading", "img")}} элемента {{HTMLElement("img")}} (или {{htmlattrxref("loading", "iframe")}} атрибут для {{HTMLElement("iframe")}}) могут быть использованы, чтобы указать браузеру на необходимость отложить загрузку изображений / iframe до тех пор, пока пользователь не доскроллит до них.</p>
<pre><img src="image.jpg" loading="lazy" alt="..." />
<iframe src="video-player.html" loading="lazy"></iframe></pre>
<p>Событие <code>load</code> запускается, когда все другие необходимые ресурсы были загружены. В это время, возможно (или даже наиболее вероятно), что изображения не будут загружены, даже если пользователь доскроллит до изображений и они будут в {{Glossary("visual viewport")}}.</p>
<p>Вы можете определить, было ли загружено то или иное изображение, проверив Boolean значение {{domxref("HTMLImageElement.complete", "complete")}}.</p>
<p><strong>Полифил</strong><br>
Для использованиях в браузерах, которые не поддерживают данную технологию, рекомендуется использовать полифил: <a href="https://github.com/mfranzke/loading-attribute-polyfill" rel="noopener">loading-attribute-polyfill</a></p>
<p><strong>Intersection Observer API</strong><br>
<a href="https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver">Intersection Observers</a> позволяют вам узнать, как наблюдаемый вами элемент входит или выходит из зоны видимости браузера (viewport).</p>
<p><strong>Обработчики событий (Event handlers)</strong><br>
Intersection Observer API - относительно молодая технология, которая может не поддерживаться некоторыми устаревшими браузерами.<strong> </strong>Если поддержка браузеров важна для вас, есть несколько способов получить её:</p>
<ul>
<li><a href="https://github.com/w3c/IntersectionObserver">polyfill intersection observer</a></li>
<li>вы можете вычислять, находится ли элемент во viewport каждый раз при срабатывании событий scroll, resize или orientation change.</li>
</ul>
<h2 id="Смотри_также">Смотри также</h2>
<ul>
<li><a href="https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-blocking-css">Render blocking CSS</a></li>
<li><a href="https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/webfont-optimization#optimizing_loading_and_rendering">Optimizing loading and rendering</a></li>
<li><a href="https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video">Lazy loading images and video</a></li>
</ul>
<dl>
</dl>
|