В своём блоге я недавно опубликовал статью «Асинхронная загрузка 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 достаточно крупная библиотека, которая перестанет тормозить загрузку.
Комментариев: 2 RSS
1АлександрСайт29-12-2020 20:44
Как вариант, загрузку 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';
2Максим29-12-2020 23:05
Это по сути «жёсткий хак», имевший популярность несколько лет назад. Лучше сделать по нормальному.