Как отложить или асинхронизировать этот фрагмент JavaScript-кода WordPress для последней загрузки, чтобы ускорить загрузку страниц?

36

У меня есть разные javascripts, которые являются необходимыми плагинами в одном из моих доменов WordPress, и я знаю, где в php файле он вызвал.

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

Я прочитал о функциях defer = 'defer' и async в 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 до последней загрузки и ускоряет время загрузки страницы? Каким будет идеальный способ увеличить время загрузки страниц во всех браузерах? Спасибо за любое руководство, которое может предложить любой!

Теги:
asynchronous

10 ответов

21
Лучший ответ

Этот сообщение в блоге содержит ссылки на два интересующих плагина:

Асинхронный Javascript
Повысить производительность загрузки страницы, асинхронно загружая javascript, используя head.js

Отложенные Javascripts WP
Отложите загрузку всех 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 );
  • 1
    Спасибо за то, что уделили мне время, brasofilo ... цените ваше время, и это в основном дало мне html-выход, который мне был нужен
  • 1
    @brasofilo 'clean_url' устарел сейчас, в пользу 'esc_url' codex.wordpress.org/Function_Reference/clean_url
Показать ещё 2 комментария
36

Или более универсальный способ:

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 в любой script без изменений кода, просто добавьте #asyncload в script url как:

wp_enqueue_script('dcsnt', '/js/jquery.social.media.tabs.1.7.1.min.js#asyncload' )
  • 2
    Спасибо пользователю ... это предполагает, что авторы плагинов правильно закодировали свои плагины, используя метод enqueue. Я все больше и больше удаляю плагины, которые не закодированы должным образом, и придерживаюсь плагинов с лучшими кодами, даже если они не такие старые и заслуживают доверия, как более популярные плагины.
  • 1
    Там небольшая, но существенная разница между async и defer : webkit.org/blog/1395/running-scripts-in-webkit Смотрите также: stackoverflow.com/questions/10808109/script-tag-async-defer
Показать ещё 4 комментария
9

Другое решение с использованием другого фильтра, который может использоваться для таргетинга на конкретный дескриптор script:

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 );
  • 0
    Префект решение для асинхронных скриптовых плагинов. Спасибо :)
  • 0
    эта работа для меня на WP 4.4.5
Показать ещё 1 комментарий
8

Попытка сохранить вещи несколько модульными и всеохватывающими, следующий подход динамически выбирает, как встраивать тег с атрибутами async или отложить, просто добавив небольшой идентификатор в имя $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 за то, что он вдохновил мой ответ.

  • 3
    Просто фантастика.
  • 0
    Лучший из тех, что я видел!
7

Упрощенный метод. Добавьте в свой файл 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 );
4

Чтобы получить контроль над тем, какие файлы 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' ))

To:

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 );
  • 0
    Спасибо, Натан. Я опробую это для справки, хотя я уже использовал одно из решений.
  • 0
    Это умная идея. Хотелось бы, чтобы был менее «хакерский» подход, но на самом деле это лучшее, что я когда-либо видел, чтобы поддерживать контроль над сценариями индивидуально.
1

Очень маленький код модификации Майк Корменди, который позволяет сразу добавить 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>
  • 2
    Пришел сюда, чтобы предложить это. +1!
  • 2
    Я поддерживаю это! ;-)
1

Что-то добавить решение фильтра 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";
  }
}
  • 1
    Это должен был быть комментарий, а не ответ. С чуть большим количеством представителей вы сможете оставлять комментарии . До тех пор, пожалуйста, не используйте ответы в качестве обходного пути.
  • 0
    Спасибо, ребята. Я просто хотел добавить дополнительную помощь к правильному ответу, так как столкнулся с этой проблемой, и, как вы сказали, мне не хватило представителя, чтобы добавить комментарий к правильному ответу, но я думаю, что это правильное дополнение, я ' Я не добавляю критику больше, чем пытаюсь расширить правильный ответ
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>

Источник: Здесь

  • 0
    Хотя этот метод является правильным и считается лучшей практикой на протяжении многих лет, следует отметить, что он больше не является. По словам Ильи Григорика, атрибут async работает намного лучше, более подробную информацию можно найти здесь: igvita.com/2014/05/20/…
0

Я считаю, что плохая практика - отложить/асинхронный 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню