CODYSHOP
темы и плагины для WordpressНа этот раз, мы обсудим, как объединить файлы JavaScript в один файл на WordPress. Этот процесс – часть оптимизации (уменьшения количества) http-запросов, для увеличения скорости сайта.
Объединение вручную
Казалось бы, самый очевидный способ объединить js файлы – просмотреть исходный код веб-страницы, найти все скрипты сайта, затем скопировать их содержимое и последовательно вставить их в новый js файл. Однако, этот метод не рекомендуется, так как имеет много недостатков:
- Отсутствие гибкости. Если нужно добавить или удалить скрипт, то нужно заново делать это вручную.
- Невозможно гарантировать совместимость между файлами. Это связано с определенной последовательностью подключения скриптов.
- Если будут использованы дополнительные сторонние плагины, есть вероятность двойной загрузки скриптов, что увеличивает вес загружаемой страницы.
Учитывая все минусы данного подхода, попробуем решить его более простым способом – с использованием php.
Объединяем скрипты автоматически
Итак, определив наиболее рациональный способ решения проблемы, давайте элегантно объединим скрипты в один файл, разместив данный сниппет в function.php.
add_action( 'wp_enqueue_scripts', 'merge_all_scripts', 9999 );
function merge_all_scripts() {
global $wp_scripts;
/*
#1. Reorder the handles based on its dependency,
The result will be saved in the to_do property ($wp_scripts->to_do)
*/
$wp_scripts->all_deps($wp_scripts->queue);
// Располагаем новый js файл по пути: \wp-content\theme\merged-script.js
$merged_file_location = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'merged-script.js';
$merged_script = '';
// Запускаем цикл, который последовательно сохраняет их в переменную $merged_script
foreach( $wp_scripts->to_do as $handle) {
/*
Очищаем скрипт от версии, например, вместо wp-content/themes/merged-script.js?v=1.2.4
будет wp-content/themes/merged-script.js
*/
$src = strtok($wp_scripts->registered[$handle]->src, '?');
/**
#2. Объединяем js файлы.
*/
// Учитываем протокол http / https
if (strpos($src, 'http') !== false) {
// Получаем урл сайта
$site_url = site_url();
if (strpos($src, $site_url) !== false)
$js_file_path = str_replace($site_url, '', $src);
else
$js_file_path = $src;
$js_file_path = ltrim($js_file_path, '/');
} else {
$js_file_path = ltrim($src, '/');
}
// Проверим, существует ли файл после слияния
if (file_exists($js_file_path)) {
// #3. Проверяем wp_localize_script
$localize = '';
if (@key_exists('data', $wp_scripts->registered[$handle]->extra)) {
$localize = $obj->extra['data'] . ';';
}
$merged_script .= $localize . file_get_contents($js_file_path) . ';';
}
}
// записываем скрипты в файл
file_put_contents ( $merged_file_location , $merged_script);
// #4. Подключаем в теме созданный скрипт
wp_enqueue_script('merged-script', get_stylesheet_directory_uri() . '/merged-script.js');
// 5. Отключаем все файлы, которые были слиты
foreach( $wp_scripts->to_do as $handle ) {
wp_deregister_script($handle);
}
}Убедитесь, что процесс объединения прошел успешно. Проверьте, что объединение скриптов прошло без ошибок. Для этого откройте инструменты разработчика в браузере (нажмите F12 для Google Chrome) и выберите вкладку “Консоль”. Если ошибок нет, то консоль не выдаст никаких предупреждений.

Следует отметить, что некоторые файлы не объединяются, например wp-embed.min.js и akismet.js. Это связано с тем, что указанные скрипты загружаются позже, чем наш фрагмент кода.
Если ошибки в консоли браузера присутствуют, проверьте исходные скрипты на наличие строк комментариев. При автоматическом слиянии, мог быть “закомментирован” нужный код.
Добрый! Как исключить из такого способа конкатенации инлайновые скрипты?
Когда столкнулся с тем, что инлайновые скрипты данное решение просто выбрасывает, сделал следующим образом:
// #4.5. Получаем встраиваемые в html скрипты foreach ( $wp_scripts->registered as $k=>$v ) { foreach ( $wp_scripts->to_do as $script ) { if ( $k == $script ) { $scr = $v->extra; if ( $scr ) { $allajaxs[] = $scr['data']; } } } } // теперь можно вернуть на место ajax скрипты $allajaxs = array_diff( $allajaxs, array('') ); foreach ( $allajaxs as $key => $value ) { $inc .= '<script type="text/javascript">'; $inc .= '/* <![CDATA[ */'; $inc .= $value; $inc .= '/* ]]> */'; $inc .= '</script> '; } print_r($inc); // #5. Отключаем все файлы, которые были слиты ...В
$wp_scripts->registeredсодержится информация обо всех подключаемых скриптах. Перед тем, как отключаем слитые файлы, ищем те которые встраивают скрипты в html и выводим их.Блин, почти сработало. Но всё равно подкосило функционал. А как можно исключить определённые скрипты из выборки?
Подскажите, пожалуйста у меня хорошо объединились скрипты в один файл. Но, произошла проблема. Не все скрипты работают и в консоли появились ошибки. Создаетс впечатление, что браузер не увидел эти скрипты, хотя файл был подключен. Я его видел через консоль разработчика. Почему может быть такая проблема. Такое впечатление, что сайт не видел скрипт, хотя он был подключер. В чем может быть проблема?