Правильный способ переноса всех JS файлов в подвал сайта

17 февр. 2015 г., 05:19:04
Просмотры: 24.5K
Голосов: 2

Чтобы ускорить загрузку сайта и предотвратить блокировку рендеринга страницы скриптами, я пытаюсь переместить все возможные скрипты (JS файлы) из head в footer. После изучения вопроса и исследований я создал такой код:

function footer_enqueue_scripts() {
    remove_action('wp_head', 'wp_print_scripts');
    remove_action('wp_head', 'wp_print_head_scripts', 9);
    remove_action('wp_head', 'wp_enqueue_scripts', 1);
    add_action('wp_footer', 'wp_print_scripts', 5);
    add_action('wp_footer', 'wp_enqueue_scripts', 5);
    add_action('wp_footer', 'wp_print_head_scripts', 5);
}

add_action('after_setup_theme', 'footer_enqueue_scripts');

Но это не работает, так как некоторые скрипты все еще загружаются в head, смотрите вывод ниже:

<head>
<link rel="stylesheet" type="text/css" href="http://elclarin.dev/wp-content/cache/minify/000000/d4587/default.include.993ea9.css" media="all" />
<script type="text/javascript" src="http://elclarin.dev/wp-content/cache/minify/000000/d4587/default.include.0fe0ac.js"></script>
....
<!-- Metas -->
<meta charset="utf-8">

 <!-- JS Files -->
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/jquery.tools-1.2.7.min.js"></script>
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/prefixfree-1.0.6.min.js"></script>
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/modernizr.js"></script>
<!--[if lt IE 9]>
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/html5shiv.js"></script>
<![endif]-->
<!--[if (gte IE 6)&(lte IE 8)]>
<script type="text/javascript" src="http://elclarin.dev/wp-content/themes/elclarin_v2/js/selectivizr-1.0.2.min.js"></script>
<![endif]-->
<script type="text/javascript">
    var TEMPLATEURL = 'http://elclarin.dev/wp-content/themes/elclarin_v2';
</script>


<!-- Generated by OpenX 2.8.9 -->
<script type='text/javascript' src='http://openx.elclarinweb.com/www/delivery/spcjs.php?id=2&amp;target=_blank'></script>

<!-- Analytics Files -->
<script type="text/javascript">
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-29394358-3']);
    _gaq.push(['_trackPageview']);
    _gaq.push(['elclarin._setAccount', 'UA-36592785-1']);
    _gaq.push(['elclarin._trackPageview']);
    _gaq.push(['elclarin._setAccount', 'UA-49334701-1']);
    _gaq.push(['elclarin._trackPageview']);

    (function () {
        var ga = document.createElement('script');
        ga.type = 'text/javascript';
        ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(ga, s);
    })();

</script>
</head>
 ...
</footer>
    <script type='text/javascript' src='http://elclarin.dev/wp-includes/js/admin-bar.min.js?ver=4.1'></script>
    <script type='text/javascript' src='http://elclarin.dev/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1'></script>
    <script type='text/javascript' src='http://elclarin.dev/wp-includes/js/hoverIntent.min.js?ver=r7'></script>
...

Любые варианты решения этой проблемы? Живой сайт для тестирования доступен здесь

Обновление

После подсказки @Milo я обнаружил, что скрипты, как он и сказал, неправильно подключены в теме в файле header.php, так как я вижу следующее:

<!-- JS Files -->
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/jquery.tools-1.2.7.min.js"></script>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/prefixfree-1.0.6.min.js"></script>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/modernizr.js"></script>
<!--[if lt IE 9]>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/html5shiv.js"></script>
<![endif]-->
<!--[if (gte IE 6)&(lte IE 8)]>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/selectivizr-1.0.2.min.js"></script>
<![endif]-->
<script type="text/javascript">
    var TEMPLATEURL = '<?php echo TEMPLATEURL; ?>';
</script>
<script type="text/javascript" src="<?php echo TEMPLATEURL ?>/js/acciones.js"></script>

<!-- Generated by OpenX 2.8.9 -->
<script type='text/javascript' src='http://openx.elclarinweb.com/www/delivery/spcjs.php?id=2&amp;target=_blank'></script>

<!-- Analytics Files -->
<script type="text/javascript">
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-29394358-3']);
    _gaq.push(['_trackPageview']);
    _gaq.push(['elclarin._setAccount', 'UA-36592785-1']);
    _gaq.push(['elclarin._trackPageview']);
    _gaq.push(['elclarin._setAccount', 'UA-49334701-1']);
    _gaq.push(['elclarin._trackPageview']);

    (function () {
        var ga = document.createElement('script');
        ga.type = 'text/javascript';
        ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(ga, s);
    })();

</script>
<!-- WP Files -->
<?php wp_head(); ?>

Мой вопрос касательно этих подключений (я не разработчик темы, но уверен, что это можно исправить): какой правильный способ загрузки этих файлов, чтобы не сломать тему и при этом сохранить производительность и скорость загрузки страницы?

5
Комментарии

Вы уверены, что ваша тема правильно подключает эти скрипты? Полагаю, что скорее всего нет.

Milo Milo
17 февр. 2015 г. 05:49:05

@Milo, вы правы, все они неправильно подключены в header.php (см. мои правки), есть какие-то советы по исправлению?

ReynierPM ReynierPM
17 февр. 2015 г. 06:40:43

Правильным методом было бы зарегистрировать все JS-библиотеки в functions.php, но будет проще, если вы вырежете и вставите все JS-файлы из header.php в footer.php

Robert hue Robert hue
17 февр. 2015 г. 07:08:07

@Roberthue это будет работать, но точно не рекомендуется :-)

Pieter Goosen Pieter Goosen
17 февр. 2015 г. 07:13:04

Да, именно поэтому я и сказал. Перенос JS-файлов из header.php в footer.php будет намного проще, но это не правильное решение. :)

Robert hue Robert hue
17 февр. 2015 г. 07:30:26
Все ответы на вопрос 2
3

ИМХО, я всё ещё считаю, что загрузка скриптов и стилей напрямую в header — это плохая практика, так как их сложно удалять и загружать условно.

Лучший способ обойти это — создать [дочернюю тему], затем скопировать header.php в вашу дочернюю тему. WordPress будет загружать header из дочерней темы вместо родительской.

Теперь вы можете удалить все скрипты из header и правильно зарегистрировать и загрузить их через хук wp_enqueue_scripts в functions.php дочерней темы. Не забудьте установить параметр $in_footer в функциях wp_enqueue_script() и wp_register_script() в `true`.

РЕДАКТИРОВАНИЕ

Из вашего приложенного header.php, скрипты добавляются между строками 56 - 95. Их нужно удалить. Если вы посетите сайт, вы не увидите загруженный jquery.

Встроенная библиотека jquery уже загружается, беспокоиться не о чем. Остальные скрипты вам нужно загрузить самостоятельно. Вот пример (Помните, каждый скрипт должен иметь уникальный идентификатор, чтобы избежать конфликтов):

add_action('wp_enqueue_scripts', 'enqueue_my_scripts');

function enqueue_my_scripts() 
{
    wp_enqueue_script('jquery-tools', get_template_directory_uri() . '/js/jquery.tools.js-1.2.7.min.js', array('jquery'), false, true);
    //То же самое для остальных скриптов
}

Обратите внимание, я использовал get_template_directory_uri(), так как папка js остаётся в родительской теме. Однако вы можете переместить папку js в дочернюю тему, но тогда нужно использовать get_stylesheet_directory_uri().

ЗАМЕТКИ ОБ УСЛОВНЫХ СКРИПТАХ

Даже спустя четыре года после поднятия вопроса, нет встроенного способа загружать скрипты условно для IE, как это сделано для стилей. Вы можете посмотреть тикет и другой вопрос по этой теме здесь.

Я никогда не пробовал условную загрузку скриптов по браузеру, поэтому не могу комментировать этот раздел или утверждать, работают ли решения, упомянутые в ответах или тикете. Что я могу сказать, если решения не работают, вам нужно скопировать footer.php в дочернюю тему и переместить строки 61 -66 из header в footer.

ЗАМЕТКИ О СКРИПТАХ В СТРОКАХ 67 -69

Этот раздел передаёт php-переменную в jquery. Правильный способ сделать это — использовать wp_localize_script(). Вам нужно связаться с разработчиком для помощи, так как это связано с темой, и я не знаю, где это используется в скриптах. Посмотрите ссылку для информации и использования.

ЗАМЕТКИ О СКРИПТЕ АНАЛИТИКИ В СТРОКАХ 75 - 94

Вам нужно создать js-файл для этого раздела. Если вы не скопировали папку js из родительской темы в дочернюю, создайте новую папку js в дочерней теме. Откройте её и создайте новый js-файл, назовите его как угодно, например analytics.script.js.

Затем перенесите всё внутри тегов script в этот файл, это строки 77 - 92. Обязательно оберните этот скрипт в no conflict wrapper, как описано здесь.

Вы можете загрузить этот скрипт как обычно, как описано выше, просто не забудьте использовать get_stylesheet_directory_uri(), а не get_template_directory_uri().

РЕДАКТИРОВАНИЕ 2

Патч из ответа в разделе ЗАМЕТКИ ОБ УСЛОВНЫХ СКРИПТАХ не работает, он ещё не реализован, и, как я сказал в комментариях, вероятно, не будет включён в версию 10 даже через 100 лет :-). К сожалению, вам придётся с этим жить, сейчас просто нет способа достичь этого. Это действительно недостаток поддержки IE6 - 8. Честно говоря, если вы всё ещё поддерживаете IE6 и 7, вы сражаетесь в битве, проигранной давно. Все крупные разработчики ПО отказались от IE6 (включая WordPress), Microsoft сами отказались от IE7, поэтому разработчики ПО скоро последуют, и IE8 не доживёт до конца 2016 года, ИМХО.

Чтобы преодолеть эту проблему совместимости с jquery, возможно, лучше придерживаться того, что предлагает сама тема.

Вы можете попробовать что-то вроде этого:

add_action('wp_enqueue_scripts', 'enqueue_my_scripts', PHP_INT_MAX);

function enqueue_my_scripts() 
{

    /**
     * Убедитесь, что get_template_directory_uri(), если скрипт остаётся в родительской теме
     * Используйте get_stylesheet_directory_uri(), если скрипт в дочерней теме
    */ 
    wp_enqueue_script('jquery-min', get_template_directory_uri() . '/js/jquery-1.7.2.min.js', array(), false, true);
    wp_enqueue_script('jquery-tools', get_template_directory_uri() . '/js/jquery.tools.js-1.2.7.min.js', array('jquery-min'), false, true);
    wp_enqueue_script('prefixfree', get_template_directory_uri() . '/js/prefixfree-1.0.6.min.js', array(), false, true);
    wp_enqueue_script('modernizr', get_template_directory_uri() . '/js/modernizr.js', array(), false, true);

    /**
     * Два условных скрипта, для которых нет обходного пути, загружайте их или откажитесь от поддержки
    */ 
    wp_enqueue_script('html5shiv', get_template_directory_uri() . '/js/html5shiv.js', array(), false, true);
    wp_enqueue_script('selectivizr', get_template_directory_uri() . '/js/selectivizr-1.0.2.min.js', array(), false, true);

    wp_enqueue_script('acciones', get_template_directory_uri() . '/js/acciones.js', array(), false, true);
    wp_enqueue_script('openx', 'http://openx.elclarinweb.com/www/delivery/spcjs.php?id=2&amp;target=_blank', array(), false, true);
    wp_enqueue_script('analytics', get_stylesheet_directory_uri() . '/js/analytics.script.js', array(), false, true);

}

Как я уже говорил, есть php-переменная, передаваемая в скрипт, о которой вам стоит поговорить с автором темы. Также любые проблемы совместимости следует обсудить с авторами темы. Это правильная структура, и в теории она должна работать. По любым другим вопросам, связанным с темой и совместимостью, обращайтесь к авторам темы за поддержкой.

РЕДАКТИРОВАНИЕ 3

Вот как должен выглядеть header.php вашей дочерней темы:

<!DOCTYPE html>
<html itemscope itemtype="http://schema.org/Blog">
<head>
    <!-- Метаданные -->
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="google-site-verification" content="V022hygXU9AHEdTBX2BFnTBYeo4SsaTjC7aGdoIMPL4"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width">
    <meta name="description" content="<?php bloginfo( 'description' ); ?>">
    <?php if (is_single()) { ?>
        <meta property="og:title" content="<?php the_title(); ?>"/>
        <meta itemprop="name" content="<?php the_title(); ?>">
        <meta property="og:type" content="article"/>
        <meta property="og:url" content="<?php the_permalink(); ?>"/>
        <?php
        if (has_post_thumbnail()) {
            $src = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), array( 490, 290 ), false );
            ?>
            <meta property="og:image" content="<?php echo $src[0]; ?>"/>
            <meta itemprop="image" content="<?php echo $src[0]; ?>">
        <?php } else { ?>
            <meta property="og:image" content="<?php echo TEMPLATEURL; ?>/images/logo.png"/>
            <meta itemprop="image" content="<?php echo TEMPLATEURL; ?>/images/logo.png">
        <?php } ?>
        <meta property="og:site_name" content="<?php bloginfo( 'name' ); ?>"/>
        <meta itemprop="description" content="<?php the_excerpt(); ?>">
    <?php } ?>

    <!-- Заголовок -->
    <title>
        <?php
        if (isset($wp_query->query_vars['b'])) {
            echo str_replace( "+", " ", $wp_query->query_vars['b'] )." | ";
        }
        wp_title( '|', true, 'right' );
        bloginfo( 'name' );
        if (isset($paged) && $paged >= 2 || isset($page) && $page >= 2 || isset($page_alt) && $page_alt >= 2) {
            echo ' | '.sprintf( 'Страница %s', max( $paged, $page, $page_alt ) );
        }
        ?>
    </title>

    <!-- Стили и прочее -->
    <link rel="stylesheet" type="text/css" media="all" href="<?php bloginfo( 'stylesheet_url' ); ?>?version=4"/>
    <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>"/>
    <link rel="alternate" type="application/rss+xml" title="RSS" href="<?php echo SITEURL; ?>/feed/"/>
    <link rel="alternate" type="application/atom+xml" title="Atom" href="<?php echo SITEURL; ?>/feed/atom/"/>

    <link rel="shortcut icon" href="<?php echo TEMPLATEURL ?>/images/favicon.ico"/>
    <link rel="shortcut icon" href="<?php echo TEMPLATEURL ?>/images/favicon.png"/>
    <link rel="apple-shortcut icon" href="<?php echo TEMPLATEURL ?>/images/favicon_iphone.png"/>
    <link rel="apple-touch-icon-precomposed" href="<?php echo TEMPLATEURL ?>/images/favicon_iphone.png">
    <link rel="apple-touch-icon" href="<?php echo TEMPLATEURL ?>/images/favicon_iphone.png">

    <!-- Файлы WP -->
    <?php wp_head(); ?>
</head>
<body>
<div class="for_overlays">
    <?php
    if (is_front_page()) {
        $prepost      = $post;
        $normal_args  = Array(
            'post_type'      => 'portadadeldia',
            'post_status'    => 'publish',
            'posts_per_page' => 1
        );
        $normal_query = new WP_Query( $normal_args );
        if ($normal_query->have_posts()) {
            while ($normal_query->have_posts()) {
                $normal_query->the_post();
                ?>
                <?php
                if (has_post_thumbnail()) {
                    $large_image_url = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' );
                    ?>
                    <div id="portadadeldia" class="from_overlay">
                        <a href="<?php echo $large_image_url[0]; ?>" target="_blank">
                            <?php echo get_the_post_thumbnail(
                                $post->ID,
                                'portadadeldia_frontpage_overlay',
                                array( 'alt' => trim( get_the_title() ), 'title' => trim( get_the_title() ) )
                            ); ?>
                        </a>
                    </div>
                <?php } ?>
            <?php
            }
        }
        $post = $prepost;
        wp_reset_postdata();
    }
    ?>
    <svg>
        <filter id="firefoxblur">
            <feGaussianBlur stdDeviation="4"/>
        </filter>
    </svg>
</div>
<header>
    <div class="center_content">
        <div id="header_publicity" class="publicity">
            <span>Реклама</span>

            <div>
                <script type='text/javascript'><!--// <![CDATA[
                    /* [id18] Header Top */
                    OA_show(18);
                    // ]]> --></script>
                <noscript><a target='_blank' href='http://openx.elclarinweb.com/www/delivery/ck.php?n=1073df0'><img
                            border='0' alt=''
                            src='http://openx.elclarinweb.com/www/delivery/avw.php?zoneid=18&amp;n=1073df0'/></a>
                </noscript>
            </div>
        </div>
        <h1 id="header_logo"><a href="<?php echo SITEURL; ?>">
                <?php
                $prepost      = $post;
                $normal_args  = Array(
                    'post_status'    => 'publish',
                    'posts_per_page' => 1,
                    'post_type'      => 'logos',
                );
                $normal_query = new WP_Query( $normal_args );
                if ($normal_query->have_posts()) {
                    $normal_query->the_post();
                    $thumbnail_id     = get_post_thumbnail_id( $post->ID );
                    $thumbnail_object = get_post( $thumbnail_id );
                    $url              = $thumbnail_object->guid;
                    ?><img src="<?PHP echo $url; ?>" alt="<?php bloginfo( 'name' ); ?>"><?php
                } else {
                    ?><img src="<?PHP echo TEMPLATEURL; ?>/images/logo.png" alt="<?php bloginfo( 'name' ); ?>"><?php
                }
                $post = $prepost;
                wp_reset_postdata();
                ?>
            </a></h1>
        <?php custom_secondary_nav( "executive_menu", 'header_lateral_superior', 'Корпоративное меню' ); ?>
        <div id="header_lateral_inferior">
            <div id="header_buscador" role="search" title="Поиск">
                <div id="header_buscador_inner">
                    <form method="get" action="<?php echo SITEURL; ?>">
                        Поиск
                        <input title="Поиск" type="text" name="s"
                               value="<?php echo str_replace( "+", " ", $wp_query->query_vars['s'] ); ?>">
                    </form>
                </div>
            </div>
            <div id="header_redes">
                <a href="http://twitter.com/elclarin_aragua" target="_blank"><img
                        src="<?php echo TEMPLATEURL ?>/images/icons/tw.png"></a>
                <a href="<?php echo SITEURL; ?>/rss" target="_blank"><img
                        src="<?php echo TEMPLATEURL ?>/images/icons/rs.png"></a>
                <a href="<?php echo SITEURL; ?>"><img src="<?php echo TEMPLATEURL ?>/images/icons/ho.png"></a>
            </div>
        </div>
        <div id="header_menu">
            <?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_id' => 3 ) ); ?>
        </div>
    </div>
</header>
<div role="main" id="main" class="main">
    <div class="center_content">
17 февр. 2015 г. 07:11:27
Комментарии

Это слишком сложно для меня, @Pieter, не мог бы ты привести простой пример для одного или двух скриптов в своем ответе? Я прочитал твой ответ, но не знаю, что делать дальше

ReynierPM ReynierPM
17 февр. 2015 г. 07:25:38

Хорошо, последний вопрос: что насчет файла header.php в дочерней теме? Каким должно быть его содержимое? Сейчас вот так выглядит мой файл, и я думаю, это совершенно неправильно, так что...

ReynierPM ReynierPM
17 февр. 2015 г. 18:06:31

Смотри мое обновление. Могу я попросить об одолжении? Пожалуйста, удали все свои комментарии, так как этот ответ вызовет флаг в панели модератора из-за слишком большого количества комментариев. Спасибо :-)

Pieter Goosen Pieter Goosen
17 февр. 2015 г. 18:12:34
0

Я думаю, ваш скрипт правильный, но, возможно, вам нужно исправить этот элемент

add_action('after_setup_theme', 'footer_enqueue_scripts');

Измените на

add_action( 'wp_enqueue_scripts', 'oiw_remove_head_scripts' );

Вы можете найти справочную информацию здесь, и я проверил это - работает

25 янв. 2020 г. 04:38:23