Comments 70
Интересно. Ушёл пробовать.
Спасибо. А я как-то и не задумывался о таких вещах.
Просто мы используем jQuery в качестве фреймворка, а при работе с какими-то специфичными вещами, обычно формируем отдельный js файлик с необходимыми функциями...
Думаю, стоит попробовать и такой подход тоже...
Просто мы используем 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 файл :)
имхо удобно..
семпл на пхп:
$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 файл :)
имхо удобно..
UFO just landed and posted this here
Большой файл всегда будет загружаться быстрее, чем несколько его частей, за счет отсутствия накладных расходов на установку соединения. С картинками ситуация немного другая - если резать картинки "правильно", то каждый из кусков можно сжать лучше, чем картинку в целом.
Более-менее готовое решение: http://www.seanalyzer.ru/projects/jsproc… (не пробовал, но идея нравится).
Там щас совсем страшненькая, но рабочая, версия валяется. Щас есть отрефакторенная, но не доходят руки выложить.
Почему-то никто из комментаторов не затрагивает вопрос поддержки больших файлов. В файле на пару тысяч строк трудновато ориентироваться. Если же не использовать автоматическую сборку, то при создании нового файла нужно лезть в шаблон, который зачастую лежит в другом месте, а нередко и поддерживается другим человеком.
По поводу подгрузки большого скрипта при первом заходе: а никто не заставляет делать сборку для всего сайта, можно сделать сборки для каждой страницы в отдельности и/или для групп страниц.
Вообще, в JsProcessor'е директива //#include(_once) не единственная вкусность. Есть еще //#define, с помощью которого можно не только определять константы (по типу С), а еще и брать переменные из php и из окружения (этакий шаблонизатор, не портящий js-код). А для больших файлов, которые, тем не менее, логически разбивать некуда (методы для работы со строками, например) есть директива //#label, позволяющая отмечать участки кода и подгружать затем только нужный участок.
И все это работает на реальном сайте, напичканном js-скриптами, и проверено временем. Вот только бы еще //#if реализовать для условной сборки.
Почему-то никто из комментаторов не затрагивает вопрос поддержки больших файлов. В файле на пару тысяч строк трудновато ориентироваться. Если же не использовать автоматическую сборку, то при создании нового файла нужно лезть в шаблон, который зачастую лежит в другом месте, а нередко и поддерживается другим человеком.
По поводу подгрузки большого скрипта при первом заходе: а никто не заставляет делать сборку для всего сайта, можно сделать сборки для каждой страницы в отдельности и/или для групп страниц.
Вообще, в JsProcessor'е директива //#include(_once) не единственная вкусность. Есть еще //#define, с помощью которого можно не только определять константы (по типу С), а еще и брать переменные из php и из окружения (этакий шаблонизатор, не портящий js-код). А для больших файлов, которые, тем не менее, логически разбивать некуда (методы для работы со строками, например) есть директива //#label, позволяющая отмечать участки кода и подгружать затем только нужный участок.
И все это работает на реальном сайте, напичканном js-скриптами, и проверено временем. Вот только бы еще //#if реализовать для условной сборки.
Ага, я про остальные вкусности тоже читал. Сейчас столкнулся с необходимостью такой фичи как получение данных в js их какого-то "более внутреннего" источника в приложении, нежели переменные окружения.
Например, в приложении есть конфигурационный файл наподобие Zend_Config, который должен быть доступен и на сервере (в PHP), и на клианте (в JS). Хотелось бы, чтобы при динамической сборке скрипта можно было вставлять в него такие вот данные.
Идея загружать эти данные асинхронно при необходимости в виде json, например, не очень нравится. Может быть и на этот счет есть соображения?
Например, в приложении есть конфигурационный файл наподобие Zend_Config, который должен быть доступен и на сервере (в PHP), и на клианте (в JS). Хотелось бы, чтобы при динамической сборке скрипта можно было вставлять в него такие вот данные.
Идея загружать эти данные асинхронно при необходимости в виде json, например, не очень нравится. Может быть и на этот счет есть соображения?
В свое время долго думал над этим.
В итоге сейчас пользую jQuery. И гружу отдельные плагины к нему, если они нужны на данной странице. Считаю, что с js у меня на проектах все более-менее хорошо.
В итоге сейчас пользую jQuery. И гружу отдельные плагины к нему, если они нужны на данной странице. Считаю, что с js у меня на проектах все более-менее хорошо.
имхо, сама идея загрузки всего js сразу не совсем удачна и своевременна. все-таки не все еще обладают толстым каналом, чтоб грузить такой проект без особого дискомфорта. знаю нескольких людей, которые именно из-за этого отказались от gmail. как один из путей решения представляется все-таки разбить код на несколько модулей, а с самого начала предлагать грузить скрипты только для наиболее посещаемых разделов.
не считаю это правильным...
как сказали встерчают по одежке - и если у меня на главной странице подгрузится скрипт в 150 кб (а именно примерно столько жабаскрипта у нас подгружается в среднем) - то юзеры задолбаются ждать
мы разбили скрипты которые подгружается только там где нужны - а на большое количество запросов - нам откровенно плевать - сервера выдержат :)
да мы пробовали обьеденять в один файл - поставили - на сайте стали реже задерживаться люди - начались жалобы на долгую загрузку и тп... убрали - все стало ок
как сказали встерчают по одежке - и если у меня на главной странице подгрузится скрипт в 150 кб (а именно примерно столько жабаскрипта у нас подгружается в среднем) - то юзеры задолбаются ждать
мы разбили скрипты которые подгружается только там где нужны - а на большое количество запросов - нам откровенно плевать - сервера выдержат :)
да мы пробовали обьеденять в один файл - поставили - на сайте стали реже задерживаться люди - начались жалобы на долгую загрузку и тп... убрали - все стало ок
Вообще, чтобы говорить о проблеммах в подгрузке - хорошо привести пример, в котором страница будет грузиться очень медленно и приведенный пример заметно ускорит её загрузку.
JS кешируются. По этому, смысла в "объеденении JS" не вижу - только если мы хотим загрузить сервер лишней работой. А пользователь, если даже и получит меньшую скорость, то это проценты - миллисекунды и то, в первую загрузку страницы. (далее данные будут прокешированны)
Я надеюсь, что автор во второй части приведет рабочий пример (с кешем и без) :)
JS кешируются. По этому, смысла в "объеденении JS" не вижу - только если мы хотим загрузить сервер лишней работой. А пользователь, если даже и получит меньшую скорость, то это проценты - миллисекунды и то, в первую загрузку страницы. (далее данные будут прокешированны)
Я надеюсь, что автор во второй части приведет рабочий пример (с кешем и без) :)
Как выше пошутил Dargin, может и картинки объеденить? :)
Странно, что этим никто не занимается.
Странно, что этим никто не занимается.
Да, ещё одно замечание. Cервер, конечно же, этим каждый раз заниматься не будет. Это делается один раз после обновления какого либо из JS-файлов.
стоит один раз написать диспетчер вызовов и обращаться к внешним модулям только через него, например:
component("myComponent").call("methodName", {arg1:"val1", arg2:"val2"});
component("myComponent").call("methodName", {arg1:"val1", arg2:"val2"});
да сколько можно уже придумывать подобные грабли?
научитесь правильно кешировать файлы на стороне клиента.
научитесь правильно кешировать файлы на стороне клиента.
И как кеширование поможет при первичной загруке?
См. примечание (1).
См. примечание (1).
да никак! если кеша нет, то его нужно заполнить.
зато все остальные танцы с бубном отпадают после одного запроса.
зато все остальные танцы с бубном отпадают после одного запроса.
Простите, но
1) Описанная мной схема примитивна, как апельсин, и до "танцев с бубном" ей как до луны. Она не предназначена для использования вместо кеширования.
2) Новые пользователи, по вашему, должны сосать лапу, пока страничка грузится в первый раз?
2) Кеш, он такая странная штука, которая имеет свойство периодически опустошаться. При падении браузера например. Почему при этом должны сосать лапу обычные пользователи?
Кроме того, я специально в примечании упомянул кеширование; таком образом, ваше предположение, что я не умею правильно кешировать файлы, мягко говоря, необоснованы. Хотелось бы услышать ваши извинения. "Я был чрезмерно горячен" или "Я был невнимателен" сойдёт.
1) Описанная мной схема примитивна, как апельсин, и до "танцев с бубном" ей как до луны. Она не предназначена для использования вместо кеширования.
2) Новые пользователи, по вашему, должны сосать лапу, пока страничка грузится в первый раз?
2) Кеш, он такая странная штука, которая имеет свойство периодически опустошаться. При падении браузера например. Почему при этом должны сосать лапу обычные пользователи?
Кроме того, я специально в примечании упомянул кеширование; таком образом, ваше предположение, что я не умею правильно кешировать файлы, мягко говоря, необоснованы. Хотелось бы услышать ваши извинения. "Я был чрезмерно горячен" или "Я был невнимателен" сойдёт.
если выполнить ваше первое примечание, то ничего другого вообще не нужно.
:) а если у нас 99% пользователей заходят один-единственный раз? :)
мы сами себе создаём проблему - усложняем систему, объединив файлы. для меня, как для разработчика важна простота компонентов. мне не надо сидеть и дебажить скрипт, который включает все мои четыре файла. если пользователей много, значит сайту нужен CDN и нечего головы ломать, заставлять бедный апачик отдавать статику.
При обновлении проекта кеш принудительно очищается и все файлы надо тянуть заново. При частых обновлениях файлы будут перетягиваться заново часто. HTTP-запросы на канале с большой latency съедают львиную долю времени загрузки. ADSL соединение может быть 5mbit, а страница с несколькими десятками файлов будет грузиться десятки секунд. Объединение рулит в этом случае.
при частых обновлениях, советую научиться разбивать файлы таким образом, чтобы количество новых файлов было минимальным. частые обновление - знак того, что код не стабилен. тестируйте больше перед продакшеном.
Нет, частые обновления это признак того, что проект живёт и развивается.
вот вам примеры живых и развивающихся проектов с нечастыми обновлениями: Prototype, script.aculo.us, jQuery.
а если вы обновляете какую-то свою библиотеку c вашего сайта каждый день - поверьте, у вас проблемы.
а если вы обновляете какую-то свою библиотеку c вашего сайта каждый день - поверьте, у вас проблемы.
А что собирать надо только библиотеки? Вот вам пример живого, развивающегося сервиса: http://wow.ya.ru
И не один день, а раз в неделю, этого достаточно, чтобы задуматься о сборке.
И не один день, а раз в неделю, этого достаточно, чтобы задуматься о сборке.
по вашему, я должен каждую неделю тянуть заново 10-ть в 1-м вместо пары-тройки файлов?
Для сброса кеша используется foo.js?build=N.
Как вы опеределите в автоматическом режиме, что эта пара-тройка файлов изменилась в этом билде, в отличие от того, что сейчас в продакшене? Проще всего проставить новый build=N для всех файлов.
Как вы опеределите в автоматическом режиме, что эта пара-тройка файлов изменилась в этом билде, в отличие от того, что сейчас в продакшене? Проще всего проставить новый build=N для всех файлов.
у меня в имени файла есть его версия.
меняется файл, меняется и его имя. значит клиент запросит новый файл.
меняется файл, меняется и его имя. значит клиент запросит новый файл.
Вы это руками делаете или в автоматическом режиме?
да, вручную - в два удара: имя файла и в одном php-файле его новое имя.
А теперь представьте, что файлов у вас сотни и разработчиков десяток.
это не многое меняет. каждый занимается своим файлом и заботится о том, чтобы он был правильно прописан.
Хороший наглядный пример. Там на одной странице подключается 48 js-файлов и 12 css-файлов. Все, разумеется, кэшируются браузером и обновляются не так часто, но при каждой загрузке браузер вынужден делать 60 http-запросов, чтобы проверить, не изменился ли какой-нибудь файл.
Уй, зря вы это сказали. Если там при каждой загрузке запросы отправляются - это как раз пример "плохого" кэширования.
если настроены expires заголовки, за проверок вообще не будет, пока "срок годности" не выйдет.
и ещё. gzip вам и медленным клиентам в помощь.
кеш и сжатие трафика, вот где сила!
кеш и сжатие трафика, вот где сила!
Я про latenty на http запросах, вы мне про гзип. Не находите, что до того, как гзип сработает должен запрос прийти? Так вот в этом и есть тормоза, а не в скорости отдачи контента сервером.
latency в запросах CDN должен устранить.
если нету его, то давайте зададимся вопросом, а сколько сил мы бросаем на решение столь второстепенной проблемы, вместо того, чтобы заняться чем-то действительно полезным?
если мы говорим про какой-то конкретный случай, когда сайт на северном полюсе, а клиент на южном сидит через модем в 33600 Кб/с, и он единственный пользователь нашего сайта, тогда другое дело.
если нету его, то давайте зададимся вопросом, а сколько сил мы бросаем на решение столь второстепенной проблемы, вместо того, чтобы заняться чем-то действительно полезным?
если мы говорим про какой-то конкретный случай, когда сайт на северном полюсе, а клиент на южном сидит через модем в 33600 Кб/с, и он единственный пользователь нашего сайта, тогда другое дело.
ИМХО большинство пользователей сначала попадают на заглавную страницу. Сделав заглавную в обычном дизайне, но без JS (или практически), можно показать пользователю "часть" сайта намного быстрее, чем если заглавная подгружает скрипты. Сплешскрины в начале скорее всего и были наделены такой идеей, которая затем была забыта дизайнерами.
Похожий подход я использую в своих проектах, отличие в том, что у меня в описании зависимости всего 2 уровня и этого достаточно т.к. результирующий список строится в несколько проходов, потом полученный скрипт пропускается через упаковщик скрипта, а затем упаковывается gzipом и помещается в кэш на сервере и затем отдается всем, кто желает получить такой же набор скриптов.
На практике сталкивался с тем, что для некоторых скриптов важен порядок помещения в единый файл скриптов, поэтому зависимости и порядок описываю отдельным файлом.
Так же оставил возможность простым переключением использовать скрипты классическим способом (например при отладке). Таким же образом обрабатываю и CSS файлы. Сейчас решаю вопрос с версионностью наборов скриптов. Если интересно, попробую найти время и описать поподробнее.
На практике сталкивался с тем, что для некоторых скриптов важен порядок помещения в единый файл скриптов, поэтому зависимости и порядок описываю отдельным файлом.
Так же оставил возможность простым переключением использовать скрипты классическим способом (например при отладке). Таким же образом обрабатываю и CSS файлы. Сейчас решаю вопрос с версионностью наборов скриптов. Если интересно, попробую найти время и описать поподробнее.
Статья стала последней каплей. Отодвинул все дела, засучил рукава да и объединил все js файлы в один, в своём проекте.
Спасибо!
Спасибо!
Идея неплохая, лично я пользуюсь малоизвестным но чень удобным js фреймворком сделанным именно по такому принципу: каждая функция реализована в виде пары — js файл с кодом + xml файл с зависимостями. Также есть отдельная программа которая собирает в единственный файл только необходимые функции
Если заинтересовало ищите здесь http://cross-browser.com/
Если заинтересовало ищите здесь http://cross-browser.com/
DAG - ориентированный ациклический граф; на лекциях по дискретной математике спать просто вредно :)
и кстати, почему бы не рассмотреть "системы модулей" в существующих JS-фреймворках?
и кстати, почему бы не рассмотреть "системы модулей" в существующих JS-фреймворках?
Sign up to leave a comment.
Объединение JS-файлов 2.0 (1/2)