Pull to refresh

Comments 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 и тп.
К настоящему моменту большинство читателей Хабрахабра, принявших участие в опросе, просто указывают скрипты в <head> и не напрягаются (по-видимому) насчёт того, что их скачивание заблокирует отрисовку.

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

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

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

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

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

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

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

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

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

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

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

Да, размер каждой страницы вырастает на 25% (40-50 KB), но на бизнес-критичных сервисах плюсы окупают этот минус.
UFO just landed and posted this here
UFO just landed and posted this here
Странно видеть лидирующим ответ «Обычным, в 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 — в начало или в конец».
Этот перевод меня удручает.

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

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

Можно подумать, что скрипты могут выполниться до того как загрузится DOM. Мне кажется, лучше не «до DOMContentLoaded», а «прямо перед вызовом события DOMContentLoaded».
А статья замечательная, спасибо за перевод.
Sign up to leave a comment.

Articles