С одной стороны, конечно, хочется накладывать JS сразу по мере загрузки HTML. Иными словами, хорошо бы делать инициализацию JS-кода компонента сразу после загрузки HTML-кода компонента:
<div id="something">
...
</div>
<script>
Something.init();
</script>
Понятно зачем — чтобы свести к минимуму задержку между двумя событиями: 1) HTML компонента отобразился и 2) JS компонента загрузился и инициализировался.
Например, чтобы псевдоссылка сразу вела себя как порядочная псевдоссылка и показывала спрятанный за ней контент, а форма сразу умела валидироваться в тот самый момент, когда она полностью вывелась на экран.
Разумеется, для этого нужно грузить JS-код компонента вперед HTML-кода (обычно это делают в <head>
).
***
С другой стороны, следуя рекомендациям ведущих специалистов по борьбе с тормознутостью сайтов, хочется вынести загрузку всех JS-файлов в конец страницы (перед закрывающим тегом <body>
).
Тоже понятно зачем — чтобы первым делом загрузился и показался контент, и у пользователя возникло ощущение, что сайт грузится быстро.
Однако, минус очевиден — увеличивается задержка между рассмотренными выше событиями 1) и 2). То есть мы получаем, что пользователь дольше видит HTML с еще не наложенным яваскриптом.
***
Что делать? Я думаю, что правильный путь — это все-таки вынести загрузку всех JS-файлов в конец страницы, при этом в <head>
грузить один маленький легковесный скрипт, который при попытке пользователя взаимодействовать с компонентом при еще не наложенном JS, будет сигнализировать ему, что, мол, все окей, подожди чуть-чуть, JS грузится и скоро наступит счастье.
Вот и Мэтт Снайдер похожим путем идет. А как вы решаете эту дилемму?
8 комментариев:
Я на такие элементы навешиваю css-класс, который при включенном js на странице, для тех компонент, которым необходим js, делает visibility: hidden. А когда js компонента инициализируется, он убирает этот css-класс.
Этот подход похож на указание атрибутов width и height для image, когда место под изображение резервируется браузером сразу.
Я в таких случаях использую решение из предидущего комментария и сразу после открывающего body вставляю скрипт, который добавляет fixed (по центу вьюпорта) элемент с анимированным гифом (типа "ждите, всё будет"). А в конце инициализации всех компонентов этот элементик с индикатором убираю.
minify наше все. Один css-файл, один js-файл, и все это кешируем.
Минимизация лишь уменьшает проблему, но уж точно не решает.
Проблема
>> Понятно зачем — чтобы свести к минимуму задержку между двумя событиями: 1) HTML компонента отобразился и 2) JS компонента загрузился и инициализировался.
как раз таки и решается. А написание дополнительного кода в попытке скрыть собственное неумение кратко и понятно писать - это плохо...
Если было кода 100 КБ, разбросанного по 10 файлам, а после минимизации стало 50 КБ в одном, это конечно уменьшит время, когда пользователь видит неинициализированный компонент. Но проблема в том, что он все равно его видит, пусть и меньшее количество времени.
В случае, если весь js, что есть на сайте - только какая-нибудь интерактивная форма связи + slideshow, то вставялю script в конец body и не парюсь.
minify + gzip + cache позволяет небольшие файлы выплевывать практически мгновенно.
А в случае веб-приложений, где несжатого js кода порядка 600-700 килобайт, я показываю прелоадер до тех пор, пока весь необходимый для работы js не подгрузится (примерно как в gmail).
И, кстати, в этом случае я не гружу на каждую страницу весь js что есть, пусть даже это и плохо с точки зрения кеширования, js подгружается только по мере необходимости - и трафик бережется, и движок память лишним функционалом не забита.
моя философия: все элементы, видимые на странице без яваскрипта, работают без яваскрипта на встроенной в html функциональности. Всё, что работает только на яваскрипте, показывается только после загрузки яваскрипта. Он грузится последним, и вообще я предпочитаю не делать нечто, без скриптов не работающее
Отправить комментарий