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

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

В BuildZoom мы в настоящее время используем AngularJS 1.5.8 в качестве нашей клиентской среды, которая будет использоваться в этом примере. Хотя такой же функциональности можно добиться и с помощью ванильного JS.

Есть два распространенных способа отображения изображений с помощью HTML / CSS:

  • HTML-тег img
  • Атрибут CSS background-image

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

Отложить загрузку изображений для HTML img

Типичный тег HTML img автоматически запускает запрос изображения на основе значения атрибута src:

<img src="thumbnail.png" />

Цель состоит в том, чтобы контролировать выполнение запроса. Для этого атрибут src должен быть изначально опущен и устанавливаться только после того, как событие load было инициировано браузером.

Ниже представлена ​​директива Angular, которая принимает в качестве входных данных желаемое значение атрибута src, настраивает прослушиватель для события load и устанавливает src атрибута HTML img элемента после срабатывания события. Некоторые браузеры вместо этого запускают событие onload, поэтому есть запасной вариант.

angular.module("myApp").directive('deferImageLoad', [function () {
   return {
      restrict: 'A',
      scope: {},
      controllerAs: '$ctrl',
      bindToController: {
         imageSrc: '@'
      },
      controller: ['$element', function ($element) {
         this.$onInit = function () {
            if (window.addEventListener) {
               window.addEventListener("load",
                   this.setImageSrc.bind(this), false);
            }
            else if (window.attachEvent) {
               window.attachEvent("onload",
                   this.setImageSrc.bind(this));
            }
         };

         this.setImageSrc = function () {
            $element.attr('src',  this.imageSrc);
         };
      }]
   };
}]);

Эта директива используется в теге HTML img, причем атрибут image-src изначально заменяет src:

<img defer-image-load image-src="thumbnail.png"/>

Атрибут src устанавливается только после события load, что не позволяет изображению thumbnail.png блокировать сначала загрузку критически важного содержания на странице.

Отложить загрузку изображения для фонового изображения CSS

Типичный атрибут CSS background-image автоматически запускает запрос изображения на основе значения ввода url ():

.thumbnail {
    background-image: url("thumbnail.png");
    width: 30px;
    height: 20px;
}

Класс CSS будет применен к элементу HTML:

<div class="thumbnail"></div>

Цель остается прежней: контролировать, когда будет сделан запрос.

Во-первых, необходимо обновить CSS, чтобы в классе CSS был только атрибут background-image, который передается в директиву deferring:

.thumbnail {
    width: 30px;
    height: 20px; 
}
.thumbnail.with-image {
    background-image: url("thumbnail.png");
}

Ниже приведена директива, которая принимает в качестве входных данных имя класса CSS надстройки, настраивает прослушиватель для события load и добавляет класс CSS в HTML. элемент после срабатывания события load:

angular.module("myApp").directive('addClassOnLoad', [function () {
   return {
      restrict: 'A',
      scope: {},
      controllerAs: '$ctrl',
      bindToController: {
         cssClass: '@'
      },
      controller: ['$element', function ($element) {
         this.$onInit = function () {
            if (window.addEventListener) {
               window.addEventListener("load",
                   this.addClassToElement.bind(this), false);
            }
            else if (window.attachEvent) {
               window.attachEvent("onload",
                   this.addClassToElement.bind(this));
            }
         };

         this.addClassToElement = function () {
            $element.addClass(this.cssClass);
         };
      }]
   };
}]);

Затем директива addClassOnLoad применяется к элементу HTML:

<div add-class-on-load css-class="with-image"
     class="thumbnail"></div>

Класс with-image добавляется только после события load, что не позволяет изображению thumbnail.png блокировать сначала загрузку критически важного содержания на странице. .