Как стать автором
Обновить

Комментарии 47

Я всегда делал модульность таким образом.
1) Создавал отдельно каждый файл с классом, который он должен реализовать. Например, мне нужно 2 класса Foo и Bar. Я создаю Foo.js и Bar.js.
2) Также создается файл, который объединяет и создает эти классы в одном объекте (чтобы через него было просто обратится ко всем классам). Например, App.js.
3) В каждом из классов написан такой код:
//Foo.js
function Foo() {
    return this;
}

Foo.prototype = {
    print: function() {
        console.debug("Foo");
        }
}
//Bar.js
function Bar() {
    return this;
}

Bar.prototype = {
    print: function() {
        console.debug("Bar");
    }
}
//App.js
function App() {
    this.Foo = new Foo();
    this.Bar = new Bar();
    return this;
}

//on loaded page
window.Application = new App();

Меня этот способ полностью устраивает. На таком же принципе был написан OpenLayersTools.
Осталось 2 нерешенных проблемы: асинхронная загрузка и замыкания. Когда я создаю класс Foo и Bar, он видим в контексте окна. Хотелось бы замыкать эти классы внутри класса приложения, чтобы отгородить плагины и мой код. Асинхронную загрузку пока можно пропускать. Сжимаю грантом все скрипты приложения и получается один файл жс (без плагинов), поэтому по поводу асинхронной загрузки пока особо не переживаю.
А как унаследовать Bar от Foo?
Всё это будет работать, пока у вас не начнутся сложные зависимости. А потом подбирать порядок файлов при склейке?
(Пока читал статью и набирал коммент, TheShock уже задал наводящий вопрос, да).
Каким способом вы пользуетесь? Наследование и полиформизм я тяжело понимаю в JavaScript. К его прототипам я еще не совсем привык.
В надежде найти способ, который был бы очень похожим с вышеописанным, но позволял делать замыкания классов.
Раньше я любил использовать AMD, require.js и прочее. Потом как-то потребность так загружать модули отпала.

Сейчас в начале каждого JS файла есть некоторая директива (скрытая в комментариях), которая указывает зависимость на файлы, что в конечном итоге позволяет нам собрать монолитный файл (ваш вариант с App.js) с правильным порядком определения модулей, классов, нэймспэйсов и так далее (ваши Foo.js и Bar.js).
Я тоже раньше игрался AMD, но не понравилось из-за получения этих самых модулей. Когда в main.js подключаешь все модули, которые возвращаются функцией. А что делать если классов много? Вручную каждый из них обрабатывать? Поэтому я с require слез, не по душе как-то пришлось.
А вот по поводу директивы интересно. Можете подробнее рассказать? Насколько я понял, то про более старые браузеры и их поддержку этой директивы речи быть не может?
Браузеры тут не причем — это сервер обрабатывает. Смотрите sprockets , rails asset pipeline и тп.
Используй Chrome ;)
К настоящему моменту большинство читателей Хабрахабра, принявших участие в опросе, просто указывают скрипты в <head> и не напрягаются (по-видимому) насчёт того, что их скачивание заблокирует отрисовку.

И это правильно.

Какая польза читателю от незаблокированной отрисовки страницы, если для отрисованных элементов её не скачалось ещё описание поведения — так что выходит, что нечего и думать о том, чтобы невозбранно жмякать по ним мышою или пальцем? Или весь интерактив также джаваскриптами рисовать прикажете, а в первоначальный HTML только голый текст для поисковиков поместить?

Вопрос риторический. Трюк, изложенный Вами в блогозаписи, небезынтересен (поэтому я плюсанул перевод). Однако употреблять его я не стану, вероятно.
Полностью согласен. для меня незаблокированная страница, но без реакции на действия хуже, чем заблокированная на лишние пару секунд
НЛО прилетело и опубликовало эту надпись здесь
Многие сайты в реальности подгружают актуальный контент уже дальше асинхронно, после того, как платформа загрузилась. Примеры — soundcloud, coursera. Тут вы пока скрипты не загрузятся всё равно ничего читать не сможете. Неважно, где их грузить.
НЛО прилетело и опубликовало эту надпись здесь
Всё очень просто. Предположим, на вашей странице очень много JS кода, который блокирует отрисовку. Хостится всё это дело не очень близко к пользователю, да ещё и канал у него не очень, так сказать, широкий. Пользователь открывает ваше веб-приложение, с грустью смотрит на белый (?) экран и значок загрузки, вздыхает, думает: «Да а нафига мне пользоваться таким непонятно работающим сервисом? Необработанные тормоза? Лежащий сервер?», ещё раз вздыхает и с высокой долью вероятностью отказывается от пользования вашими услугами.

Другой же вариант событий: пользователь открывает веб-сервис, где видит в меру надоедливый прелоадер (= сообщение о том, что мы работаем, да! щас будет счастье и радость), ждёт и получает необходимое ему.

Это нам с вами — как веб (и около) разработчикам — понятно, почему может быть белая страница с прелоадером. Это нам периодически не лень открыть дебаггер и «отладить» чужое приложение. Пользователям, привыкшим пользоваться продуктами из коробки это не свойственно — им хочется знать, что всё работает. Просто работает.
Мне кажется, пользователь с «канал у него не очень, так сказать, широкий» привык, что сайты могут «непонятно работать»
Не настолько неширокий же :)
Но ожидание загрузки 2-3-х мегабайтного JS может оказаться достаточно утомительным, если просто пялиться в белый экран. Сложно ведь не согласиться с тем, что проявить уважение к пользователю и сказать: «Чувак, мы грузимся, всё в порядке» лучше, чем проявлять бездействие.
И так же может получиться что скрипт подгружаеться с другого сервера (онлайн-чат, шаринги всякие), и этот сервер не отвечает (лежит, тех работы и тд). При этом ожидать 30-60 секунд с белым экраном не у каждого хватит терпения, скорее всего придут к выводу что сайт лежит. При отрисовке страницы можно будет ознакомиться с информацией на сайте за это время (и решить, полезен сайт или нет)
Нужно просто знать все имеющиеся инструменты и уметь ими пользоваться. Иногда нужно грузить в head, иногда в body. Бездумно размещать либо там, либо там — глупо.
Может, но время загрузки скрипта — это тоже контролируемо. Вы ж, наверняка, видели, как это сделано в gmail: если за N секунд скрипт не загрузился, то показать сообщение, мол, может быть, что-то пошло не так. Это всё же лучше, чем бездействие в полной мере. А можно пойти дальше, и, если определённый файл за N секунд не загрузился, то попробовать загрузить его с другого CDN, например.

> При отрисовке страницы можно будет ознакомиться с информацией на сайте за это время (и решить, полезен сайт или нет)
Сайты, на которых можно ознакомиться с текстовой информацией, вообще не должны нести в себе кучу джаваскрипта (или накрайняк первая страница может быть отдана статическим контентом). Я всё же говорю о серьёзных веб-приложениях, где обойтись без большого объёма JS достаточно сложно.
Сайты, на которых можно ознакомиться с текстовой информацией, вообще не должны нести в себе кучу джаваскрипта

Так они обычно и не несут. К примеру пост на каком нибудь блоге, кототые так часто любят усеять разными там шаринк кнопками/виджетами — сайт по сути не несет в себе кучу скрипта, но зависит от стороннего сервера. Я довольно часто попадаю на такие сайты.
Я всё же говорю о серьёзных веб-приложениях, где обойтись без большого объёма JS достаточно сложно.

Для таких приложений скрипты расположены скорее всего на тотм же сервере, и проблема таймаутома в этом случае врят ли сильно беспокоит разработчиков

Ну и в комментарии выше верно сказано — обдуманно располагать скрипты
Для таких приложений скрипты расположены скорее всего на тотм же сервере

Не очень логичное, на мой взгляд, утверждение: мне всё чаще приходится сталкиваться с сервисами, у которых статический контент разнесён по CDN, причём, на несколько серверов сразу (имею ввиду, JS и CSS на одном, изображения на другом, видео на третьем и так далее — видимо, по соответствующей настройке для каждого типа/размера файлов). Но спорить здесь не буду — к сожалению, у меня нет для этого никакой статистики.

Что касается того же сервера, то верить, что случайно что-то не упадёт — достаточно наивно. Динмический контент отдаётся одним способом, статический — другим. Навернулся где-нибудь кэш-сервер — и началось…
Статья хорошая, запутали ещё больше, спасибо!
Это ирония конечно, сам же использовал разные сценарии по юзер-агенту, благо движок позволял. Потом открыл компиляцию в один файл (в head) и сплю спокойно.
И да — чуровщина какая-то в вашем голосовании.
Никакой чуровщины, там можно выбрать несколько ответов одновременно.
Если скриптов не много, то я сжимаю их вместе и включаю в конец страницы.
Такая техника используется на Google Maps и избавляет от проблем с запросами и кешированием.

Да, размер каждой страницы вырастает на 25% (40-50 KB), но на бизнес-критичных сервисах плюсы окупают этот минус.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Странно видеть лидирующим ответ «Обычным, в head» — 61 %
Ну, для специфических приложений типа вашего это оправдано. Для контентных сайтов и т.п. нет
Стоит отметить, что вставка скриптов через javascript не блокирует загрузку других ресурсов, однако отодвигает время срабатывания события window.onload. Этого можно избежать, если подключать скрипты через setTimeout:
[
  '//other-domain.com/1.js',
  '2.js'
].forEach(function(src) {
  setTimeout(function() {
    var script = document.createElement('script');
    script.src = src;
    script.async = false;
    document.head.appendChild(script);
  }, 0);
});

А почему всё так плохо с инновациями в яваскрите? В мс-досе было понятнее и прямее. Наверное не осталось ни одного настолько беспомощного языка во времена бюджетных 8миядерных процессоров. У них ТАМ тоже коррупция все деньги на разработку сжирает?
Судя посту, Вы что MS-DOS, что современный JavaScirpt достаточно плохо себе представляете.
Сомневаюсь, что про мс-дос кто-то догадался бы писать статью про то, что инструкции выполняются в том порядке, в каком они сами захотят. Если наезд на меня был обоснован силою скрипта, подскажите какая в нем синхронизация, а то про нее в статье очень не хватает.
Не знаю насчет статьи, но при создании autoexec.bat надо было учитывать зависимости «ручками» и знать «синхронную» команду запускаешь )(типа nc) или «асинхронную» (типа keyrus).

И вообще к javascript порядок загрузки имеет мало отношения, это проблемы html и браузеров.
К html это тоже маловато отношения имеет, html и javascript здесь инструменты. А проблема — про браузеры и DOM.
DOM в браузере явно зависит от html. Толком управление порядком загрузки в html не предусмотрено. Ввели бы атрибут у script типа depends=%id% (над синтаксисом лень думать) и большую часть проблем поднятых в посте можно было бы решить.
Когда я там, наверху, где заминусовали, писал про коррупцию и кризис, я имел ввиду всю веб-отрасль в целом во всеми ее консорциумами и браузерами. Врядли нормальный человек 80х годов, увидев всё что здесь происходит, похвалил бы корпорации за их здравый разум. Какая разница во что здесь упёрлось — дом или не дом, скрипт или не скрипт. Проблема в этой огромной нестабильной шизе. Доходит до того, что вебразработчикам приходится на стол ставить по 4 монитора. Неужели вы этого не видите? В турбо паскале было достаточно одного монитора, а сейчас недостаточно трех не потому, что сейчас жизнь стала слаще, а потому что технология свихнулась.
Те кто понял комент, положа руку на сердце, скажите, почему так вышло?
Извините, но в статье чувствуется какая-то однобокость и непонимание сути проблемы.

Нет однозначного ответа на вопрос «как вы загружаете скрипты?».

Загружаемая браузером асинхронно в общем случае из нескольких источников html страница представляет собой довольно сложный объект, и при для его нормальной работы используется масса разных способов.

То, без чего сложно обойтись, и что хорошо кэшируется ставится в head, а дельше уже начинается полет фантазии в зависимости от решаемой задачи. Тут делают и аснихронную загрузку с рестартом обломавшихся модулей, и используют localStorage, и ранее популярный трюк с setTimeout( my_lodaer, 1).

В общем, здесь можно много о чем поговорить, но не в духе «куда вы ставите тэги script — в начало или в конец».
Этот перевод меня удручает.

Тем не менее, спасибо за предоставленную информацию.
Поправки можете присылать в личные сообщения :)
А как же importScripts() в Воркерах?
гораздо интереснее переопределить document.write и грузить все скрипты по window.onload…
Я твой друг, мы сделаем это как по учебнику.

Такая манера подачи спеки просто поднимает настроение и усваивается на порядок лучше =)
На примере Twitter Bootstrap у меня в Chrome.
Если на странице, где bootstrap.js подгружается в футере страницы, активно долбить F5, то частенько видна страница без оформления. При переносе в head — просто пустая страница. Хорошо это или плохо, но тут вариант с head выглядит лучше с моей, далеко не frontend, колокольни :)
В кратком справочнике не совсем корректно написано про Defer
Спецификация говорит: Скачивай вместе, выполняй по порядку до DOMContentLoaded. Игнорируй «defer» для скриптов без «src».

Можно подумать, что скрипты могут выполниться до того как загрузится DOM. Мне кажется, лучше не «до DOMContentLoaded», а «прямо перед вызовом события DOMContentLoaded».
А статья замечательная, спасибо за перевод.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории