Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GWT Html file with CSS

Tags:

css

inline

gwt

When I'm creating new project with GWT plug in it creates a skeleton project for me. In html file there is a comment saying "Consider inlining CSS to reduce the number of requested files" Why would i consider using inline css? I tough having css in separate file not inline reduces size of my file? isn't it true?

like image 990
Maksim Avatar asked Jun 30 '09 21:06

Maksim


2 Answers

The answer lies in the way that GWT operates. Since GWT only has one page load per module load the inlined caching doesn't really come into play.

If you just want the answer: inlined CSS reduces the number of TCP/IP connections that are needed to load all of the files that compose your project. This can be non-trivial given that you may have multiple CSS files, high latency, and other network conditions. In my line of work (state government) you aren't always guaranteed a "fat pipe".

GWT (or at least the gwt-incubator) has a mechanism for combining the optimization of inline CSS with the separation of information and layout.

Enter the ImmutableResources and StyleInjector. These two things (combined) lead to a way to load Immutable (after compile time) resources.

To use these, first download the gwt-incubator. Then add the required libraries to your module.gwt.xml

<!-- immutable resources and injecting styles -->
<inherits name="com.google.gwt.libideas.ImmutableResources" />
<inherits name="com.google.gwt.libideas.StyleInjector" />

Once that is done, create the CSS files as code resources. I keep mine in the source path like "org.project.client.resources.*". You can keep these in seperate segments such as: header.css, body.css, table.css. Go crazy, really keep things as seperate as you want. Your file path should look something like "/src/org/project/client/resources/header.css".

Now, to create the CSS interface. Now, there are some rather special things you can do with this look here. But I've just gone with the basic one.

import com.google.gwt.libideas.resources.client.CssResource;

public interface Css extends CssResource {

}

Now that you have your CssResource class (and you can have different ones) you need to create an immutable resource bundle that wraps up all of your CSS files.

import com.google.gwt.core.client.GWT;
import com.google.gwt.libideas.resources.client.ImmutableResourceBundle;

public interface ResourceBundle extends ImmutableResourceBundle {

    public static final ResourceBundle INSTANCE = GWT.create(ResourceBundle.class);

    /*
     * =============================
     * CSS
     * =============================
     */

        @Resource("org/project/client/resources/header.css")
        public Css headerCss();

        @Resource("org/project/client/resources/body.css")
        public Css bodyCss();
}

This will, at compile time, create links to the immutable CSS resources. Now we need to put (insert) those CSS resources into the module somehow. This is where the StyleInjector comes in.

I put code similar to the following into my entry point's "onModuleLoad" method.

StyleInjector.injectStylesheet(ResourceBundle.INSTANCE.headerCss().getText());
StyleInjector.injectStylesheet(ResourceBundle.INSTANCE.bodyCss().getText());

There may be other ways to accomplish the same effect in GWT but the power of the CssResource can be leveraged for more things than what I've gone over here. For example: in one of my projects I need a small change in CSS to get IE and Firefox to render what I consider to be corretly. I have two small browser specific sections in my global.css like so:

/* fix ie floating quirk */
@if user.agent ie6 ie7 ie8 {
    #someElement {
        top: -21px;
        right: 5px;
    }
}

/* fix firefox floating quirk */
@if user.agent ff gecko mozilla firefox Gecko Mozilla moz gecko1_8 {
    #someElement {
        top: -14px;
    }
}

Being able to leave this logic out of my JavaScript/Java is beautiful. There's also a small optimization here because GWT will only do the injection for the browsers that need it. (Deferred binding based on browser is how a lot of things in GWT work.)

So, the mechanism that provides inline CSS also provides other benefits while maintaining the separation of CSS.

Whats not to love?

like image 71
Chris Ruffalo Avatar answered Sep 20 '22 08:09

Chris Ruffalo


Basically, it takes time to open up a TCP connection and request the file, so it can reduce the amount of time that it takes to load all of the files for a page.

Also, if you are going to load that file anyway, in the end it will be the same amount of bandwidth. It is better to have a reduced time for transfer than a reduced filesize.

like image 27
Thomas Avatar answered Sep 19 '22 08:09

Thomas