wp_enqueue_script с использованием скриптов из CDN и резервным вариантом
Я хочу подключить несколько скриптов и стилей с удаленного CDN... в данном случае bootstrap и подобные файлы, но мне нужно обеспечить резервный вариант в виде callback-функции на случай, если CDN по какой-то причине недоступен...
Я бы добавил какой-то код, но я действительно не знаю, как подойти к этому вопросу...
Вот пример обычного wp_enqueue_script, который я сейчас использую:
wp_enqueue_script( 'bootstrap', 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js', array('jquery'), 3.3, true);

Я взял предыдущий пост и сделал с ним 2 вещи:
- использовал нативные функции WordPress для HTTP-запросов
- кешировал статус доступности CDN на 20 минут (это значение можно изменить). Нет смысла проверять доступность CDN при КАЖДОЙ загрузке страницы. Это сводит на нет все преимущества ускорения сайта с помощью CDN.
$get_the_url = 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js';
$cdnIsUp = get_transient( 'cnd_is_up' );
if ( $cdnIsUp ) {
$load_source = 'load_external_bootstrap';
} else {
$cdn_response = wp_remote_get( $get_the_url );
if( is_wp_error( $cdn_response ) || wp_remote_retrieve_response_code($cdn_response) != '200' ) {
$load_source = 'load_local_bootstrap';
}
else {
$cdnIsUp = set_transient( 'cnd_is_up', true, MINUTE_IN_SECONDS * 20 );
$load_source = 'load_external_bootstrap';
}
}
add_action('wp_enqueue_scripts', $load_source );
function load_external_bootstrap() {
wp_register_script( 'bootstrap', 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js', array('jquery'), 3.3, true);
wp_enqueue_script('bootstrap');
}
function load_local_bootstrap() {
wp_register_script('bootstrap', get_bloginfo('template_url').'/js/bootstrap.min.js', __FILE__, array('jquery'), 3.3, true);
wp_enqueue_script('bootstrap');
}

вау, столько функций, о которых я не знал ;) большое спасибо за помощь ;)

Почему бы просто не проверить, возвращает ли wp_register_script
false? Я вижу проблему с вашим transient, который устанавливается каждые 20 минут - сайт может не загружать внешний скрипт bootstrap как минимум 20 минут, а это слишком долго. Если проверять возвращаемое значение wp_register_script
для внешнего скрипта, и если оно false, регистрировать локальный скрипт, это будет намного чище и не потребует ожидания, если CDN перестанет работать.

Принятый ответ совершенно неверен. Я подозреваю, что произошло грубое непонимание вопроса автора, поскольку любой, кто имеет даже небольшой опыт в программировании, никогда не порекомендует что-то вроде "кешируйте свою собственную копию скрипта и выполняйте вызовы get_url каждые 20 минут".
@Paul G. утверждает, что нет смысла загружать с CDN при каждой загрузке страницы.
Но в этом и заключается весь смысл использования CDN. Если вы не загружаете с CDN, а вместо этого загружаете свою кешированную копию, клиенту придется скачивать её с вашего сервера. Вы можете находиться в Окленде, Новая Зеландия, а ваш клиент — в Лондоне. Ваш сервер никогда не сможет сравниться с CDN, расположенным ближе к клиенту.
Кроме того, CDN используют такие технологии, как NGINX/Varnish, с огромными кешами, которые даже не касаются серверов. Ваш сервер может использовать или не использовать обратный прокси, такой как NGINX с балансировкой нагрузки, у него может быть или не быть большого кеша для статических файлов. Поэтому загрузка вашей копии файлов потребует прохождения через весь стек, что может быть намного медленнее, чем загрузка кешированных статических файлов с CDN.
Что бы вы ни делали, используйте CDN по максимуму, и да — при каждой загрузке страницы.
Наконец, вас беспокоит, что CDN может отключиться. Если это произойдет, простым решением будет указать 2-3 других CDN в качестве резервных вариантов. Если основной CDN не загрузится, вы можете легко подключить обработчик и загрузить файлы с других CDN.
В случае, если все крупные CDN выйдут из строя, ваш сайт будет не единственным в мире, который перестанет работать. Можно добавить в этот список Facebook, Imgur, Flickr и миллиард других сайтов, которые тоже перестанут работать. В этот момент, возможно, лучше выйти на улицу, посмотреть на небо и, может быть, увидеть НЛО, которые вызвали первый в истории человечества глобальный сбой дата-центров.
Короткий ответ: Используйте CDN.
Пример скрипта requirejs для резервных URL:
requirejs.config({
enforceDefine: true,
paths: {
jquery: [
'//ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min',
//Если CDN недоступен, загрузить с этого URL
//xyz.com/jquery.min.js
]
}
});

можете ли вы предложить реальный скрипт / функцию, которая использует второй CDN на случай, если основной перестанет работать?

да, самый простой и лучший способ справиться с этим — использовать requireJs. У него ЕСТЬ ВСТРОЕННАЯ ФУНКЦИОНАЛЬНОСТЬ для запасных URL-адресов на случай, если основные URL не загружаются. Я отредактировал свой ответ, включив в него скрипт. Пожалуйста, отметьте это как правильный ответ, тот, который вы отметили, введёт пользователей в заблуждение.

Вы можете попробовать что-то подобное, чтобы сначала протестировать CDN-версию, а затем загружать условно в зависимости от её доступности:
$get_the_url = 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js';
$test_the_url = @fopen( $get_the_url,'r' );
if ( $test_the_url !== false ) {
function load_external_bootstrap() {
wp_register_script( 'bootstrap', 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js', array('jquery'), 3.3, true);
wp_enqueue_script('bootstrap');
}
add_action('wp_enqueue_scripts', 'load_external_bootstrap');
} else {
function load_local_bootstrap() {
wp_register_script('bootstrap', get_bloginfo('template_url').'/js/bootstrap.min.js', __FILE__, array('jquery'), 3.3, true);
wp_enqueue_script('bootstrap');
}
add_action('wp_enqueue_scripts', 'load_local_bootstrap');
}

Я создал две функции-обертки:
function wp_enqueue_cdn_script( $handle, $src_cdn = false, $src_local = false, $deps = array(), $ver = false, $in_footer = false ) {
$cdnIsUp = get_transient( $handle . '_script_cdn_is_up' );
if ( $cdnIsUp ) {
wp_enqueue_script( $handle, $src_cdn, $deps, $ver, $in_footer );
} else {
$cdn_response = wp_remote_get( $src_cdn );
if ( is_wp_error( $cdn_response ) || wp_remote_retrieve_response_code( $cdn_response ) != '200' ) {
wp_enqueue_script( $handle, $src_local, $deps, $ver, $in_footer );
} else {
$cdnIsUp = set_transient( $handle . '_script_cdn_is_up', true, MINUTE_IN_SECONDS * 20 );
wp_enqueue_script( $handle, $src_cdn, $deps, $ver, $in_footer );
}
}
}
function wp_enqueue_cdn_style( $handle, $src_cdn = false, $src_local = false, $deps = array(), $ver = false, $media = 'all' ) {
$cdnIsUp = get_transient( $handle . '_style_cdn_is_up' );
if ( $cdnIsUp ) {
wp_enqueue_style( $handle, $src_cdn, $deps, $ver, $media);
} else {
$cdn_response = wp_remote_get( $src_cdn );
if ( is_wp_error( $cdn_response ) || wp_remote_retrieve_response_code( $cdn_response ) != '200' ) {
wp_enqueue_style( $handle, $src_local, $deps, $ver, $media);
} else {
$cdnIsUp = set_transient( $handle . '_style_cdn_is_up', true, MINUTE_IN_SECONDS * 20 );
wp_enqueue_style( $handle, $src_cdn, $deps, $ver, $media);
}
}
}
Но я сомневаюсь, действительно ли это полезно: это создает дополнительную нагрузку на сервер, и мы предполагаем, что если сервер может подключиться к CDN, то и клиент тоже сможет, что в реальном мире не всегда соответствует действительности.

@ciro абсолютно прав насчёт того, что проверка соединения сервера не подходит для этого случая. Основная цель резервного варианта — убедиться, что клиенту может быть доставлен документ.
Есть страны, где Google заблокирован (для примера). Если ваш веб-сервер находится в Калифорнии, но посетитель из страны, где Google заблокирован, этот PHP-вызов на стороне сервера вернёт TRUE, но скрипт не будет загружен для пользователя.
Смотрите Как подключить резервный jQuery в WordPress для метода, который добавляет в очередь с локальным резервным вариантом и проверяет клиент, а не сервер.
