Правильный способ переноса всех JS файлов в подвал сайта
Чтобы ускорить загрузку сайта и предотвратить блокировку рендеринга страницы скриптами, я пытаюсь переместить все возможные скрипты (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&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&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(); ?>
Мой вопрос касательно этих подключений (я не разработчик темы, но уверен, что это можно исправить): какой правильный способ загрузки этих файлов, чтобы не сломать тему и при этом сохранить производительность и скорость загрузки страницы?

ИМХО, я всё ещё считаю, что загрузка скриптов и стилей напрямую в 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&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&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">

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

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

Я думаю, ваш скрипт правильный, но, возможно, вам нужно исправить этот элемент
add_action('after_setup_theme', 'footer_enqueue_scripts');
Измените на
add_action( 'wp_enqueue_scripts', 'oiw_remove_head_scripts' );
Вы можете найти справочную информацию здесь, и я проверил это - работает
