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

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

Интересно. Ушёл пробовать.
Спасибо. А я как-то и не задумывался о таких вещах.
Просто мы используем jQuery в качестве фреймворка, а при работе с какими-то специфичными вещами, обычно формируем отдельный js файлик с необходимыми функциями...

Думаю, стоит попробовать и такой подход тоже...
можно ещё и автоматическую сборку наворотить ;)
семпл на пхп:

$add_js = new AddJs();
$add_js -> AddRoot('dom.js');
$add_js -> AddRoot('pane.js');
$add_js -> AddBranch('transition.js');
$add_js -> Optimize = true;
$add_js -> Gzip = true;
$add_js -> GetJsFile();

после чего скрипт делает всю рутину в стиле обхода дерева, выделения юников из массива..
в конце он выплёвывает собранный воедино, оптимизированый по размеру и гзипнутый js файл :)
имхо удобно..
В принципе, оно более-менее так и сделано.
Ну и еще ссылку на source было бы неплохо приложить.
Идея неплохая.
НЛО прилетело и опубликовало эту надпись здесь
Большой файл всегда будет загружаться быстрее, чем несколько его частей, за счет отсутствия накладных расходов на установку соединения. С картинками ситуация немного другая - если резать картинки "правильно", то каждый из кусков можно сжать лучше, чем картинку в целом.
Плюс к этому, если имеется сжатие gzip'ом, то большой файл сожмется лучше, чем куча маленьких.
Там щас совсем страшненькая, но рабочая, версия валяется. Щас есть отрефакторенная, но не доходят руки выложить.

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

По поводу подгрузки большого скрипта при первом заходе: а никто не заставляет делать сборку для всего сайта, можно сделать сборки для каждой страницы в отдельности и/или для групп страниц.

Вообще, в JsProcessor'е директива //#include(_once) не единственная вкусность. Есть еще //#define, с помощью которого можно не только определять константы (по типу С), а еще и брать переменные из php и из окружения (этакий шаблонизатор, не портящий js-код). А для больших файлов, которые, тем не менее, логически разбивать некуда (методы для работы со строками, например) есть директива //#label, позволяющая отмечать участки кода и подгружать затем только нужный участок.

И все это работает на реальном сайте, напичканном js-скриптами, и проверено временем. Вот только бы еще //#if реализовать для условной сборки.
Ага, я про остальные вкусности тоже читал. Сейчас столкнулся с необходимостью такой фичи как получение данных в js их какого-то "более внутреннего" источника в приложении, нежели переменные окружения.

Например, в приложении есть конфигурационный файл наподобие Zend_Config, который должен быть доступен и на сервере (в PHP), и на клианте (в JS). Хотелось бы, чтобы при динамической сборке скрипта можно было вставлять в него такие вот данные.

Идея загружать эти данные асинхронно при необходимости в виде json, например, не очень нравится. Может быть и на этот счет есть соображения?
В php
$jsprocessor->assign('var', 'value');

В js
//#define FROM_PHP $var
alert(FROM_PHP);

JavaScript в результате
alert('value');
Да, только не понятно, как определить, что для этого js-файла (там где используется //#define FROM_PHP $var) процессор должен выполнить assign в эту $var, а в остальных — нет. Или нужно этот assign писать везде?
Хм, честно говоря, не понял вопроса.
В свое время долго думал над этим.
В итоге сейчас пользую jQuery. И гружу отдельные плагины к нему, если они нужны на данной странице. Считаю, что с js у меня на проектах все более-менее хорошо.
имхо, сама идея загрузки всего js сразу не совсем удачна и своевременна. все-таки не все еще обладают толстым каналом, чтоб грузить такой проект без особого дискомфорта. знаю нескольких людей, которые именно из-за этого отказались от gmail. как один из путей решения представляется все-таки разбить код на несколько модулей, а с самого начала предлагать грузить скрипты только для наиболее посещаемых разделов.
Угу, это я собирался разобрать во второй части. Много за раз написать трудно.
не считаю это правильным...
как сказали встерчают по одежке - и если у меня на главной странице подгрузится скрипт в 150 кб (а именно примерно столько жабаскрипта у нас подгружается в среднем) - то юзеры задолбаются ждать

мы разбили скрипты которые подгружается только там где нужны - а на большое количество запросов - нам откровенно плевать - сервера выдержат :)

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

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

Я надеюсь, что автор во второй части приведет рабочий пример (с кешем и без) :)
Как выше пошутил Dargin, может и картинки объеденить? :)
Странно, что этим никто не занимается.
Объединением картинок занимаются. Ключевое слово - CSS Sprites.

Выигрыш во времени при объединении файлов уже много раз разбирался, но поскольку возникли вопросы - подброшу статистику.
Да, ещё одно замечание. Cервер, конечно же, этим каждый раз заниматься не будет. Это делается один раз после обновления какого либо из JS-файлов.
Согласен. На счёт статистики - ждём.
Спасибо.
стоит один раз написать диспетчер вызовов и обращаться к внешним модулям только через него, например:

component("myComponent").call("methodName", {arg1:"val1", arg2:"val2"});
Зачем?
да сколько можно уже придумывать подобные грабли?
научитесь правильно кешировать файлы на стороне клиента.
И как кеширование поможет при первичной загруке?
См. примечание (1).
да никак! если кеша нет, то его нужно заполнить.
зато все остальные танцы с бубном отпадают после одного запроса.
Простите, но
1) Описанная мной схема примитивна, как апельсин, и до "танцев с бубном" ей как до луны. Она не предназначена для использования вместо кеширования.
2) Новые пользователи, по вашему, должны сосать лапу, пока страничка грузится в первый раз?
2) Кеш, он такая странная штука, которая имеет свойство периодически опустошаться. При падении браузера например. Почему при этом должны сосать лапу обычные пользователи?

Кроме того, я специально в примечании упомянул кеширование; таком образом, ваше предположение, что я не умею правильно кешировать файлы, мягко говоря, необоснованы. Хотелось бы услышать ваши извинения. "Я был чрезмерно горячен" или "Я был невнимателен" сойдёт.
возможно, "Я был чрезмерно горячен", прощу прощения. "Я был невнимателен" и ни в коем случае не хотел сказать, что вы не умеете кешировать.
просто создавая дополнительные зависимости в своём проекте, вы обрекаете программистов на новые ошибки.
если выполнить ваше первое примечание, то ничего другого вообще не нужно.
:) а если у нас 99% пользователей заходят один-единственный раз? :)
мы сами себе создаём проблему - усложняем систему, объединив файлы. для меня, как для разработчика важна простота компонентов. мне не надо сидеть и дебажить скрипт, который включает все мои четыре файла. если пользователей много, значит сайту нужен CDN и нечего головы ломать, заставлять бедный апачик отдавать статику.
При обновлении проекта кеш принудительно очищается и все файлы надо тянуть заново. При частых обновлениях файлы будут перетягиваться заново часто. HTTP-запросы на канале с большой latency съедают львиную долю времени загрузки. ADSL соединение может быть 5mbit, а страница с несколькими десятками файлов будет грузиться десятки секунд. Объединение рулит в этом случае.
при частых обновлениях, советую научиться разбивать файлы таким образом, чтобы количество новых файлов было минимальным. частые обновление - знак того, что код не стабилен. тестируйте больше перед продакшеном.
Нет, частые обновления это признак того, что проект живёт и развивается.
вот вам примеры живых и развивающихся проектов с нечастыми обновлениями: Prototype, script.aculo.us, jQuery.
а если вы обновляете какую-то свою библиотеку c вашего сайта каждый день - поверьте, у вас проблемы.
А что собирать надо только библиотеки? Вот вам пример живого, развивающегося сервиса: http://wow.ya.ru

И не один день, а раз в неделю, этого достаточно, чтобы задуматься о сборке.
по вашему, я должен каждую неделю тянуть заново 10-ть в 1-м вместо пары-тройки файлов?
Для сброса кеша используется foo.js?build=N.

Как вы опеределите в автоматическом режиме, что эта пара-тройка файлов изменилась в этом билде, в отличие от того, что сейчас в продакшене? Проще всего проставить новый build=N для всех файлов.
у меня в имени файла есть его версия.
меняется файл, меняется и его имя. значит клиент запросит новый файл.
Вы это руками делаете или в автоматическом режиме?
да, вручную - в два удара: имя файла и в одном php-файле его новое имя.
А теперь представьте, что файлов у вас сотни и разработчиков десяток.
это не многое меняет. каждый занимается своим файлом и заботится о том, чтобы он был правильно прописан.
Всё ясно. Теоретик.
вам виднее, видимо :)
ни один нормальный tech leader не даст вам делать 100 файлов на проекте, если это не ExtJS какой-нить :)
Я и говорю, теоретик.
этот теоретик однажды работал в стартапе, где каждый из 6-ти программеров писал свои собственные обработчики для AJAX, когда уже существовали кроссбраузерные JS-библиотеки.
поверьте, у меня есть опыт.
В огороде бузина, а в Киеве дядя.

Как соотносится ваш страшный опыт работы с программистами, не умеющими использовать существующие инструменты, с неиспользованием инструментов вообще?
buena suerte, mi amigo
Хороший наглядный пример. Там на одной странице подключается 48 js-файлов и 12 css-файлов. Все, разумеется, кэшируются браузером и обновляются не так часто, но при каждой загрузке браузер вынужден делать 60 http-запросов, чтобы проверить, не изменился ли какой-нибудь файл.
Уй, зря вы это сказали. Если там при каждой загрузке запросы отправляются - это как раз пример "плохого" кэширования.
Скорее всего кэширование работает нормально, меня смущает сам факт подключения 60 файлов без учета картинок.
если настроены expires заголовки, за проверок вообще не будет, пока "срок годности" не выйдет.
и ещё. gzip вам и медленным клиентам в помощь.
кеш и сжатие трафика, вот где сила!
Я про latenty на http запросах, вы мне про гзип. Не находите, что до того, как гзип сработает должен запрос прийти? Так вот в этом и есть тормоза, а не в скорости отдачи контента сервером.
latency в запросах CDN должен устранить.
если нету его, то давайте зададимся вопросом, а сколько сил мы бросаем на решение столь второстепенной проблемы, вместо того, чтобы заняться чем-то действительно полезным?
если мы говорим про какой-то конкретный случай, когда сайт на северном полюсе, а клиент на южном сидит через модем в 33600 Кб/с, и он единственный пользователь нашего сайта, тогда другое дело.
Мы решаем конкретные проблемы конкретных пользователей.
а тоже ценю каждого своего пользователя. но гонясь за всеми, вы не угодите всем.
Немного не то. "Фишка", которую я пытаюсь продвинуть - не само по себе слияние, а учёт зависимостей при слиянии.
ИМХО большинство пользователей сначала попадают на заглавную страницу. Сделав заглавную в обычном дизайне, но без JS (или практически), можно показать пользователю "часть" сайта намного быстрее, чем если заглавная подгружает скрипты. Сплешскрины в начале скорее всего и были наделены такой идеей, которая затем была забыта дизайнерами.
Похожий подход я использую в своих проектах, отличие в том, что у меня в описании зависимости всего 2 уровня и этого достаточно т.к. результирующий список строится в несколько проходов, потом полученный скрипт пропускается через упаковщик скрипта, а затем упаковывается gzipом и помещается в кэш на сервере и затем отдается всем, кто желает получить такой же набор скриптов.
На практике сталкивался с тем, что для некоторых скриптов важен порядок помещения в единый файл скриптов, поэтому зависимости и порядок описываю отдельным файлом.
Так же оставил возможность простым переключением использовать скрипты классическим способом (например при отладке). Таким же образом обрабатываю и CSS файлы. Сейчас решаю вопрос с версионностью наборов скриптов. Если интересно, попробую найти время и описать поподробнее.
Статья стала последней каплей. Отодвинул все дела, засучил рукава да и объединил все js файлы в один, в своём проекте.

Спасибо!
в js framework-е YUI есть компонент yuiloader
оттуда можно почерпнуть много идей по теме подгрузки зависимостей
на его основе в своём проекте делал автоматическое подключение нужных скриптов и css-файлов
немного не туда коммент написал *confused*
Идея неплохая, лично я пользуюсь малоизвестным но чень удобным js фреймворком сделанным именно по такому принципу: каждая функция реализована в виде пары — js файл с кодом + xml файл с зависимостями. Также есть отдельная программа которая собирает в единственный файл только необходимые функции
Если заинтересовало ищите здесь http://cross-browser.com/
DAG - ориентированный ациклический граф; на лекциях по дискретной математике спать просто вредно :)

и кстати, почему бы не рассмотреть "системы модулей" в существующих JS-фреймворках?
Вот могу руку на отсечение дать, что преподаватель как-то обошел этот термин. Орграфы и деревья - естественно был. (Хотя я мог и просто забыть об этом за прошедшие пять лет).

Рассмотрим.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории