Отложенный скрипт wp-i18n вызывает ошибку в консоли ‘wp не определен’ – Gravityforms

Вопрос или проблема

Я откладываю скрипты JS, чтобы оптимизировать время загрузки страницы и SEO. Мой код для откладывания скриптов выглядит примерно так:

add_filter(
    'script_loader_tag', // Фильтрует HTML-тег скрипта добавленного в очередь.
    function ( $tag, $handle ) {
        return str_replace( ' src', ' defer="defer" src', $tag );
    }
);

Это работает нормально для большинства скриптов. Однако, когда он откладывает скрипты, такие как wp-i18n, это вызывает ошибку из-за кода -js-after, который он пытается выполнить перед выполнением откладываемого скрипта.

<script type="text/javascript" defer="defer" src="http://192.168.1.71/wp-includes/js/dist/i18n.min.js?ver=db9a9a37da262883343e941c3731bc67" id='wp-i18n-js'></script>
<script type="text/javascript" id='wp-i18n-js-after'>
wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } );
</script>

Проблема в том, что скрипт откладывается в отличие от его скрипта -js-after. Мне нужно решение, которое делает одно из следующего.

  • Пропускает откладывание скриптов, которые имеют -js-after
  • Откладывает js-after вместе со скриптом.

Реализация первого варианта с использованием

$data = $wp_scripts->get_data( 'wp-i18n', 'data' );

не работает, потому что $data не содержит информации о том, имеет ли скрипт -js-after. Поиск “обнаружение ‘WordPress -js-after'” не дает никаких полезных результатов.

Необходимо исключить добавление defer для файлов, которые имеют -js-after. В моем случае ошибка была вызвана файлами hooks.min.js и i18n.min.js.

Эта функция отлично сработала в моем случае:

function defer_parsing_of_js( $url ) {

    if ( is_user_logged_in() ) return $url; //не ломать WP Admin
    if ( FALSE === strpos( $url, '.js' ) ) return $url;
    if ( strpos( $url, "jquery.min.js" ) || strpos( $url, "jquery-migrate.min.js" ) || strpos( $url, "hooks.min.js" ) || strpos( $url, "i18n.min.js" )) {
        return $url;
    }
    
    return str_replace( ' src', ' defer src', $url );
}                                        
add_filter( 'script_loader_tag', 'defer_parsing_of_js', 10 ); 

Ответ или решение

В качестве ИТ-эксперта, рассмотрим проблему, связанную с добавлением атрибута defer к скрипту wp-i18n, которая приводит к ошибке консоли с сообщением «wp is not defined» в forms Gravity. Рассмотрим, как можно решить эту проблему, избегая разбросанных шаблонов и клише.

Проблема

При оптимизации времени загрузки страницы и SEO, вы используете фильтр script_loader_tag для добавления атрибута defer к загружаемым скриптам. Однако, это приводит к проблеме, когда скрипты с суффиксом -js-after пытаются выполниться до того, как основной скрипт был загружен и выполнен. В результате возникает ошибка, указывающая на то, что объект wp не определен.

add_filter(
    'script_loader_tag',
    function ( $tag, $handle ) {
        return str_replace( ' src', ' defer="defer" src', $tag );
    }
);

Это решение неплохо работает, однако приводит к ошибкам, когда попытки доступа к объекту wp происходят, прежде чем скрипт wp-i18n завершит загрузку.

Решение

Для устранения описанной проблемы предлагаю два подхода.

1. Исключение деферы для скриптов с суффиксом -js-after

Первый предложенный вариант — пропустить добавление атрибута defer для скриптов, имеющих суффикс -js-after. Можно проверить имя загружаемого скрипта и, в случае совпадения, вернуть оригинальный тег без изменений. Это достигается следующим образом:

function defer_parsing_of_js( $url ) {
    if ( is_user_logged_in() ) return $url; // Не нарушаем работу в админке WP
    if ( FALSE === strpos( $url, '.js' ) ) return $url;

    // Проверяем, является ли скрипт -js-after
    if ( strpos( $url, '-js-after' ) !== false ) {
        return $url; // Игнорируем скрипт с -js-after
    }

    return str_replace( ' src', ' defer src', $url );
}

add_filter( 'script_loader_tag', 'defer_parsing_of_js', 10 );

Этот код проверяет, есть ли в имени файла суффикс -js-after, и если да, то не добавляет атрибут defer.

2. Деферирование как основного, так и вспомогательного скрипта

Второй вариант, который можно рассмотреть, заключается в том, чтобы сделать так, чтобы скрипты с суффиксом -js-after тоже обрабатывались с атрибутом defer. Для этого нужно добавить дополнительные действия для их правильной обработки. Рассмотрим как это можно сделать:

add_filter( 'script_loader_tag', 'defer_parsing_of_js', 10 );

function defer_parsing_of_js( $tag, $handle ) {
    if ( is_user_logged_in() ) return $tag; // Не влезаем в админку
    if ( strpos( $handle, '-js-after' ) !== false || strpos( $url, 'hooks.min.js' ) !== false || strpos( $url, 'i18n.min.js' ) !== false ) {
        return $tag; // Игнорируем скрипты, требующие предшествующей загрузки
    }

    return str_replace( ' src', ' defer src', $tag );
}

Выводы

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

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

Оцените материал
Добавить комментарий

Капча загружается...