46
Grails' Resource Plugin

Grails resources

Embed Size (px)

DESCRIPTION

Presentation about Grails' Resources plugin

Citation preview

Page 1: Grails resources

Grails' Resource Plugin

Page 2: Grails resources

whoami

Colin HarringtonSenior Consultant

[email protected]@ColinHarrington

Page 3: Grails resources

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

Page 4: Grails resources

Why?

Page 5: Grails resources

Performance ~ Perception

Page 6: Grails resources

Performance impacts cost

- less traffic- less load

- better scalability

Page 7: Grails resources

14 rules

http://stevesouders.com/hpws/rules.php

Good performance tips from Yahoo!

Firefox ySlow pluginGoogle Page Speed - Chrome - Firefox - mod_pagespeed for apache

Page 8: Grails resources

Rule 1 - Make Fewer HTTP RequestsRule 2 - Use a Content Delivery NetworkRule 3 - Add an Expires HeaderRule 4 - Gzip ComponentsRule 5 - Put Stylesheets at the TopRule 6 - Put Scripts at the BottomRule 7 - Avoid CSS ExpressionsRule 8 - Make JavaScript and CSS ExternalRule 9 - Reduce DNS LookupsRule 10 - Minify JavaScriptRule 11 - Avoid RedirectsRule 12 - Remove Duplicate ScriptsRule 13 - Configure ETagsRule 14 - Make AJAX Cacheable

Page 9: Grails resources

Example

Page 10: Grails resources

Example optimized with resources

Page 11: Grails resources

Modular development

Page 12: Grails resources

History

● D.I.Y.● 2008 - UI Performance● 2009 - Static Resources Plugin● December 2011 – Resources Plugin included by

default in Grails 2.0 release

Page 13: Grails resources

DIY

● pre-optimized bundles

● custom filters

● build time jobs

Page 14: Grails resources

UI Performance plugin

● http://grails.org/plugin/ui-performance/

● minification of CSS and JS● compression● css sprites● bundling of CSS and JS● build time

Page 15: Grails resources

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.”

Page 16: Grails resources

Using Resources in your Layout

<html> <head> <g:layoutTitle/> <r:layoutResources/> </head> <body> <g:layoutBody/> <r:layoutResources/> </body></html>

Page 17: Grails resources

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>

Page 18: Grails resources

Runtime

● Redirects on legacy URLs to a /static/<resource URI>

● Uses the ProcessingFilter to Process the Resource

Page 19: Grails resources

Resources

● MyApplicationResources.groovy contains modules, bundles, etc.

● ResourcesArtefactType

– *Resources.groovy

● Definable in Config.groovygrails.resources.modules = { … }

Page 20: Grails resources

Resource DSLmodules = {

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']

}

}

Page 21: Grails resources

dependsOn

modules = {

core {

dependsOn 'jquery, utils'

dependsOn 'other'

dependsOn(['heavy', 'metal'])

}

}

Page 22: Grails resources

resource method

modules = {

ui {

resource '/css/forms.css'

resource '/js/forms.js'

}

}

Page 23: Grails resources

resource attributes

● url * required● exclude (exclude:'minify')● bundle● disposition● attrs● id● linkOverride● wrapper

– (wrapper: { s -> "<!--if lt IE 8>$s<!endif-->" } )

Page 24: Grails resources

defaultBundle method

modules = {

core {

defaultBundle 'core-ui'

...

}

ui {

defaultBundle 'core-ui' …

}

}

Page 25: Grails resources

TagLib

● <r:resource>● <r:img>● <r:renderModule>● <r:script> ● <r:layoutResources>● <r:require>● <r:external>

Page 26: Grails resources

CSS

● Bundling

● Rewriting

● Minification

Page 27: Grails resources

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...

Page 28: Grails resources

less.css

● Variables● Mixins● Nested Rules● Functions & Operations

● Client side● Server side● Command Line

● compile ":lesscss-resources:1.3.0.3"● http://lesscss.org/

Page 29: Grails resources

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

Page 30: Grails resources

Javascript

● jQuery● Bootstrap (out of date?)● Handlebars● dustjs● gsp

Page 31: Grails resources

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'/>

Page 32: Grails resources

Asset pipeline

● Pluggable pipeline of ResourceMappers

● Include/exclude logic

● Phases

● Configurable map() method

Page 33: Grails resources

class TestResourceMapper {

def phase = MapperPhase.MUTATION

static defaultExcludes = [ '**/*.png', '**/*.gif', '**/*.jpg', '**/*.jpeg', '**/*.gz', '**/*.zip' ] static defaultIncludes = [ '/images/**' ]

def map(resource, config) { … }}

Page 34: Grails resources

enum MapperPhase { GENERATION, MUTATION, COMPRESSION, LINKNORMALISATION, AGGREGATION, RENAMING, LINKREALISATION, ALTERNATEREPRESENTATION, DISTRIBUTION, ABSOLUTISATION, NOTIFICATION }

Page 35: Grails resources

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

Page 36: Grails resources

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

Page 37: Grails resources

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

Page 38: Grails resources

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'

Page 39: Grails resources

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...

Page 40: Grails resources

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

Page 41: Grails resources

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']

Page 42: Grails resources

Debugging

● Reloading in development

● Debug with ?_debugResources=y

● anti-cache: ?_refreshResources=y

● log4j:● debug "org.grails.plugin.resource"

Page 43: Grails resources

● println grailsResourceProcessor.dumpResources()

Page 44: Grails resources

Write your own plugin?

● Dart?

● Sass?

● Javascript templating du jour?

Page 45: Grails resources

Issues

● Load balancing bugs

● non-DRY elements in Deep hierarchies

● Others?

Page 46: Grails resources

Questions?

Thank you