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

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

Спасибо, оч. интересная статья!
Также простое решение, но менее автоматизированное:
dean.edwards
Да, таких онлайн упаковщиков, можно было бы конечно использовать curl и hpricot, но сами понимаете это не так удобно + зависимость от сторонних сервисов.
* «таких онлайн упаковщиков много»
Давно использую yuicompressor для сжатия. Кросплатформенно и написано на java. Легко подключается к IDE.
Тоже возможный вариант, сначала я рассмотривал подобные подобные упаковщики, но в виде гема мне показалось привлекательней. Для описанного случая интеграция с IDE не нужна, цель описанного способа разделить яваскрипты для разных целей (разработчикам не нужны упакованные файлы и наоборот). Скрипты должны паковаться исключительно на сервере, т.к. неудобно когда разработчику после изменения яваскрипта необходимо его еще и запаковывать.

Tip: если кто-то делает деплой без capistrano вручную через ssh (git, apache/nginx + passenger), можно испльзовать на сервере команду «git pull && rake packr:pack && touch tmp/restart.txt»
Да, тут вы правы, просто у меня задание к phing (аналог ant только для php) запускается из netbeans и у меня нет rubi на компьютере, поэтому компрессор на java удобнее :)

Кстати, во многих ветках asset_packager на github используется YUI.
Я об этом не знал, в последней версии которую я использовал этого не было. Может плагины (разработчики) просто разные?
В официальной версии (sbecker) этого нет. Но есть во многих форках (первые повашиеся сейчас на глаза: eandrejko,menno).

В моем форке тоже есть, но его я бе не советовал использовать сразу, он ушел немного в сторону от основной ветки. В частности, у меня по прежнему используется номер версии в имени файла, а не в параметре и нет автоматической генерации упакованного файла.
Спасибо за информацию!
Я иногда люблю изобретать велосипеды, необычная задача всегда интересней рутинной работы. Так как велосипед обчно делается «под себя», это позволяет сделать его более простым и оптимальным для своего случая, нежели в некоторых плагинах, для которых больше важна универсальность и применимость абсолютно во всех случаях. Хотя во многих плагинах уже разработаны достаточно сложные алгоритмы, которые не имеет смысла переделывать, за что я их и люблю.
Ваш велосипед можно вполне запаковать в простенький гем-плагин, у него есть преимущество как минимум в том, что он проще устроен, чем asset_packager =)

Как я понимаю, единственный минус — то, что packr не умеет работать с CSS. Но для сжатия CSS вполне можно использовать и простое удаление пробелов — наверное, ничего разумней там сделать и нельзя.
Ага, с css он не работает. css тут не рассмтривается, т.к. все приложения с которыми я имею дело переведены на compass, а он и сам умеет генерировать компактный css. По поводу сжатия css вы правы, больше чем удалить лишние пробелы, переносы строк и комментарии тут ничего не сделать.
Насколько я понял из начала статьи packr сжимает файлы более интеллектуально чем удаление пробелов? Значительно лучше, чем тот же asset_packager?
Вы правильно поняли, к примеру jquery-1.3.2.js (development версия) весит 117.9 КБ, а его сжатая версия 38.3 КБ. Выкидываются все пробельные символы, комментарии, сжимаются имена переменных и методов. В запакованном виде код jquery-1.3.2.js выгдяит примерно так:
…[]);g.31=17;g.1W=a;12 g}}18 12 d©.1B(a)}18 7(d.1X(a))12 d(17).2G(a);7(a.1W&&a.31){6.1W=a.1W;6.31=a.31}12 6.6X(d.32(a)?a:d.2t(a))},1W:"",5B:«1.3.2»,size:11(){12 6.15},33:11(a){12 a===q?2u.2a.1Y.1q(6):6[a]},2v:11(a,c,b){14 f=d(a);f.5C=6;f.31=6.…
[voice mode=«со старческим недогованием в голосе»]

Куда катится этот мир… чем плох старый добрый Makefile?

[/voice]
Поясните. Я примерно представляю о чем вы, можно создать makefile с набром файлов и правил. Но в данной статье помимо упаковки есть еще и интеграция с javascript_include_tag, что позволяет подключать несколько файлов по ключу. Так же для изменения списка подключаемых яваскриптов требуется отредактировать всего один файл js_files.yml и эти изменения подхватит и упаковщик. В случае же с makefile, я так понимаю потребуется его перегенерация.
> В случае же с makefile, я так понимаю потребуется его перегенерация.

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

---->8-----------------------------------------

SRC = ../packages
BLD = ../build
COMPRESSOR = ./yuicompressor-2.3.4.jar

SOURCES = $(wildcard $(SRC)/*.js)
MAINS = $(BLD)/core.js
OBJECTS = $(filter-out $(MAINS),$(patsubst $(SRC)%,$(BLD)%,$(SOURCES)))

build: BUILDER = java -jar $(COMPRESSOR) --type js --charset UTF-8 -o $@ $<
build: $(BLD)/.build-optimized $(BLD)/api.js $(BLD)/autoload.no-cache.js

debug: BUILDER = cp $< $@
debug: $(BLD)/.build-debug $(BLD)/api.js $(BLD)/autoload.no-cache.js

$(BLD)/api.js: $(MAINS) $(OBJECTS)
cat $^ > $(BLD)/api.js

$(BLD)/autoload.no-cache.js: ../autoload.js
$(BUILDER)

$(BLD)/%.js: $(SRC)/%.js
$(BUILDER)

$(BLD)/.build-debug:
rm -Rf $(BLD)/*.js $(BLD)/.build-*
touch $(BLD)/.build-debug

$(BLD)/.build-optimized:
rm -Rf $(BLD)/*.js $(BLD)/.build-*
touch $(BLD)/.build-optimized

clean:
rm -Rf $(BLD)/*.js $(BLD)/.build-*

.PHONY:

---->8-----------------------------------------

> Но в данной статье помимо упаковки есть еще и интеграция с javascript_include_tag, что позволяет подключать несколько файлов по ключу

Эм… теперь моя очередь не понимать. Поясните, плиз :-)
Спасибо за пояснение. Но в вашем решении преимуществ я не вижу.

Теперь про javascript_include_tag.
Если брать примеры из статьи (файл js_files.yml)

В development варианте javascript_include_tag :base, :cache => «base_packed» выдаст:
<script src="/javascripts/swfobject.js?1249849468" type=«text/javascript»></script>
<script src="/javascripts/jquery-1.3.2.js?1242498740" type=«text/javascript»></script>
<script src="/javascripts/jquery.media.js?1249119197" type=«text/javascript»></script>
<script src="/javascripts/jquery.markitup.js?1249502010" type=«text/javascript»></script>
<script src="/javascripts/jquery.markitup.set.js?1249502075" type=«text/javascript»></script>
<script src="/javascripts/application.js?1249983693" type=«text/javascript»></script>

В production все запакованные файлы объединяются в один javascript_include_tag :base, :cache => «base_packed» выдаст:
<script type=«text/javascript» src="/javascripts/base_packed.js?1249741119">

Указывается всего лишь ключ :base для подключения всех указанных файлов.
Чтобы еще сильнее уменьшить размер загружаемых объектов, нужно настроить сжатие на сревере.
Обратите внимание на последнюю колонку на картинке.

Image Hosted by ImageShack.us

Тут видно, что тот же уже запакованный яваскрипт из примера, сжимается gzip'ом еще в 2 раза, а для другого контента сжатие может доходить до 80%.

Но это уже тема другой статьи.
>В данной статье я опишу как сжимать яваскрипты дла production, объединять их в один файл,
Это решение не всегда является приемлемым. И если для простых сайтов объединение в один файл еще прокатит, то для сложных систем такой подход будет приводить к:
1. К паразитной загрузке ненужных для текущей страницы, но объединенных скриптов. Паразитные скрипты, кроме того, отбирают ресурсы у клиента.
2. Если текущая страница требует своих «особых» скриптов, и если создать разные версии «объединенных» скриптов, — то порождается неоптимальное использование клиентского кеша, и рост траффика, который можно избежать (например ядро jQuery присутствует в нескольких объединенных файлах).
3. Невозможность «параллельной загрузки» (загрузка с разных доменных имен), когда объединение наоборот тормозит загрузку.

В статье не отмечен один из самых важных этапов «згрузочной оптимизации». Это:
1. настройка сервера для сверки etag и отдачи 304. Что позволяет сократить максимально трафик.
2. настройка сервера на использование клиентского кеша ExpiresDefault. Что позволяет вообще избежать обращений к серверу.
3. (про это упоминалось) — настройка gzip сжатия.
При выполнении п.1 и 2, — упаковщик из благодетеля превращается в зло, ибо нивелирует их эффективность.
Тогда возникает вопрос, стоит ли вообще пользоваться упаковщиком. Для маленьких сатов, где вариация невысока, — да, безусловно. Для сложных систем — выгоднее использовать хорошо спроектированную модульную структуру, как сделано, например в Dojo.

Будьте внимательней, название статьи «Сжатие javascript средствами packr». Ваши претензии никак не относятся к теме.

> Если текущая страница требует своих «особых» скриптов …
можно подгружать их отдельно и сделать несколько ключей
base:
— swfobject.js
— jquery-1.3.2.js
— jquery.media.js
— application.js
markitup:
— jquery.markitup.js
— jquery.markitup.set.js
и т.д.

по поводу
>… 304… ExpiresDefault… gzip
— это настройка веб-сервера (чаще всего это Apache или Nginx либо даже их связка), которая не входит в задачи данной статьи.
Как все это сделать очень легко найти в гугле, тем более способов для этого много. Копипастить смысла не вижу.

> загрузка с разных доменных имен
опять же легко настраивается, но никак не относится к теме.
файл production.rb:
# Enable serving of images, stylesheets, and javascripts from an asset server
# config.action_controller.asset_host = «assets.example.com»

Если надо больше хостов:
Alternatively, you can exert more control over the asset host by setting asset_host to a proc like this:
ActionController::Base.asset_host = Proc.new { |source| «assets#{rand(2) + 1}.example.com» }

image_tag(«rails.png»)
# => < имг alt=«Rails» src=«assets0.example.com/images/rails.png?1230601161» />

stylesheet_link_tag(«application»)
# => < линк href=«assets1.example.com/stylesheets/application.css?1232285206» media=«screen» rel=«stylesheet» type=«text/css» />
>Ваши претензии никак не относятся к теме
Претензий никаких не было.
Теперь будут.
Похоже, суть Вашей статьи — это оптимизация загрузки страницы для небольших сайтиков (а Вы, вероятно только ими и занимаетесь). Только вот непонятно, неужели у них вообще существует потребность в оптимизации?

>Как все это сделать очень легко найти в гугле
Ага-ага. И про обфускацию и минимизацию тоже.

>опять же легко настраивается, но никак не относится к теме.
Да кому нужна эта тема. Людей интересует скорость загрузки, а не басня про шашечки.

P.S.: Последний Ваш комментарий (не без моей подачи) несет больше пользы для читателей, чем сама статья. Будьте внимательней ))
Да куда нам без Вас!?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории