Статьи

Более быстрый YouTube встраивает JavaScript

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

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

Одно простое видео на странице, вызываемое через безобидный iframe, может добавить до 6 HTTP-запросов и до 450 КБ контента. Решение, которое я предлагаю в этой статье, может уменьшить эти числа до 1 запроса и около 50 КБ на видео вместе с несколькими байтами JavaScript (поверх библиотеки jQuery, если вам не нравится ванильный вкус).

И знаешь, что? Это решение не ново. Ранее он был предложен Амитом Агарвалом в апреле 2013 года .

Итак, что за хитрость?

В решении Amit DOM анализируется с помощью JavaScript при загрузке документа, и каждый вызов видео YouTube (через специальный div, а не обычный iframe) заменяется предварительным просмотром эскиза, к которому прикрепляется iframe при нажатии на него.

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

Моя маленькая добавленная стоимость

Я переписал код Amit на простом JavaScript и jQuery для тех, кто заинтересован. Я сохранил оригинальные комментарии в коде, чтобы сделать его максимально понятным. Моя версия добавляет новую функцию в параметр данных HTML5, которая позволяет добавлять любой параметр в URL-адрес YouTube для настройки видео.

YouTube предлагает список параметров для отображения и скрытия элементов управления, маркировки и информации, а также для настройки качества видео или начального кадра вашего видео (среди прочего).

  • Средства управления : установите это в 0, и средства управления слоем не отображаются на видео проигрывателе.
  • modestbranding : установите для этого параметра значение 1, и логотип YouTube исчезнет с панели управления.
  • rel : установите это значение в 0, и никакие связанные видео не будут показаны, когда закончится воспроизведение исходного видео.
  • showinfo : установите для этого параметра значение 0, и проигрыватель не будет отображать информацию, такую ​​как название видео и загрузчик, до начала воспроизведения видео.
  • start : установите это значение в секундах, и проигрыватель начнет воспроизведение видео с этого времени (точнее, с ближайшего ключевого кадра).
  • vq : установите желаемое качество видео, если оно поддерживается (например, hd720

При добавлении iframe YouTube в событие click некоторым параметрам присваиваются значения, а именно autoplayautohide

Поддерживаемые эскизы YouTube

Каждое видео на YouTube содержит список сгенерированных изображений. Вы можете получить к ним доступ через URL-адрес http://img.youtube.com/vi/<youtube-video-id>/<youtube-thumbnail>img.youtube.comi.ytimg.com

Те, которые нас интересуют:

  • default.jpg (версия по умолчанию, 120px x 90px)
  • hqdefault.jpg (высококачественная версия, 480px × 360px)
  • mqdefault.jpg (версия среднего качества, 320 × 180 пикселей)
  • sddefault.jpg (стандартная версия, 640 × 480 пикселей)
  • maxresdefault.jpg (версия с максимальным разрешением, 1.280px × 720px)

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

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

HTML

HTML-код устанавливает идентификатор видео YouTube, определяет размер видео (ширину и высоту) и перечисляет параметры URL-адреса YouTube, если это необходимо.

 <div class="youtube"
     id="fsrJWUVoXeM" 
     style="width: 500px; height: 281px;">
</div>

<div class="youtube" 
     id="lR4tJr7sMPM" 
     data-params="modestbranding=1&showinfo=0&controls=0&vq=hd720"
     style="width: 640px; height: 360px;">
</div>

CSS

В двух видео, использованных в качестве примеров, соотношение сторон составляет 16: 9, что возвращает миниатюру sddefault.jpg с горизонтальными черными полосами. Чтобы скрыть их при отображении этого эскиза, свойство background-positioncenterdivstyle="width:500px;height:281px;" , Таким образом, на одной странице можно показывать видео разных размеров.

Значок воспроизведения, который сообщает пользователям, что содержимое не является простым изображением, добавляется в слой поверх миниатюры с переходом непрозрачности, чтобы выделить его. Здесь мы используем png с кодировкой URI данных base64 (из IconFinder ), который сохраняет HTTP-запрос и работает до IE8.

 .youtube {
    background-position: center;
    background-repeat: no-repeat;
    position: relative;
    display: inline-block;
    overflow: hidden;
    transition: all 200ms ease-out;
    cursor: pointer;
}

.youtube .play {
    background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAERklEQVR4nOWbTWhcVRTHb1IJVoxGtNCNdal2JYJReC6GWuO83PM/59yUS3FRFARdFlwYP1CfiojQWt36sRCUurRIdVFXIn41lAoVdRGrG1M01YpKrWjiYmaSl8ybZJL3cd+YA//NLObd3++eO8x79z5jSq5Gw+8kov0AP8vMR5l1BtBZQM4B8ks75wCdZdYZZj5qLZ4hov2Nht9Z9vhKKSIaB/gI4M4w62KeAO6Mte4lYOq20FxrlqqOibhHmeWbvNC9ZfDX1mLae391aN6limO/gwgvAPJbWeAZuSDingdwXTBw7/0IsyaA/Fkh+KqOkD+YNfHej1QKD+y7iVlOhgLvFqFfNJvNGyuBJ+KDAF8MDd0tgS8y64OlgSdJMsysL4cG7SOHkyQZLhTee7+d2R2rAVy/S+Jd7/32ouBHAP4gNNRGQyTHc/84NhqNywZp5rvjjnnvt21aABFeCQ+RLwAf2hQ8s7sv9OCLk6AHNgQvIrvbfzKCD76g/O6cu7lf/iER/aQGgy448pExZmhdegAPhR9sObFWH1gT3lp7DaA/5bkIgJhZPgsNmz02novj+KqeApj1ubwXWe4kdyeznAgNvTpE/HQmvKqOMeuFogTUVQSRno+iaLRLAJF7uIgL9O4ubgL8aWgB7S44mNX+35YpICUiAvS9sBLkq1WzT+NFffl6AuoiApi6NT37h6sWkBIRZGkQ8YtLgyji6e1mBYTqCEBPG2Naz+0BWQgtoGoRgCzEsd9hAN1X5BfnFZASUfrSAFQNsyZ1FJASUVpHiLinDJG8U2cBZYogkrcNs5waBAGdstbeU9zdqpw0gPwwSAI6VUxHyFlDpOcHUUBBIuYNs14aZAE5RVwyzPr3/0EAEY0TyfGNjBWQvwZ +CTSbehfAH29mrID8bET0+0EUkAd8WYDOmqJ3ecsG30yr9wqRfm6Y+a1BEFDEjHfHvWmY9ck6CygHvBVr8Xhtb4ZE5HZA3y8DvBNA1TjnrmXWf+sioMwZX5V/VHXMGGMMoKdDCxCRvRWBdzKzdHEO+EisilbPyopHYqp6S9UCAsz4iojI7hUDAtyXVQgIDd6KnOoaWNkbI6FaPSuZGyMArsi7MZoloB4zviI/Nhr3X95jltwTRQmoIfgisy5ai+me67OI7fE4nrqjrqfK1t0eby0FPRB6oGVlchL3rgnfrq19RKbVBdhV9IOSwJmfmJi4vi/4ThERitwyCxVAFqydshuCX5awhQ9KtmuIWd8IDZED/nXT77rvVVv6sHRKwjYi91poqP7Dr+Y6JJ1VSZIMA3wkPNy6bX+o8Bcm0sXMdwM8Fxo0A3xORPaWBp6uPXsmbxCRD0NDL0dOANhVCXy6iAjMcjbcrMt3RITKwdMVRdFo+y5yvkL4eWZ+zHt/ZVD4dEVRNGotpst+dZZZH8k86lqn2pIvT/eqrNfn2xuyqYPZ8mv7s8pfn/8Pybm4TIjanscAAAAASUVORK5CYII=") no-repeat center center;
    background-size: 64px 64px;
    position: absolute;
    height: 100%;
    width: 100%;
    opacity: .8;
    filter: alpha(opacity=80);
    transition: all 0.2s ease-out;
}

.youtube .play:hover {
    opacity: 1;
    filter: alpha(opacity=100);
}

Реализация JavaScript в ванили

Без зависимостей и самой быстрой реализации, версия Vanilla JavaScript использует самый маленький готовый код DOM, который я смог найти.

Различия в браузерах по-прежнему необходимо учитывать, например, отсутствие поддержки метода getElementsByClassName

 'use strict';
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}
r(function(){
    if (!document.getElementsByClassName) {
        // IE8 support
        var getElementsByClassName = function(node, classname) {
            var a = [];
            var re = new RegExp('(^| )'+classname+'( |$)');
            var els = node.getElementsByTagName("*");
            for(var i=0,j=els.length; i<j; i++)
                if(re.test(els[i].className))a.push(els[i]);
            return a;
        }
        var videos = getElementsByClassName(document.body,"youtube");
    } else {
        var videos = document.getElementsByClassName("youtube");
    }

    var nb_videos = videos.length;
    for (var i=0; i<nb_videos; i++) {
        // Based on the YouTube ID, we can easily find the thumbnail image
        videos[i].style.backgroundImage = 'url(http://i.ytimg.com/vi/' + videos[i].id + '/sddefault.jpg)';

        // Overlay the Play icon to make it look like a video player
        var play = document.createElement("div");
        play.setAttribute("class","play");
        videos[i].appendChild(play);

        videos[i].onclick = function() {
            // Create an iFrame with autoplay set to true
            var iframe = document.createElement("iframe");
            var iframe_url = "https://www.youtube.com/embed/" + this.id + "?autoplay=1&autohide=1";
            if (this.getAttribute("data-params")) iframe_url+='&'+this.getAttribute("data-params");
            iframe.setAttribute("src",iframe_url);
            iframe.setAttribute("frameborder",'0');

            // The height and width of the iFrame should be the same as parent
            iframe.style.width  = this.style.width;
            iframe.style.height = this.style.height;

            // Replace the YouTube thumbnail with YouTube Player
            this.parentNode.replaceChild(iframe, this);
        }
    }
});

А вот демонстрация кода в действии:

Реализация jQuery

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

 "use strict";
$(function() {
    $(".youtube").each(function() {
        // Based on the YouTube ID, we can easily find the thumbnail image
        $(this).css('background-image', 'url(http://i.ytimg.com/vi/' + this.id + '/sddefault.jpg)');
    
        // Overlay the Play icon to make it look like a video player
        $(this).append($('<div/>', {'class': 'play'}));
    
        $(document).delegate('#'+this.id, 'click', function() {
            // Create an iFrame with autoplay set to true
            var iframe_url = "https://www.youtube.com/embed/" + this.id + "?autoplay=1&autohide=1";
            if ($(this).data('params')) iframe_url+='&'+$(this).data('params');
    
            // The height and width of the iFrame should be the same as parent
            var iframe = $('<iframe/>', {'frameborder': '0', 'src': iframe_url, 'width': $(this).width(), 'height': $(this).height() })
    
            // Replace the YouTube thumbnail with YouTube HTML5 Player
            $(this).replaceWith(iframe);
        });
    });
 });

А вот демоверсия версии jQuery:

Окончательные результаты

Теперь давайте поговорим о том, что мы получаем в реальных ситуациях.

Это решение было реализовано на этой странице , которая представляет собой статью, которая содержит 3 встроенных видео YouTube. Вот результаты:

  • Перед внедрением этого решения у нас было 20 HTTP-запросов и 636,2 Кбайт загруженного контента, что заняло 2,22 с (3,59 с при загрузке).
  • После реализации мы сократили до 17 запросов, 370,7 КБ и 1,05 с (нагрузка: 733 мс).
  • Это означает на 15% меньше запросов и веб-страницу, которая на 41% легче и на 52% быстрее (загрузка: на 80% быстрее).

Результаты довольно хорошие, даже с одним встроенным видео на YouTube, как на следующей странице , которая является нашим следующим примером. Вот результаты для страницы с одним видео:

  • Перед внедрением решения у нас было 20 HTTP-запросов и 684,4 Кбайт загруженного контента, что заняло 2,13 с (загрузка 2,14 с).
  • После реализации мы сократили до 17 запросов, 322,4 КБ и 1,24 с (нагрузка: 975 мс).
  • Это означает, что мы получили на 15% меньше запросов и веб-страницу на 53% легче и на 42% быстрее (загрузка: на 54% быстрее).

Вывод

В заключение, я думаю, что мы все можем согласиться с тем, что сокращение веса страницы с 40 до 50% стоит того небольшого куска кода, не правда ли?

Если у вас есть какие-либо мысли по поводу кода или вы хотите улучшить его, не стесняйтесь раскошелиться на CodePen или поделиться своими взглядами в комментариях.

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