The new staticresources framework
About meMarc PalmerPaid to develop WeceemFounder at NoticeLocal and Spotty MushroomOld skool Grails user since 0.4Plugin w...
Resource management  Web performance
Eternal caching   Minifying   Zipping   Bundling  Load order
Old ProblemsAntJavaBoilerplate codeSpring MVC configCode verbosity
New ProblemsDownload performanceComplex UI from plugins
Your application                 Admin UICustom CSS                       Security UICustom JS                        Scaf...
Optimization hellWho includes resources & when?Is the resource already optimized?Load orderPerformance: I want control
Plugin version conventions help:grails-blueprint-0.9grails-jquery-1.4.3grails-jquery-ui-1.8.2
Resources pluginResource declaration DSLDependency resolutionResource tagsMapping pipelineModular and extensibleProcessed ...
Runtime?!
Runtime?!
Only at startup!Works in any environmentCan be bypassedSupports reloadingTiny trade-off
Installing itmarcmacbook:AwesomeApp marc$ grails install-plugin resourcesWelcome to Grails 1.3.1 - http://grails.org/Licen...
So far so...?Before          After
Resource DSLFile: grails-app/config/AwesomeResources.groovymodules = {    grailsDefaults {        resource url:[dir:css, fi...
Changes to GSPFile: grails-app/views/index.gsp<html>    <head>        <title>Welcome to Grails</title>        <meta name="...
What does this page do?  What does it need to do it?Explicit resource tags are wrong
Changes to layoutFile: grails-app/views/layouts/main.gsp<html>    <head>        <title><g:layoutTitle default="Grails" /><...
Link disposition<head>     <r:layoutResources/> <!-- head --></head><body>     ...     <r:layoutResources/> <!-- defer -->...
The basic tags<script src="..."><script src="...">              <r:use modules="myStuff"/><link rel="stylesheet" ... /><li...
Disposition in DSLFile: grails-app/config/AwesomeResources.groovymodules = {    grailsDefaults {        resource url:[dir:c...
Better...Before         After
Bundlingmodules = {    grailsDefaults {        resource url:[dir:css, file:main.css]        resource url:[dir:js, file:app...
Dependency overridesmodules = {    grailsDefaults {        defaultBundle core        resource url:[dir:css, file:main.css]...
Deferred inline JS<r:script>    initUIThatDoesNotSuck();</r:script>
We love the debugDevelopment reloadsTurn it all off: add ?_debugResources=yCache defeat: add ?_refreshResources=yX-Grails-R...
What just happened?Declarative resourcesSingle tag mechanismOptimal, smart orderingResource de-dedupingBundling
Now the fun part
Mapping pipeline    Copy to work dir     Apply mappers       Modify resource     Add response handler       Update URI
Mapper Artefactsclass TestResourceMapper {    def priority = Integer.MAX_VALUE    def map(resource, config) {             ...
Bundling Mapper   /js/jquery-ui/jquery-ui.css   /css/blueprint/screen.css         /css/main.css       /bundle_main.css
CSS rewriting                     Before                     /css/main.css:                     body {Both CSS and image  ...
Resources   Others
Zipped Resourcesgrails install-plugin zipped-resourcesCompresses files to xxx.css.gzKeeps URI the sameSets Content-Encoding...
Cached Resourcesgrails install-plugin cached-resourcesRenames to SHA256 digest of contentsShortens name to base62 encoding...
/js/some-bloated-lib/plugin/foo.js/b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9.js         /UpLdvv429f...
In production already
Config conventionsgrails.resources.<mapper>.excludes = [...]grails.resources.modules = { ... }grails.resources.debug = true...
Integration into core                               DSL     Grails Core        Dependency resolution                      ...
FutureMinifyCSS SpritesSmart image links with auto w & hE.S.P. - externalising inline JSFlavours (content variants)CDN up ...
Special thanks...    Peter Ledbrook      Luke Daley   Stéphane Maldini    Robert Fletcher    Burt Beckwith
Q & A and linksSample app:http://bit.ly/awesomeapp1http://bit.ly/awesomeapp2http://grails.org/plugin/resourceshttp://grail...
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
Upcoming SlideShare
Loading in...5
×

The new static resources framework

3,988

Published on

My talk on the new Resources plugin for Grails, at Groovy Grails Exchange 2010

0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,988
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
45
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide

The new static resources framework

  1. 1. The new staticresources framework
  2. 2. About meMarc PalmerPaid to develop WeceemFounder at NoticeLocal and Spotty MushroomOld skool Grails user since 0.4Plugin writing maniac
  3. 3. Resource management Web performance
  4. 4. Eternal caching Minifying Zipping Bundling Load order
  5. 5. Old ProblemsAntJavaBoilerplate codeSpring MVC configCode verbosity
  6. 6. New ProblemsDownload performanceComplex UI from plugins
  7. 7. Your application Admin UICustom CSS Security UICustom JS Scaffolding CSS JS JS +CSS Blueprint jQuery jQuery UI
  8. 8. Optimization hellWho includes resources & when?Is the resource already optimized?Load orderPerformance: I want control
  9. 9. Plugin version conventions help:grails-blueprint-0.9grails-jquery-1.4.3grails-jquery-ui-1.8.2
  10. 10. Resources pluginResource declaration DSLDependency resolutionResource tagsMapping pipelineModular and extensibleProcessed at runtime
  11. 11. Runtime?!
  12. 12. Runtime?!
  13. 13. Only at startup!Works in any environmentCan be bypassedSupports reloadingTiny trade-off
  14. 14. Installing itmarcmacbook:AwesomeApp marc$ grails install-plugin resourcesWelcome to Grails 1.3.1 - http://grails.org/Licensed under Apache Standard License 2.0Grails home is set to: /usr/local/grails-1.3.1Base Directory: /Users/marc/Projects/AwesomeAppResolving dependencies...Dependencies resolved in 1172ms.Running script /usr/local/grails-1.3.1/scripts/InstallPlugin.groovyEnvironment set to developmentInstalling zip ../checkout/Resources/grails-resources-1.0-RC1.zip... ... [mkdir] Created dir: /Users/marc/.grails/1.3.1/projects/AwesomeApp/plugins/resources-1.0-RC1 [unzip] Expanding: /Users/marc/Projects/checkout/Resources/grails-resources-1.0-RC1.zip into /Users/marc/.grails/1.3.1/projects/AwesomeApp/plugins/resources-1.0-RC1Installed plugin resources-1.0-RC1 to location /Users/marc/.grails/1.3.1/projects/AwesomeApp/plugins/resources-1.0-RC1. ...Resolving plugin JAR dependencies ...Executing resources-1.0-RC1 plugin post-install script ...Plugin resources-1.0-RC1 installedmarcmacbook:AwesomeApp marc$
  15. 15. So far so...?Before After
  16. 16. Resource DSLFile: grails-app/config/AwesomeResources.groovymodules = { grailsDefaults { resource url:[dir:css, file:main.css] resource url:[dir:js, file:application.js], disposition:head resource url:[dir:js/prototype, file:prototype.js] } myStuff { dependsOn grailsDefaults resource url:[dir:css, file:branding.css] resource url:[dir:js, file:ui-logic.js] }}
  17. 17. Changes to GSPFile: grails-app/views/index.gsp<html> <head> <title>Welcome to Grails</title> <meta name="layout" content="main" /> <r:use modules="myStuff"/> </head> <body><!-- ... --> </body></html>
  18. 18. What does this page do? What does it need to do it?Explicit resource tags are wrong
  19. 19. Changes to layoutFile: grails-app/views/layouts/main.gsp<html> <head> <title><g:layoutTitle default="Grails" /></title> <r:layoutResources /> <link rel="shortcut icon" href="${r.resource(dir:images,file:favicon.ico)}" type="image/x-icon" /> <g:layoutHead /> </head> <body> <div id="spinner" class="spinner" style="display:none;"> <img src="${r.resource(dir:images,file:spinner.gif)}" alt="Spinner" /> </div> <div id="grailsLogo" class="logo"><a href="http://grails.org"> <img src="${r.resource(dir:images,file:grails_logo.png)}" alt="Grails" border="0" /></a> </div> <g:layoutBody /> <r:layoutResources /> <script type="text/javascript"> oneLineAmazingUI(); </script> </body></html>
  20. 20. Link disposition<head> <r:layoutResources/> <!-- head --></head><body> ... <r:layoutResources/> <!-- defer --></body>
  21. 21. The basic tags<script src="..."><script src="..."> <r:use modules="myStuff"/><link rel="stylesheet" ... /><link rel="stylesheet" ... /><g:resource .../> <r:resource .../><img .../> <r:img .../>
  22. 22. Disposition in DSLFile: grails-app/config/AwesomeResources.groovymodules = { grailsDefaults { resource url:[dir:css, file:main.css] resource url:[dir:js, file:application.js], disposition:head resource url:[dir:js/prototype, file:prototype.js] } myStuff { dependsOn grailsDefaults resource url:[dir:css, file:branding.css] resource url:[dir:js, file:ui-logic.js] }}
  23. 23. Better...Before After
  24. 24. Bundlingmodules = { grailsDefaults { resource url:[dir:css, file:main.css] resource url:[dir:js, file:application.js], disposition:head resource url:[dir:js/prototype, file:prototype.js], bundle: core } myStuff { Cross-module bundle! dependsOn grailsDefaults defaultBundle core resource url:[dir:css, file:branding.css] resource url:[dir:js, file:ui-logic.js] }}
  25. 25. Dependency overridesmodules = { grailsDefaults { defaultBundle core resource url:[dir:css, file:main.css] } myStuff { dependsOn grailsDefaults, blueprint defaultBundle core Text resource url:[dir:css, file:branding.css] resource url:[dir:js, file:ui-logic.js] } overrides { jquery { defaultBundle core } jquery-ui { resource id:js, bundle: core resource id:theme, bundle: core } blueprint { resource id:main, bundle: core } }}
  26. 26. Deferred inline JS<r:script> initUIThatDoesNotSuck();</r:script>
  27. 27. We love the debugDevelopment reloadsTurn it all off: add ?_debugResources=yCache defeat: add ?_refreshResources=yX-Grails-Resources-Original-Src:/bundle-grailsDefaults.js, /js/application.js, /js/prototype/prototype.js
  28. 28. What just happened?Declarative resourcesSingle tag mechanismOptimal, smart orderingResource de-dedupingBundling
  29. 29. Now the fun part
  30. 30. Mapping pipeline Copy to work dir Apply mappers Modify resource Add response handler Update URI
  31. 31. Mapper Artefactsclass TestResourceMapper { def priority = Integer.MAX_VALUE def map(resource, config) { Text def file = new File(resource.processedFile.parentFile, "_${resource.processedFile.name}") assert resource.processedFile.renameTo(file) resource.processedFile = file resource.updateActualUrlFromProcessedFile() }}
  32. 32. Bundling Mapper /js/jquery-ui/jquery-ui.css /css/blueprint/screen.css /css/main.css /bundle_main.css
  33. 33. CSS rewriting Before /css/main.css: body {Both CSS and image background-image: url(../images/bg.png);may be renamed }and/or moved After /bundle_main.css: body { background-image: url(../changed.png); }
  34. 34. Resources Others
  35. 35. Zipped Resourcesgrails install-plugin zipped-resourcesCompresses files to xxx.css.gzKeeps URI the sameSets Content-Encoding: gzip
  36. 36. Cached Resourcesgrails install-plugin cached-resourcesRenames to SHA256 digest of contentsShortens name to base62 encodingFlattens directory structureSets Expires to 1 year
  37. 37. /js/some-bloated-lib/plugin/foo.js/b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9.js /UpLdvv429fMac6FhEx5FMU2F3Cg1yj4HwUGmihFvjYR.js
  38. 38. In production already
  39. 39. Config conventionsgrails.resources.<mapper>.excludes = [...]grails.resources.modules = { ... }grails.resources.debug = truegrails.resources.work.dir = ...grails.resources.uri.prefix = staticgrails.resources.adhoc.patterns = ...
  40. 40. Integration into core DSL Grails Core Dependency resolution Tags Mapping pipelinegrails-resources 2.0 Bundling CSS Rewriting Mapper pluginsgrails-xxxx-resources e.g. zipped-resources
  41. 41. FutureMinifyCSS SpritesSmart image links with auto w & hE.S.P. - externalising inline JSFlavours (content variants)CDN up loaders
  42. 42. Special thanks... Peter Ledbrook Luke Daley Stéphane Maldini Robert Fletcher Burt Beckwith
  43. 43. Q & A and linksSample app:http://bit.ly/awesomeapp1http://bit.ly/awesomeapp2http://grails.org/plugin/resourceshttp://grails.org/plugin/zipped-resourceshttp://grails.org/plugin/cached-resourceshttp://noticelocal.comhttp://www.experienceoz.com.auhttp://www.icescrum.orgAlso check out some unsung plugins:taxonomy, invitation-only, cache-headers,one-time-data, email-confirmation
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×