Сегодня узнаем как грамотно оформлять header.php в Битрикс, как правильно подключать .css и .js в header.php, как правильно подключать jQuery в Битрикс и как включить сжатие .css и .js файлов в Битрикс.
Это очень острая и актуальная проблема на сегодняшний день. Самые частые обращения по модулям связаны с ошибками в скриптах, когда неправильно подключена jQuery в header.php, и очень часто подключено несколько jQuery, но должна быть подключена на всех страницах сайта только одна библиотека jQuery и самой первой среди всех скриптов шаблона сайта.
На одном сайте был рекорд, я насчитал 7 подключенных библиотек jQuery, просто человек замучился искать ошибки и деваться уже некуда было, когда проблема была найдена и исправлена, все стало работать на сайте правильно.
Правильный header.php в Битрикс
Итак, как грамотно должен быть оформлен файл header.php шаблона сайта в Битрикс:
- Перед <!DOCTYPE html> не должно быть никаких пробелов и переносов
- Кодировка страницы задается перед <title>
- После заголовка <title> перечисляются все мета-теги <meta>
- После мета-тегов подключаются .css стили сайта <link>
- И только после подключения .css стилей подключаются все .js скрипты <script>
- Комментарии к IE по возможности лучше опустить в самый конец перед закрывающим тегом </head>
Пример header.php для HTML 5 DOCTYPE
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
/**
* @var CUser $USER
* @var CMain $APPLICATION
* @var $full_width - переменная в которой будет true если выполнится условие из $arFullWidthPages
*/
?><!DOCTYPE html>
<html lang="<?=LANGUAGE_ID?>">
<head>
<meta charset="<?=SITE_CHARSET?>">
<title><?$APPLICATION->ShowTitle()?></title>
<?
//Тут мета-теги
$APPLICATION->ShowMeta("robots", false, false);
$APPLICATION->ShowMeta("keywords", false, false);
$APPLICATION->ShowMeta("description", false, false);
?>
<meta name="yandex-verification" content="xxxxxxxxxxxxxxxx">
<meta name="google-site-verification" content="xxxxxxxxxxxxxxxx">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<?
//Тут канонический url
$APPLICATION->ShowLink("canonical", null, false);
//Тут стили шаблона сайта
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH .'/css/uikit.gradient.min.css');
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH .'/css/components/form-password.gradient.min.css');
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH .'/css/components/sticky.gradient.min.css');
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH .'/css/components/placeholder.gradient.min.css');
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH .'/css/jquery.responsive-tabs.css');
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH .'/css/nanoscroller.css');
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH .'/css/scrollup/image.css');
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH .'/css/pace.min.css');
//Тут выводим стили
$APPLICATION->ShowCSS(true, false);
?>
<!--[if lt IE 9]>
<script type="text/javascript" src="<?=CUtil::GetAdditionalFileURL(SITE_TEMPLATE_PATH.'/js/ie8-polyfill.js');?>"></script>
<![endif]-->
<script type="text/javascript" src="<?=CUtil::GetAdditionalFileURL(SITE_TEMPLATE_PATH.'/js/jquery-1.11.2_min.js');?>"></script>
<?
//Это встроенная в ядро Битрикс jQuery, если подключать ее, то строку подключения jQuery 1.11.2 выше надо удалить.
//CJSCore::Init(array('jquery'));
//Тут скрипты
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/core.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/grid.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/modal.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/dropdown.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/scrollspy.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/utility.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/button.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/switcher.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/nav.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/components/sticky.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/components/form-password.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/pace.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/jquery.nanoscroller.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/jquery.responsiveTabs.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/switchery.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/readmore.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/jquery.scrollUp.min.js');
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/fn.js');
//Тут выводим скрипты
$APPLICATION->ShowHeadStrings();
$APPLICATION->ShowHeadScripts();
?>
</head>
CUtil::GetAdditionalFileURL() - генерирует url к файлу с указанием метки версии файла, т.е. он будет кешироваться в браузере посетителя.
SITE_TEMPLATE_PATH - это константа указывающая URL от корня сайта до папки текущего шаблона включая имя папки, если измените папку шаблона, то в header.php ничего исправлять уже не придется, он изменится в этой константе, например: /bitrix/templates/папка шаблона сайта/
Разберем представленный выше код header.php детально, чтобы понимать, что тут для чего подключается.
Хочу обратить внимание на передаваемые параметры true и false в методах, например ShowMeta() и ShowCSS(), от них зависит стандарт вывода тегов, для HTML 4, HTML 5 в виде <link>, иначе по стандарту xHTML в виде <link />, в данном примере для HTML 5, подробнее читайте в API-документации Битрикс.
Тут мы выводим мета-теги "описание" и "ключевые слова" для поисковых систем.
<?
$APPLICATION->ShowMeta("robots", false, false);
$APPLICATION->ShowMeta("keywords", false, false);
$APPLICATION->ShowMeta("description", false, false);
?>
Методом SetAdditionalCSS() подключаем стили шаблона, так каждый стиль.
$APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH .'/css/uikit.gradient.min.css');
Метод ShowCSS() выводит все стили шаблона и стили, которые могут подключаться в компонентах Битрикс, т.е. вообще все подключенные стили, включая стили ядра Битрикс.
<?
$APPLICATION->ShowCSS(true, false);
?>
Перед подключением вообще всех скриптов сайта и только для браузера Internet Explorer младше IE 9 я подключаю специальные полифилы функций/методов, которые в нем отсутствуют и вызывают ошибки javascript, возможная самая частая ошибка типа Object doesn't support property or method 'forEach'...
Т.е. если какого-то метода нет в IE 8, но он используется в новой jQuery или каком-то плагине, то может повезет и он найдется в этом скрипте, но Вы можете его не подключать, только если нужен.
<!--[if lt IE 9]>
<script type="text/javascript" src="<?=CUtil::GetAdditionalFileURL(SITE_TEMPLATE_PATH.'/js/ie8-polyfill.js');?>"></script>
<![endif]-->
А вот и подошли мы к самому интересному, на этом этапе самая частая ошибка подключения jQuery, которая должна выводиться самой первой среди всех остальных подключенных в компонентах или в шаблоне сайта jQuery-плагинах, т.е. ошибок с подключенными где-то в компоненте или шаблоне jQuery-плагинами быть не должно!
Все плагины и скрипты будут подключаться как положено, после jQuery, а не как у многих, в обратном порядке, это базовое правило подключения плагинов jQuery, знать его нужно всем!
<script type="text/javascript" src="<?=CUtil::GetAdditionalFileURL(SITE_TEMPLATE_PATH.'/js/jquery-1.11.2_min.js');?>"></script>
Методом AddHeadScript() подключаем скрипты шаблона и только после подключения стилей, стили всегда подключайте выше скриптов.
$APPLICATION->AddHeadScript(SITE_TEMPLATE_PATH .'/js/uikit/core.min.js');
Ниже два заключительных метода "выводят":
- ShowHeadStrings() выводит все скрипты ядра Битрикс, включая встроенную jQuery, если вызывается методом CJSCore::Init(array('jquery'));
- ShowHeadScripts() выводит скрипты шаблона добавленные с помощью AddHeadScript(), а также специальные стили, JavaScript, либо произвольный html-код, который задается в компонентах с помощью CMain::AddHeadString() и все на свете пользовательское.
Обратите внимание на порядок, именно в таком порядке!
$APPLICATION->ShowHeadStrings();
$APPLICATION->ShowHeadScripts();
Почему строго в таком порядке?
Потому что в методе ShowHeadStrings() может выводиться jQuery ядра Битрикс, вызываемая таким образом:
CJSCore::Init(array('jquery'));
Я ее специально закомментировал, чтобы Вы это знали, и знали где подключать. Вызываться он может в любом компоненте, в шаблоне, на любой странице сайта, а выводится она именно в этом самом первом методе, если поменять их местами, она окажется в самом низу, вот и ошибка разработки, можно это смело добавлять в чек-лист по разработке сайта.
Но если Вы выводите встроенную jQuery, значит подключенную ранее вручную jQuery надо удалить со страницы, не забывайте, она должна быть одна на всем сайте!
Итак, все это подключенное в исходном коде выглядит так:
Это конечно все круто! Но, как мы видим, к серверу очень много запросов - 93 шт., много подключено всяких файликов, а это заметно сказывается на скорости загрузки страницы, на время ожидания клиентом, мне-то как разработчику очень удобно, наглядно все видно в коде, но посетители мои от этого заметно страдают...
Оказывается, в Битрикс есть отличные опции в настройках главного модуля, позволяющие:
- Объединять CSS файлы
- Объединять JS файлы
- Подключать минифицированные версии CSS и JS файлов
- Создавать сжатую копию объединенных CSS и JS файлов - нужно отключить
Включается сжатие и объединение .css и .js здесь:
Администрирование -> Настройки -> Настройки модулей -> Главный модуль
Поставьте галочки и сохраните настройки модуля зеленой кнопкой Сохранить.
При включении этих опции в идеальном случае на странице подключается 3 css и 3 js файла, подробнее читайте в курсе про Сжатие css и js файлов.
Создавать сжатую копию объединенных CSS и JS файлов - это нужно отключить!
Потому что при включенной опции Битрикс сжимает вообще все подключенные на сайте скрипты и стили со всех страниц сайта, это и вес им прибавляет, и велика вероятность появления JS-ошибок на странице.
Лично я столкнулся с такой проблемой, JS-ошибка запросто будет в модуле, где у jQuery-плагина есть js-lang, эти лэнги хранятся в соответствующих php-файлах, вот если на странице сайта подключается какое-то расширение, то Битрикс его также сжимает, скрипт этого расширения будет на всех страницах сайта, а вот лэнги расширения подключаются только на той странице, где вызывается расширение, если jQuery-плагин не видит свой js-lang, то запросто может быть на странице js-ошибка.
Например, я свой jQuery-плагин подключил как расширение на странице Каталог, тут же и лэнги моего плагина подключаются, вот если включить сжатую копию всех JS-файлов, мой плагин будет на всех страницах сайта в хедере, а лэнг только на странице Каталог, соответственно, когда я открываю например главную страницу сайта или любую другую отличную от Каталога, то в консоли появляется JS-ошибка, т.к. лэнги моего плагина подключаются только на странице Каталог.
В общем, очень опасная опция, не включайте ее вообще.
Все, сжатие включено и должно работать.
Для точного результата работы сжатия необходимо разлогиниться, далее открывайте главную страницу сайта, обновите ее, откройте исходный код и увидите такую картину
Наглядно видим, насколько уменьшилось количество файлов, все скрипты шаблона сжаты в один файл, стили также в один файл.
Количество запросов уменьшилось в разы, время полной загрузки страницы сократилось с 3.8сек. до 1.8сек., запросы к серверу сократились с 93 до 43.
Заключение
Данный способ конечно не является идеальным, но он послужит хорошим образцом, как все подключать и в каком порядке, и как не совершать грубейших ошибок при разработке сайта.
Обязательно изучите все моменты подключения jQuery, скриптов и стилей, их порядок и включайте сжатие на сайте, это существенно ускорит время загрузки страницы и время ее отклика на действия посетителя, облегчит ее и нагрузку на сервер, сайт даже меньше трафика станет потреблять, т.к. каждый файлик на вашем сайте - это трафик!
Также, советую избавляться от всех малонужных и устаревших jQuery-плагинов, ко многим можно найти замену меньшую в разы и даже лучше по функционалу.
Это была моя первая статья из курса "Ускорение сайта", продолжение следует...