В погоне за Pagespeed (оптимизация DLE). Начало

В погоне за Pagespeed (оптимизация DLE). Начало
Всем привет. Не так давно решил оптимизировать один из своих сайтов. Вернее самый первый мой сайт. Много лет назад были популярны "варезники", на которых была инфа по всем тематикам и т.д. и т.п. За время существования сайта (8 лет) насобиралось немного мусора, а именно: ~2 миллиона фото (включая миниатюры), замурзанная база в 300 мб и старая версия самого движка (v9.6).

На Pagespeed оценки вообще не радовали (~50 баллов), хотя как могли радовать, если я забил на сайт 2 года назад и он жил своей жизнью. И вот наконец-то дошли руки до этого сайта. И как вы уже поняли, данная статья (как и три последующих) будет о том, как качественно оптимизировать сайт, дабы добиться максимально возможных показателей по pagespeed.

Что с CSS?

Все CSS и JS пакуем через минифаер, который уже есть в DLE. Выглядит сеё дело примерно так:
<link href="/engine/classes/min/index.php?charset=windows-1251&f={THEME}/css/allsite.css,{THEME}/css/font-awesome.css,{THEME}/css/bbcodes.css&30" rel="stylesheet" />

Где, charset= кодировка сайта, f= все скрипты/стили через запятую, &30 количество дней в кеше браузера юзера.

Лично меня бесила длиннющая строка в шаблоне. В .htaccess в корне сайта после RewriteEngine On вбиваем:
RewriteRule ^all.css$ /engine/classes/min/index.php?charset=utf-8&f=/templates/тема/css/allsite.css,/templates/тема/css/font-awesome.css,/templates/тема/css/bbcodes.css&30 [QSA]

Через запятую можете прицепить все CSS на сайте. В свою очередь в main.tpl вбиваю всего один стиль:
<link href="/all.css" rel="stylesheet" />

А вот если у вас есть какие-то стили, которые используются только, например, в полной новости или на странице добавления новостей, то лучше их отделить от всей массы. Примерно так:
[aviable=addnews]
    <link href="/add.css" rel="stylesheet" />
[/aviable]
[aviable=showfull]
    <link href="/full.css" rel="stylesheet" />
[/aviable]

На этом моменте стоит вспомнить о самом идеальном подключении .css файлов! В теге head нужно размещать только один .css, в котором описаны стили только для первого экрана, а все остальные подключить после закрывающегося тега html. В итоге:
<html>
    <head>
        <link href="/first.css" rel="stylesheet" />
    </head>
</html>
<link href="/one.css" rel="stylesheet" />
<link href="/two.css" rel="stylesheet" />

С .js файлами мы проводим идентичные операции:
[aviable=showfull]
    <script async src="/engine/classes/min/index.php?charset=windows-1251&amp;f={THEME}/js/uppod_api.js,{THEME}/js/jquery.wysibb.min.js,{THEME}/js/fullstory.js&30" type="text/javascript"></script>
[/aviable]

Или же помещаем в .htaccess аналогично со стилями, предварительно поменяв {THEME} на путь к вашей теме. Кстати можно поместить нужные JS в основной массив библиотек groupsConfig.php (об этом ниже).

По поводу JS

Как я надеюсь, всем понятно, что все скрипты мы должны передвинуть в самый низ кода до закрывающего тега </body>. Но что же делать с теми скриптами, которые требует сам DLE и выводит через тег {headers}? Начиная с версии 10.6 был введен новый тег {jsfiles}, который выводит в шаблон 3 файла (библиотеки jquery, jquery-ui и dle_js). До версии 10.6 делалось так:

Заходим в /index.php или /engine/modules/main.php (в зависимости от версии) и ищем:
$tpl->set ( '{headers}', $metatags."\n".$js_array );

И разделяем на два тега шаблона:
$tpl->set ( '{headers}', $metatags );
$tpl->set ( '{jsfiles}', $js_array );

То-есть в main.tpl в </head> мы оставляем {headers}, а перед </body> добавляем
{AJAX}
{jsfiles}

Как вы заметили, {AJAX} находится до {jsfiles}. Тут стоит сделать ремарку. Я привык подгружать jquery с CDN, например так:
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script defer src="//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
{AJAX}
{jsfiles}

Сами версии jquery конечно же на ваше усмотрение. С появления 3-й ветки я всегда использую именно 3-ю.
В связи с этим нужно убрать из {jsfiles} встроенные библиотеки. Идем в /engine/modules/functions.php и удаляем/комментируем:
'engine/classes/js/jquery.js',
'engine/classes/js/jqueryui.js',

В этой же функции находим строки, которые начинаются на:
$js_array[] = "<script type=

И дописываем к ним атрибут defer, после чего все эти строки должны выглядеть так:
$js_array[] = "<script defer type=

Пару слов про defer. Данный атрибут показывает браузеру, что данный скрипт нужно грузить после загрузки всего основного контента страницы. Сей атрибут очень похож на async. Различия их в том, что async подгружает скрипт асинхронно как только у браузера появится возможность и при этом грузятся от меньшего размера файла к большему, а при defer скрипты подгрузятся асинхронно в указанном нами порядке. В связи с вышеизложенным сам jquery подключаем как есть, а все остальные скрипты вместе с defer!

Тут стоит заменить, что jquery.js так же подключается в других файлах DLE, например в Загрузчике файлов в редакторе, который генерируется в /engine/ajax/upload.php и вы можете найти и также заменить все jquery.js на ссылку с CDN. Для поиска файлов может помочь Total Commander.

Далее идем в /engine/classes/min/groupsConfig.php и удаляем/комментируем:
$min_documentRoot . '/engine/classes/js/jquery.js',
$min_documentRoot . '/engine/classes/js/jqueryui.js',

А если хотите вообще по "модному", то можно сделать в таком духе:
'general' => array(
    #$min_documentRoot . '/engine/classes/js/jquery.js',
    #$min_documentRoot . '/engine/classes/js/jqueryui.js',
    $min_documentRoot . '/engine/classes/js/dle_js.js',
    $min_documentRoot . '/templates/Default/js/jquery.cookie.js',
    $min_documentRoot . '/templates/Default/js/ajaxform.js',
    $min_documentRoot . '/templates/Default/js/main.js',
),

И тогда в вашем {jsfiles} уже будут все нужные скрипты. Конечно же при условии включенного кеширования.

Чистим кеш и видим результат! Тем самым мы выполнили 3 правила: Сократите jаvascript, Сократите CSS и Удалите из верхней части страницы код jаvascript и CSS, блокирующий отображение. В конце концов наш main.tpl похож на:
<!DOCTYPE html>
<html>
    <head>
        {headers}
        <link href="{THEME}/images/favicon.ico" rel="icon" type="image/x-icon"/>
        <link href="{THEME}/images/favicon.ico" rel="shortcut icon" type="image/x-icon"/>
        <link href="/all.css" rel="stylesheet"/>
        [aviable=showfull]
            <link href="/full.css" rel="stylesheet"/>
        [/aviable]
        [aviable=addnews]
            <link href="/add.css" rel="stylesheet"/>
        [/aviable]
    </head>

    <body>
        {content}
        
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
        {AJAX}
        {jsfiles}
        [aviable=showfull]
            <script src="/full.js"></script>
        [/aviable]
        [aviable=addnews]
            <script src="/add.js"></script>
        [/aviable]
    </body>
</html>

Пожалуй дальнейший рассказ перенесу в следующую статью. Далее мы поговорим об отложенной подгрузке скриптов и сжатии. Тем самым выполним еще 4 правила. Надеюсь, вам было интересно. Можете задавать вопросы :)
Отредактированно:
Была добавлена заметка про defer
  • +5

Комментарии (7)

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь. Для того, чтобы оставлять комментарии, нужно авторизироваться.
    • Τатьяна Μеркушева
      • 0
    Приветствую уважаемый!
    Очень понравилась статья! Респект!
    Очень жду продолжение! Будет ли ещё статья об оптимизации DLE?
      • support
        • 0
      Привет, да конечно будет еще много чего. Вроде разгреб основные свои проекты. Как раз на их примере в ближайшие дни выложу пару статей с удобными хаками. Спасибо
    • Zet Black
      • 0
    Здравствуйте, Спасибо за вашу статью. Насколько мне известно, то jquery и jqueryui используют в dle ещё модули и шаблоны, например upload.php (jquery), editusers.php (jquery), preview.php (jquery и jqueryui) и страницы print.tpl. У меня dle 11.2 пожалуйста объясните, будут ли работать все модули (не только перечисленные) если я воспользуюсь вашим примером подключения jquery и jqueryui с CDN?
      • support
        • 0
      Здравствуйте. Да, конечно будут. Тот js файл (dle_js.js), который нужен для модальных окон и всего остального мы не трогаем. Он будет выводится через {jsfiles}. Главное {jsfiles} объявить после подключения из cdn
    • Zet Black
      • 0
    Цитата: support
    Нет. Вы не ошибаетесь в этом файле и правда подгружается jquery.js из дистрибутива. Вы можете и там по желанию заменить {$config['http_home_u']}engine/classes/js/jquery.js на путь из cdn. Добавлю эту заметку в статью.

    Тогда пожалуйста подправьте или удалите мой предыдущий коммент и если вам не сложно пересмотрите еще файлы : editusers.php (jquery), newsletter.php (jquery), preview.php (jquery), engine/preview.php (jquery), inc/engine/preview.php (jquery) и inc/engine/preview.php (jqueryui), engine/preview.php (jqueryui) и static_print. Это то, что я не перечислил выше. Если вы знаете как пользоваться поиском по документу, то возможно найдет ещё. Заранее спасибо и процветания Вашему Блогу!!!
      • support
        • 0
      Не задавался вопросом поиска/замены jquery во всех файлах, так как на скорость работы глазами поисковиков это не влияет. Но спасибо, просмотрю и дополню в статью для полноты картины.
    • Zet Black
      • 0
    Цитата: support
    Не задавался вопросом поиска/замены jquery во всех файлах, так как на скорость работы глазами поисковиков это не влияет. Но спасибо, просмотрю и дополню в статью для полноты картины.

    Я не пробовал в этом разбираться, так, как не силен в скриптах, но в консоли вижу, что они (jquery.js, jqueryui.js и dle_js.js) у меня грузятся из этой папки, но хотелось бы загружать библиотеку однажды и чтобы у пользователя (администратора) она хранилась в кэше. Спасибо!