Building Large AJAX Applications with GWT 1.4 and Google Gears

Document Sample
Building Large AJAX Applications with GWT 1.4 and Google Gears Powered By Docstoc
					Building Large AJAX Applications with GWT 1.4
             and Google Gears




                Rajeev Dayal
                Google, Inc.
Topics

 A Brief Introduction to GWT
 What’s New in GWT 1.4
 Developing Large Applications with GWT
 Using Google Gears with GWT
 Wrap Up
 Q&A
A Brief Introduction

  What is GWT?
    A set of tools for building AJAX apps in the Java language

  What makes GWT interesting?
    Write, run, test, and debug everything in Java, both client-side UI
    code and server-side business logic

  Isn’t that called an applet?
    No JVM required; GWT converts your working Java application into
    an equivalent pure JavaScript application

  So, GWT is a compiler?
    GWT’s Java-to-JavaScript compiler is a big part of it, but there’s
    really a lot more to the story than that…
A Brief Introduction

  Why bother compiling Java into JavaScript?
   JavaScript is a dynamic language – maintenance is harder.

   How many good tools are there for developing and debugging cross-platform
   JavaScript?

  Compiling? Don’t you mean translating?
   No, I really mean compiling!

   GWT’s compiler performs dead code elimination, type tightening, method call
   inlining, and string interning.

   These optimizations are only possible when compiling from a strongly-typed
   language.

  But why Java?
   Strongly-typed language + tons of developer tools = Java
A Brief Introduction

  How do I create a user interface?
   GWT has a widget library. You can create widgets, add them to
   panels.

   The widgets work consistently across all browsers.

   Widgets publish events which can be subscribed to. When the event
   occurs, all of the subscribers will be notified.

   A code example speaks 1000 words…
A Simple UI Example
 HorizontalPanel userNamePanel = new HorizontalPanel();
 userNamePanel.setSpacing(5);
 userNamePanel.add(new Label(“Username:”));
 final TextBox userName = new TextBox();
 userNamePanel.add(userName);

 Button checkUserNameButton = new Button(“Check Username”);
 checkUserNameButton.addClickListener(new ClickListener() {

   public void onClick(Widget sender) {
       if (“rajeev”.equals(userName.getText())) {
         Window.alert(“I like that username!”);
       } else {
         Window.alert(“You need to try again.”);
       }
   }
 });

 VerticalPanel mainPanel = new VerticalPanel();
 mainPanel.add(userNamePanel);
 mainPanel.add(checkUserNameButton);

 RootPanel.get().add(mainPanel);
A Brief Introduction

  How do GWT applications communicate with a server?
   Applications make Remote Procedure Calls (RPCs) to the server.

   Java objects are serialized and sent back and forth between the
   client and the server.

   A callback object passed in to the RPC call by the client is invoked
   once the RPC call has completed.

   Another code example..
A Simple RPC Example

 RPC Method
  public String getProfileData(String userName);

 Asynchronous RPC Method
  public void getProfileData(String userName,
                             AsyncCallback cb);

 Client invocation
  getProfileData(“rajeev”, new AsyncCallback() {

     public void onSuccess(Object result) {
       Profile profile = (Profile) result;
       …
     }

    public void onFailure(Throwable ex) {
      …
    }
  });
A Brief Introduction

  But I’m already using another framework…
   No problem! GWT was not designed as an all-or-nothing solution.
   You can incorporate GWT into any existing HTML page.

   Existing HTML page with placeholder div:
     <HTML>
     ..
     <script src=“myGwtModule.nocache.js”>
     <body>
        ……
        <div id=“slickdiv”>
        </div>
        …
   GWT Code:
     Image imageWidget = new Image(“myface.gif”);
     RootPanel.get(“slickdiv”).add(imageWidget);
Topics

 A Brief Introduction to GWT
 What’s New in GWT 1.4
 Developing Large Applications with GWT
 Using Google Gears with GWT
 Wrap Up
 Q&A
New Widgets in GWT 1.4

 Rich Text Editor
  Amazingly, it works on IE, Mozilla, Safari, WebKit, and Opera 9+

 SuggestBox
  Suggestions can also be retrieved from a server via RPC

 Splitters
  We didn’t take the easy way out! The splitter bar moves AS the
  mouse is dragged, not after the mouse click is released.

  This is one of the fastest splitter implementations that we’ve seen. It
  took many hours of pain to make this work cross-browser.

 Other Cool Additions
  PushButton, ToggleButton, DisclosurePanel
ImageBundles

 What is an ImageBundle?
  ImageBundles combine all of your application’s images into a single large
  image. Each individual image becomes a viewport over the larger, composite
  image.

 What are the benefits of using ImageBundles?
  Instead of making N HTTP requests for N small images, make a single HTTP
  request for a large image.

  In general, large numbers of HTTP requests have a greater effect on
  application speed than transferring more data with fewer connections.

  Composite image file name based on content hash  perfect caching

  Bouncy-startup effect is eliminated
ImageBundle Usage Example

 Defining an Image Bundle
  public interface IconImageBundle extends ImageBundle {

      public AbstractImagePrototype new_file_icon();

      /**
       * @gwt.resource open_file_icon.gif
       */
      public AbstractImagePrototype openFileIcon();
  }

 Client code
  IconImageBundle ib =
      (IconImageBundle)(GWT.create(IconImageBundle.class));
  panel.add(ib.new_file_icon().createImage());
ImageBundles

 Integration with GWT
  Introduction of AbstractImagePrototypes – these are flyweights which
  contain the necessary information to generate an Image widget. They
  are lightweight because no DOM object is created until createImage()
  is called.

  The Image widget now supports clipping.

  Dead-code elimination for free! The compiler will eliminate images
  from the bundle which are never used.

  Image bundle composition for free! Interface inheritance allows for
  the composition of multiple bundles into a larger bundle (more on this
  later).
Optimizations in GWT 1.4
Optimizations in GWT 1.4
Optimizations in GWT 1.4
Optimizations in GWT 1.4
Further Additions to GWT 1.4

 Library Enhancements
   Internationalized number, date, and time formatting

   Serializable classes can extend java.io.Serializable instead of
   IsSerializable

   Improvements for manipulating CSS class names for widgets

 Benchmarking Subsystem
 300+ bug fixes
 Out of Beta!!! ( tell your C[EOTI]O )
 Even more stuff that I’m forgetting..
Topics

 A Brief Introduction to GWT
 What’s New in GWT 1.4
 Developing Large Applications with GWT
 Using Google Gears with GWT
 Wrap Up
 Q&A
Some Examples of Large Applications

 ContactOffice
 •   Collaborative & Messaging Web Application
 •   http://www.contactoffice.com/
 •   600 classes, 300 files, 46000 lines of code
 •   1 million registrations
 •   250,000 Paying Accounts

 QuePlix
 •   Customer Relationship Management (CRM) Application
 •   http://www.queplix.com/solutions/queweb-customer-care/
 •   Open source! - http://code.google.com/p/queplix/
 •   Used by Fortune 500 Companies

 Lombardi BluePrint
 •   Business Process Management (BPM) Application
 •   http://blueprint.lombardi.com
 •   ~2000 Users
 •   Regularly Used by Fortune 10 CEOs
Techniques for Building Large Applications

 These are large, sophisticated web applications
 And they were all built with GWT!


 So, if I use GWT, will I be able to build a large, sophisticated
 application as well?
 Yes, but using GWT alone is not enough – you have to make
 smart engineering decisions that leverage the power of
 GWT


 Let’s discuss a few of those…
Good Object-Oriented Design

 Use a Data Model
   A data model makes it easy to provide different views of data from the server

   Data retrieved from the server can be cached by the model

   Pre-fetching: Even if the view only needs 1 record, fetch the next 5 if they are
   likely to be accessed in the near future

 Communication Between the View and Model
       public class BookmarkView implements BookmarkModelUpdateHandler
       {
           …
         public void onBookmarkModelUpdate(BookmarkModelEvent event) {
             Bookmark bookmark = event.getBookmark();
             // update the view with the new bookmark
         }
       }
       …
       bookmarkDataModel.addUpdateListener(bookmarkView);
Good Object-Oriented Design

 How does the view communicate with the model?
   Command-Piggyback Pattern
     final Bookmark bookmark = new Bookmark(folder);
     bookmark.saveBookmark(new Command() {
       public void execute() {
         // access the view and update it with the
         // bookmark object
       }
     });


   The saveBookmark(Command) call makes an RPC call to the server

   When the results of the call return, the Command is executed

   This pattern is more direct and cleaner than the observer pattern,
   provided that there is only one listener for model updates
Good Object-Oriented Design

 Build a Widget Hierarchy that Maps to the Application’s
 Interface
   A well-designed application-specific widget hierarchy promotes reuse
   of UI components (and code)

   Snowball effect – as the application’s base widgets are created, the
   rest of the application’s UI falls out quickly as compositions of the
   base widgets.

 Reuse of Business Logic
   Clients will usually have a simplified version of the business logic that
   is used on the server

   If the server and client are both using Java, common business logic
   code can be used on both the client and server
Be Lazy

 Initialize UI components only when needed
  We want users to have the shortest possible response time

  There is no point in creating widgets that the user cannot interact with

 Cache results of expensive operations
  If a particular UI component takes a long time to create, keep a
  reference to it

  Repeated DOM calls can become expensive. If a DOM value is read
  often, use a variable to mirror its value

 UI interaction should be independent of network speed
  Calls to the server should be asynchronous

  What if a server response is required before proceeding?
Use ImageBundles

 Compose images required by GWT widgets into your bundle
  GWT’s Tree widget has images for the +/- symbols, and they are
  contained in the TreeImages bundle.

  A separate request is made to retrieve the TreeImages composite
  image. You can get rid of this request by composing this bundle into
  your application’s bundle:
    public void MyImageBundle extends IconImageBundle,
                                      PhotoImageBundle,
                                      TreeImages {
    }
    …
    MyImageBundle myImageBundle =
       (MyImageBundle)(GWT.create(TreeImages.class));

    Tree myTree = new Tree(myImageBundle);
Caching and Compression

 The fastest network trip is the one never made..
  *.cache.* files should be cached forever (or a year in the future)

  *.nocache.* files should not be cached at all

  If using HTTPS or web application security constraints, caching will
  be disabled by default (important for ImageBundles)!

 Compression
  Ensure that your server is gzipping its responses!
Topics

 A Brief Introduction to GWT
 What’s New in GWT 1.4
 Developing Large Applications with GWT
 Using Google Gears with GWT
 Wrap Up
 Q&A
An Introduction to Google Gears

 What is Google Gears?
   A browser extension that lets developers create applications that can
   run offline

 Why do we need Google Gears?
   There is no way to access web applications when users are offline

   Web applications can still be useful when there is no connectivity

   Users should be able to manipulate application data when offline.
   Syncs with the server can be done when a connection is available.

 How does it work?
   Need to persist application’s files and data on the client side..
Main Components of Gears

 LocalServer
  A local file cache that stores the application’s resources (HTML, JS,
  CSS, etc)

  Requests for URLs that are contained in the cache will be served up
  from disk instead of the web

 Database
  A local relational database for storing data

  SQL is used to interact with the database
Application Architecture with Gears

 So, Gears makes my application work offline?
   Not exactly. Gears provides the necessary client-side components so
   that web applications can work offline

   You still have to modify your implementation in order to take
   advantage of the Gears components

   Your implementation will become more complex
   (similarities to multi-threading an application)

 Architectural Decisions Need to Be Made
   Are there distinct offline/online modes, or is the application
   modeless?

   Is synchronization with the server done in the background, or is it
   user-initiated?
Gears API - ManagedResourceStore

 Use a ManagedResourceStore to cache a set of resources

   LocalServer localServer = new LocalServer();

   ManagedResourceStore store =
      localserver.createManagedResourceStore(“GWTGearsNote”);

   store.setManifestURL(GWT.getModuleBaseURL() + “manifest”);
Gears API – Manifest Files

 Resources are defined in manifest file:
   {
       "betaManifestVersion": 1,
       "version": "v1",
       "entries": [
         { "url": “GWTNote.html“ },
         { “url": “com.mypackage.GWTNote.nocache.js“ },
         { “url”: “gears_init.js” },
         { “url”: “EDFF0C9452BE9F101E310631DE49CC0A.cache.html” },
         { “url”: “ADFF0C9452BE9F101E310631DE49CC0A.cache.html” },
          …
         { “url”: “clear.cache.gif” },
         { “url”: “LDFF0C9452BE9F101E310631DE49CC0A.cache.png” } ]
   }
Gears API – Manifest Files

 Gears automatically checks for updates to the manifest file
 If the version string in the manifest file is changed, then the
 resources listed in the file are re-requested
 Current issue with GWT:
   Users have to list all GWT-specific resources in manifest file
   (history.html, clear.cache.gif, X.nocache.js, etc..)

   Strongly-named resources must be listed as well (image bundle
   filenames, browser-specific *.cache.html files)

   This is a big problem because the client has to download all browser
   permutations

   Currently working on a fix which will auto-generate the manifest file.
   A URL-specific cache (LocalResourceStore) will be used to cache
   the browser-specific *.cache.html for the user’s browser.
Gears API - Database

 Accessing database at start of application:
   Database db = new Database();

   try {

       db.execute(“select noteid from notes”);

   } catch (GearsException ex) {

       db.execute(“create table notes (“
            + “noteid text not null primary key,”
            + “version text not null,”
            + “content text not null”
            + “)” );
   }
Gears API - Database

 Retrieving and Iterating over a ResultSet:

  ResultSet rs =
    db.execute(“SELECT * FROM notes WHERE content MATCH ?”,
            new String [] {keyword});

  while (rs.isValidRow()) {

      Note nd = new Note(rs.getFieldAsString(0),
               rs.getFieldAsString(1),
               rs.getFieldAsString(2));
      …
      rs.next();
  }
The Gist of the Synchronization Code
 // run this method on a timer that executes every x milliseconds,
 // forever
 void update() {
   List currentNotes = getUserNotes();
   syncToServer(currentNotes,
                 new AsyncCallback() {
                   public void onSuccess(Object result) {
                     // this method retrieves the updated notes
                     // the server and updates the local database
                     // if a note was changed locally by the user
                     // and also on the server, the user is
                     // informed
                     syncFromServer();
                   }

                  public void onFailure(Throwable ex) {
                    if (!(ex instanceof InvocationException)) {
                      …
                    } else {
                      // network not available, do nothing
                    }
                 }
               });
 }
Other Cool Stuff

 Caching on a per-URL basis using ResourceStore
 Full-text searches in database using fts2
 Parallel Computation using WorkerPools
   Run operations in background; UI thread is not blocked

   Workers do not share any execution state. They communicate by message
   passing.

   Gears library for GWT partially supports WorkerPools. Workers can be
   created and executed, but the code they execute is passed in as a
   JavaScript string. We’re currently working on full support for WorkerPools.

 By using Gears via GWT, you get the advantages that GWT brings
 to the table
   Compiler optimizations, static type checking, debugging, refactoring, …
Summary

 • GWT makes it possible to apply software engineering practices
   to AJAX development

 • The improvements and new additions to GWT 1.4 show that
   we’re committed to providing a toolkit that will deliver the best
   possible end-user experience

 • Developers can build large, sophisticated web applications
   using GWT and good software engineering practices

 • Google Gears API for GWT combines the advantages of using
   GWT with the power of Google Gears

 • Interoperability with other APIs is important to us. Libraries for
   Google Maps and GData are coming soon.
Resources

 Get GWT!
 http://code.google.com/webtoolkit/

 Interested in Contributing to GWT?
 http://code.google.com/p/google-web-toolkit/

 Get Gears!
 http://gears.google.com/
 Google API Library for GWT
 http://code.google.com/p/gwt-google-apis/

 Bleeding-Edge GWT Ideas
 http://code.google.com/p/google-web-toolkit-incubator/

 Questions that You’ll Remember Later?
 E-mail me: rdayal@google.com

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:7
posted:12/3/2011
language:English
pages:41