Планы по использованию jQuery в MaxSite CMS

В своём блоге я недавно опубликовал статью «Асинхронная загрузка js-скриптов», где показал как на сегодняшний день оптимально загружать js-скрипты на странице. Исторически в MaxSite CMS используется jQuery, которая загружается в секцию HEAD и по другому она не может работать поскольку в теле BODY используется её код.
В MaxSite CMS 107.4 я добавил новую функцию mso_add_preload(), которая прописывает в секции HEAD link rel="preload" — предзагрузка контента. Это один из первых шагов к тому, чтобы постепенно навести порядок в загрузке всех js-скриптов в lazy-варианте.
Сейчас mso_add_preload() оптимально использовать совместно с mso_add_file(), где второй параметр указывает на lazy (в конце BODY).
mso_add_file('assets/js/tabs.js', true); // подключение в BODY
mso_add_preload('assets/js/tabs.js'); // link rel="preload" в HEAD
Если вы подключаете js-скрипты без зависимостей, то используйте эту связку для ускорения загрузки файлов.
Что касается jQuery, то ситуация более сложная. Сейчас используется универсальная функция mso_load_jquery(), которая возвращает полный html-код (script) для вставки. Эта же функция используется в секции HEAD, то есть у нас все шаблоны всегда загружают основной файл jQuery.
В теории можно было бы прописать для этого файла defer, чтобы добавить асинхронности, но проблема в том, что у нас масса jQuery-плагинов, которые требуют, чтобы перед их подключением уже была загружена основная библиотека.
Можно было бы, конечно переписать все эти плагины на динамическое подключение, но мне кажется это не самый лучший путь.
Я проверял разные решения и решил, что лучшим вариантом будет это эдакое наведение порядка для всех jQuery-файлов. Сейчас функция mso_load_jquery() сразу отдаёт html-код для подключения, но если её переделать по аналогии с mso_add_file() под lazy-загрузку, то мы сможем упорядочить все jQuery-подключения.
Сейчас у нас что-то вроде такого:
echo mso_load_jquery('jquery.cookie.js') . mso_load_jquery('jquery.showhide.js')
По факту это превращается в <script src="...."></script> прямо в месте вывода. Это делается потому что сразу после него идёт js-код:
$(function () {
...
Этот код по факту ожидает загрузки DOM и после выполняется.
Что я думаю изменить.
Первое — функция mso_load_jquery() не будет ничего возвращать, а будет добавлять в глобальное хранилище адрес js-файла. Таким образом получится массив файлов, которые будут подключены в конце BODY (по хуку body_end). То есть все jQuery-файлы автоматом будут загружены как lazy.
Основная библиотека jquery.min.js будет подключаться перед всеми этими файлами, то есть независимо ни от чего, мы гарантируем доступность jQuery всем плагинам и прочим внешним файлам.
При этом можно будет прописать в HEAD ссылки для preload, чтобы дать возможность браузеру загрузить файлы заранее.
Что делать с script-вставками в теле страницы? Самый простой способ — заменить функцию ready от jQuery на нативный JavaScript: вместо
$(function () {
...
будет
document.addEventListener('DOMContentLoaded', () => {
...
На практике это означает, что шаблоны со старым вариантом (ready) перестанут работать из-за ошибки подключения jQuery. Мне это не нравится, поэтому я думаю сделать какой-то «переключатель» через set-переменную, где разрешить загружать jquery.min.js как и прежде в секцию HEAD. Какое-то время по умолчанию будет именно такой вариант, а в последствии поменяем наоборот, чтобы в старых шаблонах нужно будет указать вариант для HEAD. Это позволит дать вебмастерам длительный переходный период и не сломать совместимость.
Выгода от таких изменений будет в том, что скорость загрузки сайтов на MaxSite CMS существенно вырастет, поскольку jQuery достаточно крупная библиотека, которая перестанет тормозить загрузку.
Как вариант, загрузку jquery и остальных скриптов можно разместить в div в конце страницы
echo ''; echo mso_load_jquery(); ... mso_hook('body_script'); echo ''; echo NR . "а после загрузки страницы содержимое этого блока средствами чистого javascript перенести в начало body.
document.body.prepend(document.getElementById('script_ad')); document.getElementById('script_ad').style.display = 'block';Это по сути «жёсткий хак», имевший популярность несколько лет назад. Лучше сделать по нормальному.