Привет!

Подключение скриптов и скорость загрузки страницы

Гадашевич АндрейГадашевич Андрей

В этой статье я хочу поделиться нашим опытом, как мы подключаем скрипты на страницу. Как это влияет на скорость загрузки страницы и клиентскую оптимизацию. А также поделиться готовым решением для cms MODX.

К текущему варианту загрузки скриптов мы пришли не сразу, было прочитано много статей и спецификаций, испробовано несколько различных вариантов. В далеком 2013 году я прочитал отличный перевод "Погружение в темные воды загрузки скриптов" и это помогло собрать и стандартизировать имеющиеся знания.

Спецификация и различные варианты загрузки скриптов

Коротко изложу суть различных методов, боле подробно можете ознакомиться по ссылке выше.

Простое подключение скриптов в head

<script src="//example.com/js/1.js"></script>
<script src="js/2.js"></script>
<script src="js/3.js"></script>

Скрипты будут скачаны вместе и выполнены по порядку после любого ожидающего CSS и блокируя дальнейшую отрисовку страницы до полной их загрузки и интерпретации.

Данный метод можно считать стандартным, т.к. им пользуются подавляющее большинство веб разработчиков. Но он имеет существенный недостаток: блокирует дальнейшую отрисовку страницы до полной отработки подключенных скриптов. Это существенно снижает скорость загрузки страницы для конечного пользователя.

Простое подключение скриптов в конец body

Синтаксис соответствует первому методу. Такое подключение позволяет блокировать меньше всего контента, но если в скрипте есть манипуляции с DOM, это также приостановит дальнейший рендер страницы до полной загрузки и выполнения скриптов.

Асинхронное подключение скриптов

<script src="//example.com/js/1.js" async></script>
<script src="js/2.js" async></script>
<script src="js/3.js" async></script>

Великий и могучий html5 приходит на помощь

Атрибут async говорит браузеру, что можно не ожидать окончания парсинга страницы и параллельно скачивать все скрипты и по завершению выполнить их максимально скоро. В этом скоро как раз и проблема: скрипты выполняются не в том порядке, в котором мы их подключали, а в том порядке, в котором они загрузились. И все бы ничего, если они не связаны друг с другом, но если ,к примеру, один из них библиотека jquery, а другие пользуются ее методами, вы увидите очень много ошибок если она загрузится позже других скриптов.

Динамическое подключение скриптов

Проходя тесты на скорость сайта от google - pagespeed, мы наткнулись на очень интересную рекомендацию.

Deferring loading of JavaScript functions that are not called at startup reduces the initial download size, allowing other resources to be downloaded in parallel, and speeding up execution and rendering time.

— Google

Это значит, что рекомендуется отложить загрузку скрипта до полной загрузки страницы - это увеличит скорость рендера страницы в целом, более подробно здесь.

Откладываем загрузку скриптов до полной загрузки станицы

Наше решение

Наше решение заключается в комбинировании нескольких методов для достижения максимального результата. Так как в наших проектах мы постоянно используем jQuery и от нее зависит работа остальных скриптов, эту библиотеку мы подключаем обособленно от остальных скриптов перед зарывающимся body. Остальные скрипты и плагины мы собираем вместе и минифицируем, в итоге получается один файл, который мы подключаем по рекомендациям google.

Подключение скриптов от makebecool

Компонент для MODX

Изначально мы занимались минификацей скриптов вручную, но очень быстро отказались от этой идеи, так как при любом изменении в исходном скрипте, нужно его минифицировать и обновлять общий скрипт, что очень трудоемко и чревато ошибками из-за человеческого фактора и большого объема непонятного минифицированного кода.

После некоторых проб различных компонентов мы остановились на довольно хорошем компоненте -  MinifiX. Это решение не подходило для нашей схемы с отложенной загрузкой и приходилось его "допиливать" из проекта в проект, пока мы не созрели до написания своего компонента Molt (minimization and optimization of load time).

Теперь работа по подключению скриптов сводится к вставке сниппета и указанию всех необходимых для работы скриптов.

[[molt?
    &cacheFolder=`/assets/design/min/`
    &jsSources=`
        ,/assets/design/js/jquery/plugins/form/jquery.form.min.js
        ,/assets/design/js/jquery/plugins/validation/jquery.validate.min.js
        ,/assets/design/js/jquery/plugins/xhrPool.js
        ,/assets/design/js/jquery/plugins/waypoints.min.js
        ,/assets/design/js/jquery/plugins/jquery.counterup.min.js
        ,/assets/design/js/jquery/plugins/masonry.pkgd.min.js
        ,/assets/design/js/jquery/plugins/jquery.browser.js
        ,/assets/design/js/custom.js
    `
    &cssSources=`
        /assets/design/css/reset.css
       ,/assets/design/css/style.css
    `
]]

Подключение скриптов от makebecool