Grails' Resource Plugin
whoami
Colin Harrington
Senior Consultant
colin.harrington@objectpartners.com
@ColinHarrington
Intro
● Resources plugin
– http://grails.org/plugin/resources
● Installed by default in Grails 2.0
– Available in 1.3.x br...
Why?
Performance ~ Perception
Performance impacts cost
- less traffic
- less load
- better scalability
14 rules
http://stevesouders.com/hpws/rules.php
Good performance tips from Yahoo!
Firefox ySlow plugin
Google Page Speed
-...
Rule 1 - Make Fewer HTTP Requests
Rule 2 - Use a Content Delivery Network
Rule 3 - Add an Expires Header
Rule 4 - Gzip Com...
Example
Example optimized with resources
Modular development
History
● D.I.Y.
● 2008 - UI Performance
● 2009 - Static Resources Plugin
● December 2011 – Resources Plugin included by
d...
DIY
● pre-optimized bundles
● custom filters
● build time jobs
UI Performance plugin
● http://grails.org/plugin/ui-performance/
● minification of CSS and JS
● compression
● css sprites
...
Resources Plugin
● Pluggable framework for handling static resources
● runtime ":resources:1.2-RC1"
● “This plugin represe...
Using Resources in your Layout
<html>
<head>
<g:layoutTitle/>
<r:layoutResources/>
</head>
<body>
<g:layoutBody/>
<r:layou...
GSP view
<html>
<head>
<meta name="layout" content="main"/>
<r:require modules="jquery-ui, blueprint"/>
<r:script>
$(funct...
Runtime
● Redirects on legacy URLs to a
/static/<resource URI>
● Uses the ProcessingFilter to Process the
Resource
Resources
● MyApplicationResources.groovy contains
modules, bundles, etc.
● ResourcesArtefactType
– *Resources.groovy
● De...
Resource DSL
modules = {
core {
dependsOn 'jquery, utils'
defaultBundle 'ui'
resource url:'/js/core.js', disposition: 'hea...
dependsOn
modules = {
core {
dependsOn 'jquery, utils'
dependsOn 'other'
dependsOn(['heavy', 'metal'])
}
}
resource method
modules = {
ui {
resource '/css/forms.css'
resource '/js/forms.js'
}
}
resource attributes
● url * required
● exclude (exclude:'minify')
● bundle
● disposition
● attrs
● id
● linkOverride
● wra...
defaultBundle method
modules = {
core {
defaultBundle 'core-ui'
...
}
ui {
defaultBundle 'core-ui' …
}
}
TagLib
● <r:resource>
● <r:img>
● <r:renderModule>
● <r:script>
● <r:layoutResources>
● <r:require>
● <r:external>
CSS
● Bundling
● Rewriting
● Minification
yui-minification for css and js
● runtime ":yui-minify-resources:0.1.5"
● http://grails.org/plugin/yui-minify-resources
● ...
less.css
● Variables
● Mixins
● Nested Rules
● Functions & Operations
● Client side
● Server side
● Command Line
● compile...
Smart Sprites Resources
● compile ":smart-sprites-resources:0.2"
● http://grails.org/plugin/smart-sprites-resources
● Uses...
Javascript
● jQuery
● Bootstrap (out of date?)
● Handlebars
● dustjs
● gsp
disposition
● link disposition (head vs defer)
● Successive calls to <r:layoutResources>
– Once in the <head/>
– Once befo...
Asset pipeline
● Pluggable pipeline of ResourceMappers
● Include/exclude logic
● Phases
● Configurable map() method
class TestResourceMapper {
def phase = MapperPhase.MUTATION
static defaultExcludes = [
'**/*.png',
'**/*.gif',
'**/*.jpg',...
enum MapperPhase {
GENERATION,
MUTATION,
COMPRESSION,
LINKNORMALISATION,
AGGREGATION,
RENAMING,
LINKREALISATION,
ALTERNATE...
Mapper Phase
● GENERATION
– create new assets = compile less files
● MUTATION
– alter/improve assets (may mean creating ne...
Mapper Phase
● RENAMING
– moving of physical assets = hashing
● LINKREALISATION
– convert normalised inter asset reference...
cached-resources
● runtime ":cached-resources:1.0"
● http://grails.org/plugin/cached-resources
● Files/resources use a SHA...
zipped-resources
● runtime ":zipped-resources:1.0"
● http://grails.org/plugin/zipped-resources
● Gzip applied to files
● S...
cdn-resources
● compile ":cdn-resources:0.2.1"
● http://grails.org/plugin/cdn-resources
● grails.resources.cdn.enabled = t...
Configuration
● Change the /static/ URI prefix:
grails.resources.uri.prefix = 'other'
● grails.resources.work.dir
● grails...
More Config
● grails.resources.adhoc.patterns = ["/images/*", "*.css",
"*.js"]
● grails.resources.mappers.cssrewriter.incl...
Debugging
● Reloading in development
● Debug with ?_debugResources=y
● anti-cache: ?_refreshResources=y
● log4j:
● debug "...
● println grailsResourceProcessor.dumpResources()
Write your own plugin?
● Dart?
● Sass?
● Javascript templating du jour?
Issues
● Load balancing bugs
● non-DRY elements in Deep hierarchies
● Others?
Questions?
Thank you
Upcoming SlideShare
Loading in …5
×

Grails resources

7,782 views
7,486 views

Published on

Presentation about Grails' Resources plugin

Published in: Technology, Education
1 Comment
4 Likes
Statistics
Notes
No Downloads
Views
Total views
7,782
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
26
Comments
1
Likes
4
Embeds 0
No embeds

No notes for slide

Grails resources

  1. 1. Grails' Resource Plugin
  2. 2. whoami Colin Harrington Senior Consultant colin.harrington@objectpartners.com @ColinHarrington
  3. 3. Intro ● Resources plugin – http://grails.org/plugin/resources ● Installed by default in Grails 2.0 – Available in 1.3.x branches ● Written by Marc Palmer & Luke Daley
  4. 4. Why?
  5. 5. Performance ~ Perception
  6. 6. Performance impacts cost - less traffic - less load - better scalability
  7. 7. 14 rules http://stevesouders.com/hpws/rules.php Good performance tips from Yahoo! Firefox ySlow plugin Google Page Speed - Chrome - Firefox - mod_pagespeed for apache
  8. 8. Rule 1 - Make Fewer HTTP Requests Rule 2 - Use a Content Delivery Network Rule 3 - Add an Expires Header Rule 4 - Gzip Components Rule 5 - Put Stylesheets at the Top Rule 6 - Put Scripts at the Bottom Rule 7 - Avoid CSS Expressions Rule 8 - Make JavaScript and CSS External Rule 9 - Reduce DNS Lookups Rule 10 - Minify JavaScript Rule 11 - Avoid Redirects Rule 12 - Remove Duplicate Scripts Rule 13 - Configure ETags Rule 14 - Make AJAX Cacheable
  9. 9. Example
  10. 10. Example optimized with resources
  11. 11. Modular development
  12. 12. History ● D.I.Y. ● 2008 - UI Performance ● 2009 - Static Resources Plugin ● December 2011 – Resources Plugin included by default in Grails 2.0 release
  13. 13. DIY ● pre-optimized bundles ● custom filters ● build time jobs
  14. 14. UI Performance plugin ● http://grails.org/plugin/ui-performance/ ● minification of CSS and JS ● compression ● css sprites ● bundling of CSS and JS ● build time
  15. 15. Resources Plugin ● Pluggable framework for handling static resources ● runtime ":resources:1.2-RC1" ● “This plugin represents a new way of declaring and linking to static resources in your application and plugins. Resource dependencies can be declared (e.g. jQuery UI requires jQuery) and pages simply indicate which resource modules they require. The plugin does the rest, and provides a processing pipeline for advanced optimisations.”
  16. 16. Using Resources in your Layout <html> <head> <g:layoutTitle/> <r:layoutResources/> </head> <body> <g:layoutBody/> <r:layoutResources/> </body> </html>
  17. 17. GSP view <html> <head> <meta name="layout" content="main"/> <r:require modules="jquery-ui, blueprint"/> <r:script> $(function() { $('#form').dialog('open'); }); </r:script> </head> <body> <div id="form"> Hello World </div> </body> </html>
  18. 18. Runtime ● Redirects on legacy URLs to a /static/<resource URI> ● Uses the ProcessingFilter to Process the Resource
  19. 19. Resources ● MyApplicationResources.groovy contains modules, bundles, etc. ● ResourcesArtefactType – *Resources.groovy ● Definable in Config.groovy grails.resources.modules = { … }
  20. 20. Resource DSL modules = { core { dependsOn 'jquery, utils' defaultBundle 'ui' resource url:'/js/core.js', disposition: 'head' resource url:'/js/ui.js' resource url:'/css/main.css', resource url:'/css/branding.css' resource url:'/css/print.css', attrs: [media:'print'] } … }
  21. 21. dependsOn modules = { core { dependsOn 'jquery, utils' dependsOn 'other' dependsOn(['heavy', 'metal']) } }
  22. 22. resource method modules = { ui { resource '/css/forms.css' resource '/js/forms.js' } }
  23. 23. resource attributes ● url * required ● exclude (exclude:'minify') ● bundle ● disposition ● attrs ● id ● linkOverride ● wrapper – (wrapper: { s -> "<!--if lt IE 8>$s<!endif-->" } )
  24. 24. defaultBundle method modules = { core { defaultBundle 'core-ui' ... } ui { defaultBundle 'core-ui' … } }
  25. 25. TagLib ● <r:resource> ● <r:img> ● <r:renderModule> ● <r:script> ● <r:layoutResources> ● <r:require> ● <r:external>
  26. 26. CSS ● Bundling ● Rewriting ● Minification
  27. 27. yui-minification for css and js ● runtime ":yui-minify-resources:0.1.5" ● http://grails.org/plugin/yui-minify-resources ● Confgurable: – grails.resources.mappers.yuicssminify.includes = ['**/*.css'] – grails.resources.mappers.yuijsminify.includes = ['**/*.js'] – grails.resources.mappers.yuicssminify.excludes = ['**/*.min.css'] – grails.resources.mappers.yuijsminify.excludes = ['**/*.min.js'] – More...
  28. 28. less.css ● Variables ● Mixins ● Nested Rules ● Functions & Operations ● Client side ● Server side ● Command Line ● compile ":lesscss-resources:1.3.0.3" ● http://lesscss.org/
  29. 29. Smart Sprites Resources ● compile ":smart-sprites-resources:0.2" ● http://grails.org/plugin/smart-sprites-resources ● Uses Smart Sprites ● http://csssprites.org/ ● Used in UI Performance
  30. 30. Javascript ● jQuery ● Bootstrap (out of date?) ● Handlebars ● dustjs ● gsp
  31. 31. disposition ● link disposition (head vs defer) ● Successive calls to <r:layoutResources> – Once in the <head/> – Once before the closing </body> tag ● Blocking the UI!! Don't do it! ● <r:layoutResources disposition='defer'/>
  32. 32. Asset pipeline ● Pluggable pipeline of ResourceMappers ● Include/exclude logic ● Phases ● Configurable map() method
  33. 33. class TestResourceMapper { def phase = MapperPhase.MUTATION static defaultExcludes = [ '**/*.png', '**/*.gif', '**/*.jpg', '**/*.jpeg', '**/*.gz', '**/*.zip' ] static defaultIncludes = [ '/images/**' ] def map(resource, config) { … } }
  34. 34. enum MapperPhase { GENERATION, MUTATION, COMPRESSION, LINKNORMALISATION, AGGREGATION, RENAMING, LINKREALISATION, ALTERNATEREPRESENTATION, DISTRIBUTION, ABSOLUTISATION, NOTIFICATION }
  35. 35. Mapper Phase ● GENERATION – create new assets = compile less files ● MUTATION – alter/improve assets (may mean creating new/deleting aggregated resources) = spriting ● COMPRESSION – reducing the file size but maintaining semantics = minify ● LINKNORMALISATION – convert all inter asset references into a normal form = css links ● AGGREGATION – combining multiple assets into one = bundling
  36. 36. Mapper Phase ● RENAMING – moving of physical assets = hashing ● LINKREALISATION – convert normalised inter asset references into real form = css links ● ALTERNATEREPRESENTATION – attach different representations of the asset = gzipping ● DISTRIBUTION – moving assets to their hosting environment = s3, cdn ● ABSOLUTISATION – update inter asset references to their distributed equivalent ● NOTIFICATION – let the world know about the new resources = cache invalidation
  37. 37. cached-resources ● runtime ":cached-resources:1.0" ● http://grails.org/plugin/cached-resources ● Files/resources use a SHA-256 hash ● Delegates to the cache-headers plugin – ETag header – Last-Modified header
  38. 38. zipped-resources ● runtime ":zipped-resources:1.0" ● http://grails.org/plugin/zipped-resources ● Gzip applied to files ● Sends the .gz contents ● Sets the Transfer-Encoding header to 'gzip'
  39. 39. cdn-resources ● compile ":cdn-resources:0.2.1" ● http://grails.org/plugin/cdn-resources ● grails.resources.cdn.enabled = true ● grails.resources.cdn.url = " http://static.mydomain.com/” ● Configurable URL per modules...
  40. 40. Configuration ● Change the /static/ URI prefix: grails.resources.uri.prefix = 'other' ● grails.resources.work.dir ● grails.resources.debug = true ● grails.resources.processing.enabled = false ● grails.resources.rewrite.css
  41. 41. More Config ● grails.resources.adhoc.patterns = ["/images/*", "*.css", "*.js"] ● grails.resources.mappers.cssrewriter.includes = ['**/*.css', '**/*.less'] ● grails.resources.mappers.csspreprocessor.includes = ['**/*.css', '**/*.less'] ● grails.resources.mappers.cssrewriter.excludes = ['unsafe/**'] ● grails.resources.mappers.csspreprocessor.excludes = ['unsafe/**'] ● grails.resources.mappers.bundle.excludes = ['unsafe/**/*.css']
  42. 42. Debugging ● Reloading in development ● Debug with ?_debugResources=y ● anti-cache: ?_refreshResources=y ● log4j: ● debug "org.grails.plugin.resource"
  43. 43. ● println grailsResourceProcessor.dumpResources()
  44. 44. Write your own plugin? ● Dart? ● Sass? ● Javascript templating du jour?
  45. 45. Issues ● Load balancing bugs ● non-DRY elements in Deep hierarchies ● Others?
  46. 46. Questions? Thank you

×