Повышаем производительность: как загружать изображения при помощи in-view.js

Повышаем производительность: как загружать изображения при помощи in-view.js

От автора: в этом уроке я покажу вам, как повысить производительность веб-страниц при помощи in-view.js. Эта JS библиотека посылает ответ, когда что-либо попадает в видимое окно браузера во время прокрутки страницы. С ее помощью мы сможем динамически загружать изображения тогда, когда они нужны.

Производительность имеет значение

Веб-производительность играет большую роль, особенно если ваш сайт нацелен на развивающиеся страны с медленным интернетом и дорогими тарифными планами. Среди стандартных задач по повышению производительности, которые мы предпринимаем, можно выделить минификацию файлов JS и стилей, сжатие медиа файлов, уменьшение изображений. Если выполнить все эти манипуляции, наш сайт получит значительный прирост производительности. Но так ли это?

Повышаем производительность: как загружать изображения при помощи in-view.js

В примере выше в инспекторе показано, как одна страница загружает 24 изображения на мобильном устройстве с обычной скоростью 3G. Как мы видим, полная загрузка страницы занимает около 11 секунд! Это очень медленно, если учесть, что на странице всего несколько изображений и есть файлы стилей. Страница не захламлена рекламой, отслеживающими скриптами, которые обычно прибавляют страницу в весе.

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

Современные технологии веб-разработки

AngularJS, Webpack, NodeJS, ReactJS, TypeScript, Gulp, Git, Github...
Узнайте все о современных технологиях в веб-разработке

Узнать подробнее

Так как же повысить производительность загрузки страниц?

Узкое место

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

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

Начинаем

Чтобы дальше работать, скачайте index-starter.html из репозитория. Также там лежит файл стилей css/styles-starter.css, можете им воспользоваться.

Прежде всего, нам нужно заменить изображения на очень маленькие, предпочтительно закодированные в base64, чтобы избежать лишних HTTP запросов. Эти изображения будут играть роль плейсхолдеров перед загрузкой полноценных изображений. Настоящие изображения мы будем хранить в пользовательском атрибуте data-src.

<figure class="post__image">
 <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="./images/image-24.jpg" alt="" width="800" height="554">
</figure>

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

Повышаем производительность: как загружать изображения при помощи in-view.js

Давайте поправим стили.

Сохраняем соотношение сторон изображений

Наши реальные изображения имеют размер 800 на 550 пикселей. Разделим высоту изображения (800px) на его ширину (500px) и умножим результат на 100%. Полученное значение используем как padding top для псевдоэлемента контейнера изображения. Нам осталось задать изображению абсолютное позиционирование и максимальную высоту на 100%. Так высота изображения не будет сохраняться.

figure {
 position: relative;
}
figure img {
 top: 0;
 left: 0;
 position: absolute;
 max-height: 100%;
}
figure:before {
 padding-top: 69.25%; // ( 554 / 800 ) * 100%
}

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

Повышаем производительность: как загружать изображения при помощи in-view.js

Изображение с правильным соотношением сторон, само изображение еще загружается

Загружаем изображение

Во-первых, на страницу нужно загрузить in-view.js. Выше уже говорилось, что это легковесная библиотека (не зависит от JQuery и таких базовых библиотек, как Waypoints) определяет, попал ли элемент в видимую область окна браузера или нет.

Создайте JS файл, в котором мы будем писать код, и подключите его после in-view.js, как показано ниже:

<script src="./js/in-view.min.js"></script>
<script src="./js/scripts.js"></script>

Методы и функции

В библиотеке in-view.js есть функция inView(), принимающая в качестве аргумента селектор. В нашем случае мы будем передавать элемент figure, элемент, который оборачивает изображения. Мы выбрали контейнер, потому что мы пропишем пару классов для плавных переходов. Это намного проще сделать, когда класс присвоен контейнеру, а не самому изображению.

Современные технологии веб-разработки

AngularJS, Webpack, NodeJS, ReactJS, TypeScript, Gulp, Git, Github...
Узнайте все о современных технологиях в веб-разработке

Узнать подробнее
inView('figure')

Затем с помощью метода .on() мы присвоим элементу событие enter для проверки, попал ли элемент в область видимости. Также в in-view.js есть событие exit, которое выполняет противоположную проверку. Оно определяет, когда элемент скрылся из видимой области.

inView( 'figure' ).on( 'enter', function( figure ) {
 
 var img = figure.querySelector( 'img' ); // 1
 
 if (  'undefined' !== typeof img.dataset.src ) { // 2
 
 figure.classList.add( 'is-loading' ); // 3
 
 // 4
 newImg = new Image();
 newImg.src = img.dataset.src;
 
 newImg.addEventListener( 'load', function() {
 
 figure.innerHTML = ''; // 5
 figure.appendChild( this );
 
 // 6
 setTimeout( function() {
 figure.classList.remove( 'is-loading' );
 figure.classList.add( 'is-loaded' );
 }, 300 );
 } );
 }
} );

Событие enter будет запускать функцию, которая будет:

выбирать изображение внутри тега figure;

проверять в нем атрибут data-src;

добавлять класс is-loading к контейнеру, т.е. тегу figure;

загружать новое изображение по ссылке, полученной из атрибута data-src;

после загрузки вставлять изображение в контейнер;

и наконец, будет заменять класс is-loading на is-loaded.

Загружаем что хотим

В коде выше появилось два новых класса, is-loading и is-loaded. С помощью класса is-loading мы добавляем спиннер анимацию на время загрузки изображения. Из имени второго класса ясно, что он добавляется после загрузки изображения, чтобы плавно показать его.

figure.is-loaded img {
 animation: fadeIn 0.38s linear 1s forwards;
}
figure.is-loading {
 position: relative;
}
figure.is-loading:after {
 content: '';
 display: block;
 color: #ddd;
 font-size: 30px;
 text-indent: -9999em;
 overflow: hidden;
 width: 1em;
 height: 1em;
 border-radius: 50%;
 margin: auto;
 position: absolute;
 top: 50%;
 left: 50%;
 margin-left: -0.5em;
 margin-top: -0.5em;
 transform: translateZ(0);
 animation: loading 1.7s infinite ease;
}
@keyframes loading {
 0% {
 transform: rotate(0deg);
 box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
 }
 
 5%,
 95% {
 box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
 }
 10%,
 59% {
 box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em;
 }
 20% {
 box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em;
 }
 38% {
 box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em;
 }
 100% {
 transform: rotate(360deg);
 box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
 }
}
@keyframes fadeIn {
 0% {
 opacity: 0;
 }
 
 100% {
 opacity: 1;
 }
}

Фолбэк

Надейся на лучшее, готовься к худшему. Если каким-либо образом будет отключен JS (маловероятно, но вполне возможно), нужно убедиться, что изображения отображаются. Пропишите настоящие изображения в тегах noscript.

<figure>
 <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="./images/image-24.jpg" alt="" width="800" height="554">
 <noscript>
 <img src="./images/image-24.jpg" alt="" width="800" height="554">
 </noscript>
</figure>

Мы закончили! Обновите страницу. Если теперь проинспектировать временную линию на вкладке сеть в панели разработчика, можно увидеть, что скорость загрузки значительно выросла, так как мы загружаем только то, что видит пользователь.

Повышаем производительность: как загружать изображения при помощи in-view.js

Теперь страница загружается всего за 1.95 секунды на обычном 3G соединении. Прирост производительности более чем на 500%!

Заключение

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

Существует множество JS библиотек и JQuery плагинов, делающих то же самое. Почему именно in-view.js? Лично для меня, in-view.js был скриптом, который я искал, так как он выполняет только то, что от него требуется. Он предназначен для единственной цели и хорошо с ней справляется. Такая библиотека дает вам больше контроля и гибкости.

К примеру, in-view.js можно использовать не только для ленивой загрузки, но также и для создания бесконечного скрола, отображения плавающей формы подписки, когда пользователь долистывает до конца страницы (посмотрите демо) или для создания вертикального таймлайна без необходимости подключать еще одну JS библиотеку. А как вы используете эту библиотеку?

Повышаем производительность: как загружать изображения при помощи in-view.js

Плавающая форма подписки, плавно появляющаяся, когда пользователь прокручивает страницу до конца.

Автор: Louie R.

Источник: https://webdesign.tutsplus.com/

Редакция: Команда webformyself.

Современные технологии веб-разработки

AngularJS, Webpack, NodeJS, ReactJS, TypeScript, Gulp, Git, Github...
Узнайте все о современных технологиях в веб-разработке

Узнать подробнее
Самые свежие новости IT и веб-разработки на нашем Telegram-канале

Курс по JavaScript: основы

Изучите JavaScript с нуля до результата!

Смотреть курс

Метки:

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

Комментарии Вконтакте:

Комментарии Facebook:

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree