Minifying assets

Definitions

  • assets = resources css, javascript.
  • minify = remove every character that takes space without providing function.
  • concat = well you know concatenation, create on file containing all your css, one file with all your javascript.

What is it?

It reduces the size of the css and javascript, by minfying and concatenating them.
Minification refers to the process of removing unnecessary or redundant data without affecting how the resource is processed by the browser - e.g. code comments and formatting, removing unused code, using shorter variable and function names, and so on.

Why?

Because, 10 css and 13 javascripts (1 from google) for TM, it takes time!


Your browser is limited to 6 tcp connections at the same time, to the same domain.
That's why your connections are stalled, they are waiting for already established connection to become available.

If you can reduce the number of css and javascript to load you reduce the page load time and your user will be happy.

Because we are using jboss-seam some css and js are injected by the framework at compile time, so we can't minfy them (I'll try to copy them in the project to test).

When using minification the number of request is reduced: 6css and 5 javascript (1 from google) total of 11 requests instead of 23 to load css and javascript.
The browser loads images earlier than before.

Before minification



After minification


How does it work?

  • You develop using multiple css and javascript to ease maintainability.
  • You ask maven to concat an minify your assets. 
  • It generates 2 files, one css and one javascript.
  • Files name contains timestamps, allowing us to use cache on user browser and on server side without worrying about cache invalidation.
  • You include only the 2 generated files in your template.xhtml.

How can I do that?

Since gazelle-seam 1.124 you can use the minify-maven-plugin in your projects

update your projects to reference gazelle-seam 2.0.9 or higher.

Conventions

We will follow those conventions:

  • Assets are stored in war
  • css goes into: src/main/webapp/resources/stylesheet
  • javascript goes into: src/main/resources/jscript
The advantage of those conventions is that when your war depends upon another war, they are merged at compile time in your target.
So your target includes the resources/stylesheet and resources/javascript of war you depends on. Then you can minfy them.
If they are in a jar, you can't minify them.

War Pom.xml

Edit your project war pom.xml

Add dependencies

Add dependencies to needed war for example in gazelle-tm-war/pom.xml

        <dependency>
            <groupId>net.ihe.gazelle.maven</groupId>
            <artifactId>gazelle-seam-tools-war</artifactId>
            <type>war</type>
        </dependency>

Configure minification

add property used to timestamp minified assets files

    <properties>
        <maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
        <gazelle-assets-version>${maven.build.timestamp}</gazelle-assets-version>
        ....
    </properties>


with maven-war-plugin call exploded goal while prepare-package phase to ensure all assets from dependencies are in the target folder.
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>exploded</goal>
                        </goals>
                    </execution>
                </executions>
                ....
            </plugin>

Configure minify-maven-plugin

<plugin>
   <groupId>com.samaxes.maven</groupId>
   <artifactId>minify-maven-plugin</artifactId>
   <executions>
      <execution>
         <id>default-minify</id>
         <phase>prepare-package</phase>
         <configuration>
            <charset>UTF-8</charset>
            <cssSourceDir>resources/stylesheet</cssSourceDir>
            <webappSourceDir>${project.build.directory}/${artifactId}-${version}</webappSourceDir>
            <cssSourceFiles>
               <cssSourceFile>file-1.css</cssSourceFile>
               ...
               <cssSourceFile>file-n.css</cssSourceFile>
            </cssSourceFiles>
            <cssFinalFile>rename_your_assets_file-${gazelle-assets-version}.css</cssFinalFile>
            <cssTargetDir>resources/stylesheet</cssFinalFile>
            <jsSourceDir>resources/jscript</jsSourceDir>
            <jsSourceFiles>
               <jsSourceFile>file-1.js</jsSourceFile>
               ....
               <jsSourceFile>file-n.js</jsSourceFile>
            </jsSourceFiles>
            <jsFinalFile>rename_your_assets_file-${gazelle-assets-version}.js</jsFinalFile>
            <jsTargetDir>resources/jscript</jsFinalFile>
            <jsEngine>CLOSURE</jsEngine>
         </configuration>
         <goals>
            <goal>minify</goal>
         </goals>
      </execution>
   </executions>
</plugin>


Update your template.xhtml

remove old css and javascript references

add references to minified css and javasript

<h:ouputStylesheet library="stylesheet" name="rename_your_assets_file-${gazelle-assets-version}.min.css" />
Load other css that cannot be minified
Then load javascripts
<h:outputScript library="jscript" name="rename_your_assets_file-${gazelle-assets-version}.min.js" />


What changed in Gazelle folders

Introducing gazelle-assets svn link
It's a war holding some assets, that could be shared by gazelle projects.
it has the following structure:

└── src
    └── main
        ├── resources
        └── webapp
            ├── img
            ├── resources
                ├── jscript
                ├── stylesheet

If your project uses it as a war dependency it will inherit its files.