У меня есть различные javascripts, которые являются необходимыми плагинами в одном из моих доменов WordPress, и я знаю, где в php-файле он вызван.
Я принимаю все меры, которые я могу предпринять, чтобы ускорить время загрузки страницы , и каждый тестер скорости в Интернете говорит, что, по возможности, откладывать javascripts.
Я прочитал о defer = 'defer' и асинхронных функциях в javascript, и я думаю, что один из них выполнит то, что я пытаюсь выполнить. Но я не понимаю, как это сделать в php-файле.
Например, здесь приведен фрагмент из одного php-файла конкретного плагина, в котором вызывается файл javascript:
function add_dcsnt_scripts() { wp_enqueue_script( 'jquery' ); wp_enqueue_script( 'dcsnt', dc_jqsocialtabs::get_plugin_directory() . '/js/jquery.social.media.tabs.1.7.1.min.js' ); }
Я читал, что лучше всего сделать что-то подобное для более быстрого времени загрузки страницы:
<script defer async src="..."></script>
Но я не знаю, как это сделать в php-файле. Я хочу сделать это со всеми моими файлами javascript.
Как я могу выполнить отсрочку или асинхронность этого фрагмента javascript до того, как он загружается последним и ускоряет загрузку страниц ? Каким будет идеальный способ увеличить время загрузки страниц во всех браузерах? Спасибо за любое руководство, которое может предложить любой!
Это сообщение в блоге связано с двумя интересными плагинами:
Асинхронный Javascript
Улучшение производительности загрузки страницы путем асинхронной загрузки javascript с помощью head.js
WP Отложенные Javascripts
Отложите загрузку всех javascripts, добавленных с помощью wp_enqueue_scripts, используя LABJS (асинхронную библиотеку javascript).
Не проверял их, но проверял код, и они довольно причудливые вещи с процессом запуска скриптов WordPress.
Но тогда WPSE приходит на помощь :
// Adapted from https://gist.github.com/toscho/1584783 add_filter( 'clean_url', function( $url ) { if ( FALSE === strpos( $url, '.js' ) ) { // not our file return $url; } // Must be a ', not "! return "$url' defer='defer"; }, 11, 1 );
Или более универсальный способ:
function add_async_forscript($url) { if (strpos($url, '#asyncload')===false) return $url; else if (is_admin()) return str_replace('#asyncload', '', $url); else return str_replace('#asyncload', '', $url)."' async='async"; } add_filter('clean_url', 'add_async_forscript', 11, 1);
поэтому вы можете добавить async к любому скрипту без изменений кода, просто добавьте #asyncload в url скрипта как:
wp_enqueue_script('dcsnt', '/js/jquery.social.media.tabs.1.7.1.min.js#asyncload' )
Другое решение, использующее другой фильтр, который может использоваться для таргетинга на конкретный дескриптор скрипта:
function frontend_scripts() { wp_enqueue_script( 'my-unique-script-handle', 'path/to/my/script.js' ); } add_action( 'wp_enqueue_scripts', 'frontend_script' ); function make_script_async( $tag, $handle, $src ) { if ( 'my-unique-script-handle' != $handle ) { return $tag; } return str_replace( '<script', '<script async', $tag ); } add_filter( 'script_loader_tag', 'make_script_async', 10, 3 );
Попытка сделать вещи несколько модульными и всеохватывающими, следующий подход динамически выбирает, как встраивать тег с атрибутами async или defer, просто добавляя небольшой идентификатор в имя $ handle:
/** * Add async or defer attributes to script enqueues * @author Mike Kormendy * @param String $tag The original enqueued <script src="...> tag * @param String $handle The registered unique name of the script * @return String $tag The modified <script async|defer src="...> tag */ // only on the front-end if(!is_admin()) { function add_asyncdefer_attribute($tag, $handle) { // if the unique handle/name of the registered script has 'async' in it if (strpos($handle, 'async') !== false) { // return the tag with the async attribute return str_replace( '<script ', '<script async ', $tag ); } // if the unique handle/name of the registered script has 'defer' in it else if (strpos($handle, 'defer') !== false) { // return the tag with the defer attribute return str_replace( '<script ', '<script defer ', $tag ); } // otherwise skip else { return $tag; } } add_filter('script_loader_tag', 'add_asyncdefer_attribute', 10, 2); }
Пример использования:
function enqueue_my_scripts() { // script to load asynchronously wp_register_script('firstscript-async', '//www.domain.com/somescript.js', '', 2, false); wp_enqueue_script('firstscript-async'); // script to be deferred wp_register_script('secondscript-defer', '//www.domain.com/otherscript.js', '', 2, false); wp_enqueue_script('secondscript-defer'); // standard script embed wp_register_script('thirdscript', '//www.domain.com/anotherscript.js', '', 2, false); wp_enqueue_script('thirdscript'); } add_action('wp_enqueue_scripts', 'enqueue_my_scripts', 9999);
Выходы:
<script async type='text/javascript' src='//www.domain.com/somescript.js'></script> <script defer type='text/javascript' src='//www.domain.com/otherscript.js'></script> <script type='text/javascript' src='//www.domain.com/anothercript.js'></script>
Спасибо @MattKeys @crissoca за то, что вдохновили мой ответ здесь.
Упрощенный метод. Добавьте в свой файл functions.php, чтобы сделать JavaScript асинхронным в WordPress
// Make JavaScript Asynchronous in WordPress add_filter( 'script_loader_tag', function ( $tag, $handle ) { if( is_admin() ) { return $tag; } return str_replace( ' src', ' async src', $tag ); }, 10, 2 );
Чтобы получить контроль над тем, какие файлы js отложить и избежать конфликтов, вы можете добавить переменную к URL-адресу в функции wp_register_script, как показано ниже.
wp_register_script( 'menu', get_template_directory_uri() . '/js/script.js?defer', array('jquery'), '1.0', true );
Затем измените строку:
if ( FALSE === strpos( $url, '.js' ))
Для того, чтобы:
if ( FALSE === strpos( $url, '.js?defer' ))
Новый фильтр выглядит следующим образом.
add_filter( 'clean_url', function( $url ) { if ( FALSE === strpos( $url, '.js?defer' ) ) { // not our file return $url; } // Must be a ', not "! return "$url' defer='defer"; }, 11, 1 );
Включите async
атрибут в сценарии, чтобы они загружались только после загрузки всей страницы
<script type="text/javascript"> function ngfbJavascript( d, s, id, url ) { var js, ngfb_js = d.getElementsByTagName( s )[0]; if ( d.getElementById( id ) ) return; js = d.createElement( s ); js.id = id; js.async = true; js.src = url; ngfb_js.parentNode.insertBefore( js, ngfb_js ); }; </script>
Источник: здесь
Что-то добавить clean_url
фильтра clean_url
, убедитесь, что оно используется только на конце шрифта, возможно, используя if( ! is_admin() ){}
популярные плагины, такие как ACF, могут дать вам головную боль.
Обновить
Вот моя модифицированная версия решения:
if( ! is_admin() ){ add_filter( 'clean_url', 'so_18944027_front_end_defer', 11, 1 ); function so_18944027_front_end_defer( $url ) { if ( FALSE === strpos( $url, '.js' ) ) { // not our file return $url; } // Must be a ', not "! return "$url' defer='defer"; } }
Очень маленький код модификации Mike Kormendy , который позволяет вам сразу добавить 2 атрибута:
// Async load function add_asyncdefer_attribute($tag, $handle) { $param = ''; if ( strpos($handle, 'async') !== false ) $param = 'async '; if ( strpos($handle, 'defer') !== false ) $param .= 'defer '; if ( $param ) return str_replace('<script ', '<script ' . $param, $tag); else return $tag; }
Результат:
<script async defer type='text/javascript' src='#URL'></script>
Я считаю, что плохая практика – отложить / асинхронный WordPress jQuery. Лучшим решением было бы исключить jQuery из фильтра:
if (!is_admin()) { add_filter( 'script_loader_tag', function ( $tag, $handle ) { if ( strpos( $tag, "jquery.js" ) || strpos( $tag, "jquery-migrate.min.js") ) { return $tag; } return str_replace( ' src', ' async src', $tag ); }, 10, 2 ); }
Вы можете использовать defer
вместо async