Учим wordpress (и не только) отрисовывать быстро Youtube плееры

в 11:43, , рубрики: php, wordpress, YouTube, оптимизация сайта, плагины для wordpress, Повышение конверсии, Разработка веб-сайтов

youtube-speedload
Я вспомнил сайт одного старого приятеля-программиста, у которого в ленте сайта один хип-хоп, лет 6 назад он плевался на скорость загрузки страниц: «да-да-да, надо переделать, да ничего сложного там нет...» а вот зашел сейчас — все по-старому :-) Не смотря на простые технические решения, допускаю, что не только у меня есть такой приятель. Поэтому эта маленькая техническая заметка.


Мне же и самому приходилось часто публиковать лекции с нашего YouTube канала в ленте сайта, их накаливалось на одной страничке достаточно много. Да и при просмотре личных блогов встречаются подборки чужих или своих видео. И что меня нервировало, то как youtube кладет на производительность при встраивании. Чего там только не грузится через iframe ради той же картинки с кликом. И самое забавное, я просто может и не хочу смотреть видео, нафига мне грузить контент?

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

Вот тот же хабр, у него не так много попадается в ленте видео, поэтому это не столь востребовано. Однако, если популяризировать этот подход?

Давайте попробуем реализовать это на примере плагина для WordPress.

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

Что можно вытащить из Youtube

Youtube для встраивания контента использует oembed. Подробнее мой ответ на SO о том, что можно вытащить, без обращения к официальному API.

stackoverflow.com/questions/10066638/get-youtube-information-via-json-for-single-video-not-feed-in-javascript/23253789#23253789

Ответ в JSON
www.youtube.com/oembed?url=http://www.youtube.com/watch?v=ojCkgU5XGdg&format=json

Или xml
www.youtube.com/oembed?url=http://www.youtube.com/watch?v=ojCkgU5XGdg&format=xml

Типы превьюшек разных размеров hq, sd, maxres
img.youtube.com/vi/ojCkgU5XGdg/hqdefault.jpg
img.youtube.com/vi/ojCkgU5XGdg/sddefault.jpg
i.ytimg.com/vi/ojCkgU5XGdg/maxresdefault.jpg
img.youtube.com/vi/ojCkgU5XGdg/0.jpg
img.youtube.com/vi/ojCkgU5XGdg/1.jpg
img.youtube.com/vi/ojCkgU5XGdg/2.jpg
img.youtube.com/vi/ojCkgU5XGdg/3.jpg

Аннотации к видео
www.youtube.com/annotations_invideo?cap_hist=1&video_id=ojCkgU5XGdg

Еще одна ссылка
www.youtube.com/get_video_info?html5=1&video_id=ojCkgU5XGdg

А это вам пригодится, если вы делаете стримы.
www.youtube.com/embed/live_stream?channel=UCkA21M22vGK9GtAvq3DvSlA

Превью прямых трансляций
i.ytimg.com/vi/W-fSCPrYSL8/hqdefault_live.jpg

Жаль, что YT не поддерживает jsonp. Поэтому полностью отказаться от сохранения данных у нас не получится.

Как вордпресс кеширует oembed

WordPress поддерживает автовстраивание при нахождении ссылок в редакторе из белого списка. При срабатывании этого события он создает мета-поле к посту с префиксом _oembed_, а при выводе — подменяет на html код из кеша.

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

Фильтр add_filter('embed_oembed_html'); позволяет до вывода поста подменить кеш. Он представляет из себя всем известный iframe.

<iframe width="" height=""  src=""></iframe>

Так как пока разбираются, почему гугл не формирует title для своих iframe (ticket #4024) мы, увы, вынуждены делать разово запрос на сервер для захвата title в кеш.

Как обновить кеш своими данными

add_filter('embed_oembed_html', 'ytsl_oembed_html', 1, 3);
ytsl_oembed_html($cache, $url, $attr){};

В момент срабатывания фильтра, я ищу в переменной $cache наличие моего тега data-ytsl. Если его нет, то делаю запрос на

http://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=ojCkgU5XGdg&format=json

и формирую содержание нового тега. В итоге кеш выглядит вот так:

<iframe width="" height=""  src=" " data-ytsl=" "></iframe>

Обновление кеша делается так. Сначала считаем ключ

$cachekey   = '_oembed_' . md5( $url . serialize( $attr ) );

А потом обновляем.

update_post_meta( get_the_ID(), $cachekey, $cache );

Если же мой тег data-ytsl обнаруживается, я вытаскиваю из него title и id и формирую html.
В data-iframe я вставляю уже чистый код кеша без моего тега, для того чтобы по клику подменить этим содержанием верстку.

<div class='ytsl-click_div' data-iframe='$ytsl' style='$fixed position:relative;background: url($thumb_url) no-repeat scroll center center / cover' >
    <div class='ytsl-title_grad'>
        <div class='ytsl-title_text'>{$json['title']}</div>
    </div>
    <div class='ytsl-play_b'></div>
</div>"

Css -ка на гитхабе, тут нет смыла ее показывать.

В итоге плеер выглядит вот так.
Учим wordpress (и не только) отрисовывать быстро Youtube плееры - 2

В качестве отличия, я сделал кнопку play другого цвета. А вот то что тайтл написал Arial, а не кастомным шрифтом, который тоже грузится через iframe, по-моему, ни сколько не влияет на узнаваемость.

Итоговое решение обработки «на лету» очень скоростное, и судя по плагину профайлеру P3 от goDaddy обходится совершенно безболезненно. Поэтому удалось найти баланс между удобством и скоростью. Плагин вообще не требует от пользователя никаких действий. Он просто показывает картинки вместо iframe когда включен.

На фронтенде.

Всего лишь подключаем скрипт. Все до безобразия элементарно:

(function(){
  var f = document.querySelectorAll(".ytsl-click_div");
  for (var i = 0; i < f.length; ++i) {
       f[i].onclick = function () {
	 this.parentElement.innerHTML = this.getAttribute("data-iframe");
      }
    }
})();

Минусы — на мобильных устройствах браузеры шибко умные, и умеют делать это самостоятельно. Поэтому если не делать определение мобильных устройств, для воспроизведения придется делать по два клика.

Остальных минусов не заметил за довольно большой промежуток времени.

Ну а кота нарисовал в нагрузку за не столь длинный, и не столь технически интересный рассказ.

Код лежит тут github.com/Alexufo/youtube-speedload

Автор: Александр Борисович

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js