-
Notifications
You must be signed in to change notification settings - Fork 22
Maven plugin for web resource optimization
The plugin shows statistic in the output console, e.g.
[INFO] === Statistic ===========================================
[INFO] Size of original resources = 2.709 MB
[INFO] Size of optimized resources = 1.307 MB
[INFO] Optimized resources have 48.23% of original size
[INFO] =========================================================
Another goal and feature of this Maven plugin is creation of Source Maps and handling of Data URIs.
If you're doing front end web development, your web resources such as JavaScript and CSS files might be minificated, transpiled or compiled from a completely different language. If you now want to debug the generated code in the browser, you can not do that because the output code is obfuscated from the code you wrote. The solution is to use source maps. A good introduction to the source map can be found in the articles [Introduction to JavaScript Source Maps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/) and [Enhance Your JavaScript Debugging with Cross-Browser Source Maps](http://www.sitepoint.com/enhance-your-javascript-debugging-with-cross-browser-source-maps). Currently, the plugin only supports the creation of source maps for JavaScript files. If your generated code is JavaScript, one way to let the development tools know where to look is to add a comment to the end of the generated code which defines the sourceMappingURL - the location of the source map. For example: `//# sourceMappingURL=mylib.js.map` or `//# sourceMappingURL=/mypath/mylib.js.map` or `//# sourceMappingURL=http://sourcemaps/mylib.js.map` If you now open a development tool and the source map support is enabled, the browser will stream down the source map which points to the original file and show the original file instead of generated one (minificated, compiled, transpiled, etc.). Now, you can set a breakpoint in the original file and debug it as it would be delivered with you web application. Such debugging is possible due to the fact that a source map provides a way of mapping code within a generated file back to it's original position in a source file. Data URIs are an interesting concept on the Web. Read ["Data URIs explained"](http://www.nczonline.net/blog/2009/10/27/data-uris-explained/) please if you don't know what it does mean. Data URIs allow any file to be embedded inline within CSS. This technique allows separate elements such as images to be fetched in a single HTTP request rather than multiple HTTP requests, what can be more efficient. Decreasing the number of requests results in better page performance. "Minimize HTTP requests" is actually the first rule of the ["Yahoo! Exceptional Performance Best Practices"](http://developer.yahoo.com/performance/rules.html), and it specifically mentions data URIs. The plugin allows to embed data URIs for referenced images in style sheets. Data URIs are supported for all modern browsers: Gecko-based (Firefox, SeaMonkey, Camino, etc.), WebKit-based (Safari, Google Chrome), Opera, Konqueror, Internet Explorer 8 and higher. For Internet Explorer 8 data URIs must be smaller than 32 KB. Internet Explorer 9 and higher don't have this 32 KB limitation. How does the conversion to data URIs work? Plugin reads the content of CSS files. A special `java.io.Reader` implementation looks for tokens `#{resource[...]}` in CSS files. This is a syntax for image references in JSF 2. Token should start with `#{resource[` and ends with `]}`. The content inside contains image path in JSF syntax. Examples: ```css .ui-icon-logosmall { background-image: url("#{resource['images/logosmall.gif']}") !important; }.ui-icon-aristo { background-image: url("#{resource['images:themeswitcher/aristo.png']}") !important; }
In the next step the image resource for each background image is localized. Images directories are specified according to the JSF 2 specification and suit WAR as well as JAR projects. These are `${project.basedir}/src/main/webapp/resources` and `${project.basedir}/src/main/resources/META-INF/resources`. Every image is tried to be found in those directories.
If the image is not found in the specified directories, then it doesn't get transformed. Otherwise, the image is encoded into base64 string. The encoding is performed only if the data URI string is less than 32KB in order to support IE8 browser. Images larger than that amount are not transformed. Data URIs looks like
```css
.ui-icon-logosmall {
background-image: url("data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgA ... ASUVORK5CYII=") !important;
}
.ui-icon-aristo {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA ... BJRU5ErkJggg==") !important;
}
Supported mime-types are: image/gif
, image/jpeg
and image/png
, so that GIF, JPEG, JPG and PNG images can be converted to data URIs.
Tag | Type | Default value | Description |
inputDir | File | ${project.build.directory}/webapp | Input directory. Command-line parameter is "inputDir". |
compilationLevel | String | SIMPLE_OPTIMIZATIONS | Compilation level. Possible values are: WHITESPACE_ONLY, SIMPLE_OPTIMIZATIONS, ADVANCED_OPTIMIZATIONS. Command-line parameter is "compilationLevel". |
warningLevel | String | QUIET | Warning level. Possible values are: QUIET, DEFAULT, VERBOSE. To understand errors und warnings see this reference. Command-line parameter is "warningLevel". |
encoding | String | UTF-8 | Encoding to read files. Note: output files are ASCII encoded to avoid issues with proxy-servers. Command-line parameter is "encoding". |
failOnWarning | boolean | false | Flag whether this plugin must stop/fail on warnings. |
suffix | String | null | Suffix for compressed / aggregated files. |
useDataUri | boolean | false | Flag if images referenced in CSS files should be converted to data URIs. |
includes | String[] | {"**/*.css", "**/*.js"} | Files to be included. Files selectors follow patterns specified in org.codehaus.plexus.util.DirectoryScanner. |
excludes | String[] | empty array | Files to be excluded. Files selectors follow patterns specified in org.codehaus.plexus.util.DirectoryScanner. |
aggregations | Aggregation[] | null | Aggregations describing configurations how the files have to be aggregated to one big file (outputFile mode, s. below) or less files (subDirMode mode, s. below). |
resourcesSets | List<ResourcesSet> | null | List of resource sets describing resources to be processed (s. below) |
- If the same parameter was configured in
configuration
directly, the value of this parameter inresourcesSet
takes precedence (overwrites the corresponding value inconfiguration
). - If a parameter is missing in
resourcesSet
, the value of the corresponding parameter inconfiguration
will be taken.
Tag | Type | Default value | Description |
inputDir | File | null | Input directory for this resource set. |
compilationLevel | String | null | Compilation level. Possible values are: WHITESPACE_ONLY, SIMPLE_OPTIMIZATIONS, ADVANCED_OPTIMIZATIONS. |
warningLevel | String | null | Warning level. Possible values are: QUIET, DEFAULT, VERBOSE. To understand errors und warnings see this reference. |
useDataUri | boolean | false | Flag if images referenced in CSS files should be converted to data URIs. |
includes | String[] | null | Files to be included. Files selectors follow patterns specified in org.codehaus.plexus.util.DirectoryScanner. |
excludes | String[] | null | Files to be excluded. Files selectors follow patterns specified in org.codehaus.plexus.util.DirectoryScanner. |
aggregations | Aggregation[] | null | Aggregations describing configurations how the files have to be aggregated to one big file (outputFile mode, s. below) or less files (subDirMode mode, s. below). |
The next table gives an overview about all configuration details inside of aggregation
tag. The same rules as above for duplicated / missing configuration parameters are valid.
- If the same parameter was configured in
resourcesSet
orconfiguration
directly, the value of this parameter inresourcesSet
orconfiguration
takes precedence. - If a parameter is missing in
aggregation
, the value of the corresponding parameter inresourcesSet
orconfiguration
will be taken.
Tag | Type | Default value | Description |
inputDir | File | null | Input directory for this aggregation. This allows to define different directories to aggregate compressed and not compressed files simultaneously, at the same time. This makes sense if you have "production" and "development" modes and would like to use uncompressed files in the "development" mode. Uncompressed files can be better debugged and produce better error messages. See the next section with examples how to do such configuration. |
subDirMode | boolean | false | Aggregation per sub-folder. Names of aggregated files should be the same as their folder names where they are placed. Files are aggregated in the lexicographic order. If you want to aggregate files in the pre-defined order, you shoud give all files proper names. It's a good practice to use prefixes to sort them lexicographically. E.g. 0-firstfile.js, 1-seconfile.js, 2-thirdfile.js. See the next section with examples how to do such configuration. |
removeIncluded | boolean | true | Flag whether included original files must be removed. |
withoutCompress | boolean | false | Flag whether included files must be compressed or not. |
outputFile | File | null | Output file for aggregation to one big file. |
prependedFile | File | null | File to be prepended to the aggregated file. |
subDirMode
is probably one of the most benefits of this plugin for modular software. Resources of each module can be optimized separately in an easy way. It makes sense e.g. for component / widget development. Developers can write their scripts / cascading style sheets well-arranged and as much as they want (for better maintenance) - all files will be combined during project build. Web pages should reference combined files from the start of course.
/* float clearing for IE7 */
-
- html .ui-module { min-height: 1%; }
A solution is simple - remove comments `/* .... */`.