UiPerformance Plugin
Original on http://www.grails.org/plugin/ui-performance
Извършване UI Plugin отговаря на някои от 14 -правила от Стив Souders и за изпълнение екип на Yahoo.
Започвайки с версия 1.2 на приставката е включена във всички среди, включително развитие. Вижте дискусията по-долу за "разрешен" довереник атрибут за това как да го изключите за развитие.
Монтиране
За да се интегрира плъгин в молбата Ви, просто стартирате Grails "инсталирай плъгин" скрипт, напр.
grails install-plugin ui-performance
Плъгин е тестван главно в 1.0.4 и 1.1, но не работи в 1.0.3. Поради промяна в името на Events.groovy да _Events.groovy, тя не работи в 1.0.3 без една малка промяна. След като инсталирате плъгина, да преименувате plugins/ui-performance-1.2/scripts/_Events.groovy да Events.groovy. Това само трябва да се прави веднъж и само за 1.0.3.
Функции
- minifies и gzips. JS и на CSS файлове
- конфигурира. JS. CSS, както и файлове с изображения (включително favicon.ico) за кеширане от преименуването с все по-голям изграждане на брой и създаване бъдеще изтича хедър
- taglibs, които са версия и GZIP-наясно, за да позволи на разработчиците да работят без да се занимават с подробности за компресия или версията
- gzips динамично съдържание текст (GSPs, JSON, XML и др.)
- по-голямата част от работата се извършва по време на строителство, както и проблеми, са уловени по време на изграждането, вместо след разгръщането. Един скрипт _Events.groovy куки в процеса на военно строителство и gzips/версии/minifies статични ресурси, преди войната е пакетиран файл
- пренаписва вътрешната URL адреси във файлове на СГО да сочи към versioned изображения
- Sprite изображения чрез taglib
- помага да се движат JavaScript в края на тялото чрез taglib
- не използва сървлет – само няколко taglibs и филтър, отдаване под наем на контейнер (или външен уеб сървър), продължават да служат на статични ресурси
- няма временни файлове и много минимално време на изпълнение на разходите – всичко е във войната и по-малко за обработка на сървъра – то само трябва да се провери, ако клиентът поддържа GZIP когато предлагат <javascript>, <css> и <img> тагове в GSPs,
- Grails-приятелски – може да се позволи по-среда, така че в развитието режим го прави нищо, и е само поддръжка в производството (или "QA", ако вие имате едно "QA" околната среда, например) режим, така че има не налагат проверка за изменения, когато е активен, тъй като Grails не поддържа модификации освен в развитието режим
- много опции за конфигуриране
Динамичен текст компресия използва на PJL Компресирането филтър с конфигурация, взети назаем от Compress плъгин. Вижте тази дискусия за опции за конфигуриране, взаимствани от Compress плъгин и Sourceforge страница на проект на филтъра за повече подробности за неговата конфигурация.
Обосновка
За да се намали размера на изтегляне на JavaScript и CSS файлове, gzips плъгин. JS и на CSS файлове. Разбира се, не всички браузъри поддържат компресия, така че оригиналните некомпресирани файлове се съхраняват. "Accept-Encoding" заглавието е проверена, за да се определи, ако трябва да се изпращат на Генерирай архивирана версия или некомпресиран.
В плъгин също minifies двете. JS и CSS Юи компресор.
Друга функция, която намалява натоварването на сървъра се версии и бъдеще "Изтича" и "Cache-Control" заглавия. Ако все пак не кеширане след това всеки път, когато браузърът зарежда страница, той ще направи искане за сървър, за да се определи дали всеки файл е актуализиран. Тъй като статични ресурси рядко се променят, тези искания причиняват ненужно сървър трафик с 304 код отговор.
Всеки път, когато направи строителство, нова версия се прилага за всички образ, JS, и на CSS файлове, така че файловете могат да бъдат кеширани завинаги. Следващият път, когато разположи нова версия на вашата кандидатура, всички имена на ресурсен файл ще са се променили, така че само тогава ще файлове да бъдат поискани.
Разбира се изображения не са много свие, така gzipping на тях не направи много смисъл, но изображението полезен товар от повечето сайтове ще бъде много по-голяма от тази на. JS и на CSS файлове, така че има смисъл да се опита да накараш клиентите да кешира тези също.
В плъгин желание gzips HTML и други динамично съдържание, генерирани от вашите GSPs и контролери. Ако предпочитате да конфигурирате сами във вашия уеб сървър, след което можете да изключите тази функция, но оставяйки го позволи означава повече сървъра преносимост и по-малко конфигурация. Можете да конфигурирате GZIP за HTML и текстови типове в Tomcat чрез добавяне на
compression='on' compressableMimeType='text/html,text/xml,text/plain'
на HTTP <Connector> елемент в CONF/server.xml. Ако използвате Apache сървър статично съдържание, вие ще искате да използвате mod_deflate.
Можете да конфигурирате уеб сървъра си, за да компресирате. На CSS и JS файлове, но това е много ресурси и разхищението, ако рядко се променят файловете. В плъгин вместо да компресирате файлове веднъж по време на строителство.
Употреба
На приставката е активирана по подразбиране във всички среди (включително развитие), така конфигурирате дали тази опция е включена на околната среда в Config.groovy, например
environments {
development {
uiperformance.enabled = false
}
}
да го изключите в развитие, но тя даде възможност за производство или потребителски среди.
Вие ще трябва да прави промени в GSPs, за да се възползват от тези характеристики.
Да оказва един на тагове <script> за файла JS, използвайте
<p:javascript src='util/collections'/>
което ще направи
<script src='/appcontext/js/util/collections__v123.gz.js'></script>
където "appcontext" е контекстът, ап е разположена под (празен за корен контекст). Имайте предвид, че Генерирай архивирана версия е показано тук, и текущата версия е '123 '. Също така, тъй като удължаването е очевидно, това е пропуснато.
Да оказва <link> тагове за CSS файл, използвайте
<p:css name='main'/>
което ще направи
<link rel='stylesheet' type='text/css' href='/appcontext/css/main__v123.gz.css'/>
Както с. Файлове JS разширението е очевидно, така че е пропуснато.
За да се постанови <img> тагове за файл с изображение, използвайте
<p:image src='logo.png'/>
което ще направи
<img src='/appcontext/images/logo.png' border='0'/>
Да оказва милион <input type='image'…> маркер за изображение базирана форма бутона "изпрати", използвайте
<p:inputImage src='edit.png'/>
което ще направи
<input type='image' src='/appcontext/images/edit.png' border='0'/>
Имайте предвид, че всеки етикет позволява на произволен брой допълнителни атрибути, които са току-що премина през HTML (например, за да се уточни, ИД, стил и др.)
Favicons
По подразбиране си favicon.ico (или каквото и да съм име на файла) ще бъдат обработвани като всяко друго изображение. За да деактивирате това, премахнете разширение изображение "ICO" от списъка на валидните разширения:
uiperformance.imageExtensions = ['gif', 'png', 'jpg']
Да оказва Favicon е versioned тагове, използвайте
<p:favicon/>
което ще направи
<link rel='shortcut icon' href='/favicon.ico' type='image/x-icon'/>
Ако имате нестандартно името или местоположението, уточни, че използването на "SRC" атрибут (без разширение):
<p:favicon src='images/myfavicon'/>
<link rel='shortcut icon' href='images/myfavicon.ico' type='image/x-icon'/>
СГО изображения
Вградено изображение URL адреси във файлове на СГО са проблем, с помощта на тази версия схема, но тъй като всеки файл се обработва по време на строителство, можем да пренаписване на URL адреси, вътре всички файлове на CSS с вградена версия, така че те също са съгласни с имената във войната, напр.
background-image: url(/images/cluetip/wait.gif);
става
background-image: url(/images/cluetip/wait__v123.gif);
Съчетаване
Друга оптимизация е да се намали броят на статични файлове. Обикновено ще дял. CSS и JS файлове за модулност и повторна употреба, но често изпращат едни и същи файлове в няколко страници. Така още една стъпка в процеса на строителство включва групиране JavaScript и CSS файлове в по-големи единични файлове. Това са minified и Генерирай архивирана като останалите, и нетният ефект е по-малко искания с по-малък от общия размер.
Bundles, са configued като списък с карти:
- Имотът е "тип" или "JS" или "CSS"
- "фамилия", собственост определя относителната името на Комбинираната файл
- и имуществото на "файлове" определя списък на относителните имена на файлове
Имайте предвид, че имената на пакетната файл и изходни файлове са относителни, просто като те ще бъдат определени с помощта на горните taglibs пропусне JS "или папка" CSS "и удължаването на срока. Например, тази конфигурация
uiperformance.bundles = [
[type: 'js',
name: 'jquery/jquery.all',
files: ['jquery/jquery-1.2.6',
'jquery/jquery.cluetip']],
[type: 'css',
name: 'bundled',
files: ['yui/reset-min',
'main',
'plugins/custom_cluetip']]
]
ще създаде JS/на JQuery/jquery.all.js, който да съдържа съдържанието на js/jquery/jquery-1.2.6.js и JS/на JQuery/jquery.cluetip.js,.
Това ще създаде и CSS/bundled.css, който да съдържа съдържанието на CSS и на Юи//нулиране min.css, CSS/main.css и CSS/плъгини/custom_cluetip.css.
Можете да създадете произволен брой пакети, които съдържат един брой на изходните файлове.
Поредиците са "не-пакет", ако приставката не е разрешен (например в Dev режим). Така че ще обяви
<p:javascript src='jquery/jquery.all'/>
независимо на околната среда, както и в про режим ще реши един пакет файл, и в Dev режим ще изведе няколко скрипт или на CSS тагове за всеки оригинален файл, който се състои от сноп.
Картинка спрайтове
В плъгин признава на CSS файлове, които са маркирани като се използват SmartSprites коментари. Те са обсъдени подробно в сайта на библиотеката документация, но аз ще покажа някои примери тук. Всичко се определя като коментар, така че тези промени не оказват влияние върху развитието режим. Всички позициониране ощипвам, че са необходими също се определят в Коментари (Sprite марж дъно, спрайт марж ляво, и т.н.).
В CSS файл, който съдържа една или повече стил правила, които определят фоново изображение, да добавите коментар, определящ изображение дух, напр.
/** sprite: mysprite; sprite-image: url('../images/mysprite.png'); sprite-layout: vertical */
Можете да избирате, независимо от името, което искате за Sprite и името на файла. Sprite име (@ mysprite @ в този пример) се използва като клавиш, за да се свържат отделните класове на CSS с Спрайт файл, тъй като можете да декларират множество файлове Sprite на CSS файла (въпреки че това не е необходимо) или дори разделена на CSS файлове и се отнасят до един спрайт образ от всички тях.
След това можете да инструктира SmartSprites да се слеят някои или на всички отделни изображения в Sprite и замени на CSS с позоваване на образ в рамките на Sprite. Като пример съм заменя няколко, ако изображения в стандартните Grails main.css с спрайтове. Някои промени са необходими все пак – не можете да определите background атрибут като комбиниран атрибут. Вместо това трябва да го раздели на фоновото изображение, повтаряне на заден план, фон-позиция и др. Така че ще трябва да се предефинира
.menuButton a.home {
background: url(../images/skin/house.png) center left no-repeat;
…
}
като еквивалентна, но по-многословен
.menuButton a.home {
background-repeat: no-repeat;
background-position: center left;
background-image: url('../images/skin/house.png');
…
}
(Аз съм пропуснал фоновите атрибути, тъй като те са добре, тъй като те са)
и да се включват в образа на Sprite ви добавят коментар на background-image атрибут се позовават на на Sprite файла декларирани на върха (връзка на sprite-ref име на декларация на sprite атрибут, заедно с всички допълнителни атрибути, които са необходими за фино TUNING:
.menuButton a.home {
background-repeat: no-repeat;
background-position: center left;
background-image: url('../images/skin/house.png');/** sprite-ref: mysprite; sprite-margin-bottom: 5px; sprite-margin-top: 3px; */
…
}
Изображенията, които се повтаря като фон не са добри кандидати за включване в спрайтове, така че не преработи тези, но останалите класове са както следва:
.menuButton a.list {
background-repeat: no-repeat;
background-position: center left;
background-image: url('../images/skin/database_table.png');/** sprite-ref: mysprite; sprite-margin-bottom: 5px; sprite-margin-top: 3px; */
}
.menuButton a.create {
background-repeat: no-repeat;
background-position: center left;
background-image: url('../images/skin/database_add.png');/** sprite-ref: mysprite; sprite-margin-bottom: 5px; sprite-margin-top: 3px; */
}
.message {
background-repeat: no-repeat;
background-position: 8px 50%;
background-image: url('../images/skin/information.png');/** sprite-ref: mysprite; sprite-margin-bottom: 4px; sprite-margin-top: 4px; sprite-margin-left: 8px; */
background-color: #f3f8fc;
}
div.errors li {
background-repeat: no-repeat;
background-position: 8px 0%;
background-image: url('../images/skin/exclamation.png');/** sprite-ref: mysprite; sprite-margin-bottom: 8px; sprite-margin-left: 8px; */
}
th.asc a {
background-image: url('../images/skin/sorted_asc.gif'); ** sprite-ref: mysprite; sprite-margin-bottom: 5px; sprite-margin-top: 3px; *
}
th.desc a {
background-image: url('../images/skin/sorted_desc.gif'); ** sprite-ref: mysprite; sprite-margin-bottom: 5px; sprite-margin-top: 3px; *
}
.buttons input.delete {
background-color: transparent;
background-repeat: no-repeat;
background-position: 5px 50%;
background-image: url('../images/skin/database_delete.png');/** sprite-ref: mysprite; sprite-margin-bottom: 6px; sprite-margin-top: 2px; sprite-margin-left: 5px; */
}
.buttons input.edit {
background-color: transparent;
background-repeat: no-repeat;
background-position: 5px 50%;
background-image: url('../images/skin/database_edit.png');/** sprite-ref: mysprite; sprite-margin-bottom: 6px; sprite-margin-top: 2px; sprite-margin-left: 5px; */
}
.buttons input.save {
background-color: transparent;
background-repeat: no-repeat;
background-position: 5px 50%;
background-image: url('../images/skin/database_save.png');/** sprite-ref: mysprite; sprite-margin-bottom: 6px; sprite-margin-top: 2px; sprite-margin-left: 5px; */
}
DependantJavascriptTagLib
От браузъри оценка на скриптове, както те се появяват на HTML (в случай, те пишат в документа) тя е най-добре да ги включите в края на тялото, ако е възможно да се намали на ясно време натоварване (на обща страница и зависими файлове все още отнема същото общо време, но браузъра се появява готов бързо).
За да помогне с това и да се справят с използването Grails на Sitemesh и включва, можете да да използвате <p:dependantJavascript> и <p:renderDependantJavascript> тагове. Където и да имат <script> и <p:javascript> тагове (или вградени скриптове или външни скриптове, използващи атрибут "SRC"), които не пише в документа, ги поставете в <p:dependantJavascript> тагове, напр.
<a href='...'>click here<a> <div id='the_div'>...</div><p:dependantJavascript> <script type='text/javascript'> //inline stuff </script>
<p:javascript src='whatever'/>
</p:dependantJavascript>
които кеш паметта на съдържанието вътре в етикет. След това правят кешираното съдържание, с помощта на стр.: renderDependantJavascript маркер (обикновено в шаблон след организма), например:
<body><g:layoutBody/>
<p:renderDependantJavascript/>
</body> </html>
Имайте предвид, че можете да използвате като много маркери <p:dependantJavascript> като искате в основната ОСП, каквито са включени шаблони, и основният шаблон и всички на комбинираните скриптове, ще бъдат предоставени от единния тагове renderDependantJavascript.
Нова функция ви позволява да зададете кратко блок на JavaScript, като параметър за тагове, напр.
<p:dependantJavascript javascript='var foo = 1; alert(foo);'/>
Тази функция може да се използва, когато се обаждате на taglib от друг, напр.
def firstFieldFocus = { attrs, body ->
String javascript = "javascript that gives focus to the first field in the document"
p.dependantJavascript([javascript:javascript])
}
<p:addJavascript> е друг маркер, който генерира <script> тагове за вас, но иначе е същото като dependantJavascript:
<p:addJavascript> //your javascript </p:addJavascript>
което ще направи
<script type='text/javascript'> //your javascript </script>
или
<p:addJavascript src='foo'/>
което ще направи
<script type='text/javascript' src='/js/foo.js'></script>
Персонализиране
По подразбиране процесът за определяне на версията е да погледнете версията на главната папка на проекта в подривна дейност метаданни файлове. Ако не сте използвате Subversion или искате да използвате някаква друга версия Инкрементиращи логика, можете да определите затваряне в Config.groovy:
uiperformance.determineVersion = { ->/* calculate version here */}
Също така, ако има файлове или групи от файлове, които искате да се изключат от преработка, може да се определи списък на Ant стил пасване модели, напр.
uiperformance.exclusions = [ "**/grails_logo.jpg", "**/dojo/**" ]
Други свойства:
| Характеристики | Стойност по подразбиране | Значение |
|---|---|---|
| uiperformance.enabled | верен | ЛЪЖА, за да забраните на обработката |
| uiperformance.processImages | верен | ЛЪЖА, за да забраните на обработка за всички изображения |
| uiperformance.processCSS | верен | ЛЪЖА, за да забраните обработка за всички. на CSS файлове |
| uiperformance.processJS | верен | ЛЪЖА, за да забраните обработка за всички. JS |
| uiperformance.imageExtensions | "GIF", "PNG", "JPG", "ICO" (+) | определят различни стойности за промяна на вида изображения, които се обработват |
| uiperformance.minifyJs | верен | ЛЪЖА, да деактивирате minification за всички. JS |
| uiperformance.minifyJsAsErrorCheck | грешен | зададен да е истина, за да се стопяват. JS файлове в паметта за проверка за грешки, но ги изхвърлете |
| uiperformance.continueAfterMinifyJsError | грешен | зададен да е истина само предупреждава за minification проблеми JS, а от липса на сградата |
| uiperformance.minifyCss | верен | ЛЪЖА, да деактивирате minification за всички. CSS |
| uiperformance.minifyCssAsErrorCheck | грешен | зададен да е истина, за да се стопяват. на CSS файлове в паметта за проверка за грешки, но ги изхвърлете |
| uiperformance.continueAfterMinifyCssError | грешен | зададен да е истина само предупреждава за minification проблеми на CSS, отколкото при липса на сградата |
| uiperformance.keepOriginals | грешен | зададен да е истина, за да запазите оригиналните некомпресирани и неконтролираните файлове във войната, заедно с компресирани/versioned файлове |
| uiperformance.html.compress | грешен | зададен да е истина, за да се даде възможност GZIP за динамично съдържание на текст |
| uiperformance.html.urlPatterns | не е определена | настроите да се ограничи динамични модели текстови, URL адресът, които трябва да бъдат обработени |
| uiperformance.html.debug | грешен | зададен да е истина, за да се даде възможност PJL филтър Debug сеч |
| uiperformance.html.statsEnabled | грешен | зададен да е истина, за да се даде възможност PJL филтър статистика проследяване |
| uiperformance.html.compressionThreshold | 1024 | определя минималната дължина съдържание за компресия |
| uiperformance.html.jakartaCommonsLogger | не е определена | настроите категория дървар на commons/log4j да трасирате, за да |
В допълнение можете да конфигурирате include/, изключват на траектория модели чрез uiperformance.html.includePathPatterns и uiperformance.html.excludePathPatterns, включва/изключва типове съдържание чрез uiperformance.html.includeContentTypes и uiperformance.html.excludeContentTypes, и да включват/изключват потребителските агенти чрез uiperformance. html.includeUserAgentPatterns и uiperformance.html.excludeUserAgentPatterns. Вижте секцията за конфигурационния тук за обсъждане на смисъла на тези опции.
Ако не конфигурирате типове съдържание, собственост на uiperformance.html.includeContentTypes е настроен на ["текст/HTML", "текст/XML", "текст/обикновен"], тъй като, ако това се остават неподредени, филтърът ще се удвои GZIP вече Генерирай архивирана. CSS и JS файлове.
Автор
Бърт Бекуит burt@burtbeckwith.com
Моля да съобщите за проблеми в списъка на потребителя Grails пощенски и/или да напишете въпрос в JIRA http://jira.codehaus.org/browse/GRAILSPLUGINS по Grails-UI-Performance компонент.
История
- 22 декември, 2009 г.
- пусна версия 1.2.2
- 28 юли, 2009 г.
- пусна версия 1.2.1
- 23 юли, 2009
- пусна версия 1.2
- 20 май, 2009 г.
- пусна версия 1.1.1
- 13 март, 2009 г.
- пусна версия 1.1
- 19 декември, 2008 г.
- освободен версия 1.0
- 10 декември, 2008 г.
- освобождава версия 0,2 в хранилище Grails,
- 26 август, 2008 г.
- освободен първоначалната версия 0.1
