Your SlideShare is downloading. ×
0
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
The new static resources framework
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
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

The new static resources framework

3,901

Published on

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

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,901
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
45
Comments
0
Likes
8
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. The new staticresources framework
  • 2. About meMarc PalmerPaid to develop WeceemFounder at NoticeLocal and Spotty MushroomOld skool Grails user since 0.4Plugin writing maniac
  • 3. Resource management Web performance
  • 4. Eternal caching Minifying Zipping Bundling Load order
  • 5. Old ProblemsAntJavaBoilerplate codeSpring MVC configCode verbosity
  • 6. New ProblemsDownload performanceComplex UI from plugins
  • 7. Your application Admin UICustom CSS Security UICustom JS Scaffolding CSS JS JS +CSS Blueprint jQuery jQuery UI
  • 8. Optimization hellWho includes resources & when?Is the resource already optimized?Load orderPerformance: I want control
  • 9. Plugin version conventions help:grails-blueprint-0.9grails-jquery-1.4.3grails-jquery-ui-1.8.2
  • 10. Resources pluginResource declaration DSLDependency resolutionResource tagsMapping pipelineModular and extensibleProcessed at runtime
  • 11. Runtime?!
  • 12. Runtime?!
  • 13. Only at startup!Works in any environmentCan be bypassedSupports reloadingTiny trade-off
  • 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. So far so...?Before After
  • 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. 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. What does this page do? What does it need to do it?Explicit resource tags are wrong
  • 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. Link disposition<head> <r:layoutResources/> <!-- head --></head><body> ... <r:layoutResources/> <!-- defer --></body>
  • 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. 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. Better...Before After
  • 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. 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. Deferred inline JS<r:script> initUIThatDoesNotSuck();</r:script>
  • 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. What just happened?Declarative resourcesSingle tag mechanismOptimal, smart orderingResource de-dedupingBundling
  • 29. Now the fun part
  • 30. Mapping pipeline Copy to work dir Apply mappers Modify resource Add response handler Update URI
  • 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. Bundling Mapper /js/jquery-ui/jquery-ui.css /css/blueprint/screen.css /css/main.css /bundle_main.css
  • 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. Resources Others
  • 35. Zipped Resourcesgrails install-plugin zipped-resourcesCompresses files to xxx.css.gzKeeps URI the sameSets Content-Encoding: gzip
  • 36. Cached Resourcesgrails install-plugin cached-resourcesRenames to SHA256 digest of contentsShortens name to base62 encodingFlattens directory structureSets Expires to 1 year
  • 37. /js/some-bloated-lib/plugin/foo.js/b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9.js /UpLdvv429fMac6FhEx5FMU2F3Cg1yj4HwUGmihFvjYR.js
  • 38. In production already
  • 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. 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. FutureMinifyCSS SpritesSmart image links with auto w & hE.S.P. - externalising inline JSFlavours (content variants)CDN up loaders
  • 42. Special thanks... Peter Ledbrook Luke Daley Stéphane Maldini Robert Fletcher Burt Beckwith
  • 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

×