Google Web Toolkit
             Building Web Apps Sanely

Chris Ramsdale
Developer Relations, Google
Between us and lunch


• Overview
• Deeper dive
• Optimizations for developers
• Optimizations for users
• Intro to GWT & MVP
From 25,000 feet


• Development toolkit, not a framework
• Code in Java, run as Javascript
• One codebase, any browser
• Makes Ajax a piece of cake...and faster
• Used within many Google products, including
  Google Wave and Ad Words
The GWT Family




   GWT SDK   Google Plugin   Speed Tracer
              For Eclipse
It’s a loving relationship
It’s a loving relationship




             Develop
It’s a loving relationship




             Develop         Debug
It’s a loving relationship




             Develop              Debug




                       Optimize
Focus on the users


Our users - developers
 • Leverage existing IDEs and tools
 • Minimize refresh time between codes changes
 • Automate where possible

Your users - customers
 • Minimize startup time
 • Make it a comfortable experience
 • Allow them to select the browser
Different Goals
Different Goals


Developers
 • Next killer feature
 • Making it look good
 • Code refactoring
Different Goals


Developers               Customers
 • Next killer feature   • Make it fast
 • Making it look good   • ...oh, and don’t charge
                         my credit card twice
 • Code refactoring
Different Goals


Developers               Customers
 • Next killer feature   • Make it fast
 • Making it look good   • ...oh, and don’t charge
                         my credit card twice
 • Code refactoring
No plugins required

                    Silverlight
     VML    Flash
Nothing against them, but...



        Foo Player not available for
        your device


        We restrict use of
        technologies required by
        products like Foo Player...
Quirkiness



                       Firefox   Webkit (Safari) Opera    IE
    Typical portable   2876 ms   1276 ms        2053 ms   4078 ms
    setInnerText()
    textContent=... -            908 ms         1386 ms   -
    innerText=...      2477 ms   918 ms         1520 ms   2469 ms
    DOM manipulation 7148 ms     1997 ms        4836 ms   14800 ms
Quirkiness



                       Firefox   Webkit (Safari) Opera    IE
    Typical portable   2876 ms   1276 ms        2053 ms   4078 ms
    setInnerText()
    textContent=... -            908 ms         1386 ms   -
    innerText=...      2477 ms   918 ms         1520 ms   2469 ms
    DOM manipulation 7148 ms     1997 ms        4836 ms   14800 ms


    Improvement        14%       29%            32%       39%
Quirkiness



                       Firefox   Webkit (Safari) Opera    IE
    Typical portable   2876 ms   1276 ms        2053 ms   4078 ms
    setInnerText()
    textContent=... -            908 ms         1386 ms   -
    innerText=...      2477 ms   918 ms         1520 ms   2469 ms
    DOM manipulation 7148 ms     1997 ms        4836 ms   14800 ms


    Improvement        14%       29%            32%       39%




    http://quirksmode.org/blog/
Can you find the bug?

 function getMax(values) {
 	
 	    var maximum = values[0];
 	
 	    for (var i = 0; i < values.length; ++i) {
 	    	     if (values[i] > maximum) {
 	    	     	    maxinum = values[i];
 	    	     }
       }
       return maximum;
 }
Can you find the bug?

 function getMax(values) {
 	
 	    var maximum = values[0];
 	
 	    for (var i = 0; i < values.length; ++i) {
 	    	     if (values[i] > maximum) {
 	    	     	    maxinum = values[i];
 	    	     }
       }
       return maximum;
 }

 Hint: Javascript is a dynamic language
Our plugin can




 Java is a static language
A Java to Javascript compiler right?




                 13
More like assembly-level JS
function rd(a,b){var c;if(b.b){b.b=false;b.c=null}c=b.c;b.c=a.f;try{++a.c;Cd(a.e,b,a.d)}finally{--
a.c;a.c==0&&sd(a)}if(c==null){b.b=true;b.c=null}else{b.c=c}}
function Hb(b,c){yb();$wnd.setTimeout(function(){var a=$entry(Eb)(b);a&&$wnd.setTimeout(arguments.callee,c)},c)}
function ih(a,b){var c,d;if(b.e!=a){return false}try{Vg(b,null)}finally{c=b.f;(d=(hc(),c).parentNode,(!d||d.nodeType!
=1)&&(d=null),d).removeChild(c);ki(a.b,b)}return true}
function hj(c){if(c.length==0||c[0]>ao&&c[c.length-1]>ao){return c}var a=c.replace(/^(s*)/,cn);var b=a.replace(/s*
$/,cn);return b}
function qj(a){var b,c,d,e;b=0;d=a.length;e=d-4;c=0;while(c<e){b=a.charCodeAt(c+3)+31*(a.charCodeAt(c
+2)+31*(a.charCodeAt(c+1)+31*(a.charCodeAt(c)+31*b)))|0;c+=4}while(c<d){b=b*31+a.charCodeAt(c++)}return b|0}
function Bj(a){var b,c,d,e;e=this.v();a.length<e&&(a=Pd(a,e));d=a;c=this.p();for(b=0;b<e;++b)
{Ud(d,b,c.s())}a.length>e&&Ud(a,e,null);return a}
function xl(a){var b,c,d;a.length<this.c&&(a=(c=a,d=Qd(0,this.c),Sd(c.aC,c.tI,c.qI,d),d));for(b=0;b<this.c;++b)
{Ud(a,b,this.b[b])}a.length>this.c&&Ud(a,this.c,null);return a}
function Ud(a,b,c){if(c!=null){if(a.qI>0&&!ee(c.tI,a.qI)){throw wi(new ui)}if(a.qI<0&&(c.tM==gm||c.tI==2)){throw
wi(new ui)}}return a[b]=c}
function hi(a,b,c){var d,e;if(c<0||c>a.c){throw Qi(new Oi)}if(a.c==a.b.length){e=Rd(we,
47,8,a.b.length*2,0);for(d=0;d<a.b.length;++d){Ud(e,d,a.b[d])}a.b=e}++a.c;for(d=a.c-1;d>c;--d)
{Ud(a.b,d,a.b[d-1])}Ud(a.b,c,b)}
function th(b,c){var i;rh();var a,e,f,g,h;e=null;for(h=b.p();h.r();){g=fe(h.s(),8);try{c.q(g)}catch(a)
{a=Ge(a);if(ie(a,11)){f=a;!e&&(e=Fl(new Dl));i=Sj(e.b,f,e)}else throw a}}if(e){throw sh(new oh,e)}}
function Tj(j,a,b,c){var d=j.b[c];if(d){for(var e=0,f=d.length;e<f;++e){var g=d[e];var h=g.y();if(j.x(a,h)){var
i=g.z();g.A(b);return i}}}else{d=j.b[c]=[]}var g=Ul(new Sl,a,b);d.push(g);++j.e;return null}
function bk(a){var b,c,d;if((a==null?null:a)===this){return true}if(!(a!=null&&de(a.tI,18))){return false}c=fe(a,
18);if(c.v()!=this.v()){return false}for(b=c.p();b.r();){d=b.s();if(!this.u(d)){return false}}return true}
function Cd(a,b,c){var d,e,f,g,h,i,j;g=b.j();d=(h=fe(Nj(a.b,g),4),!h?0:h.c);if(c){for(f=d-1;f>=0;--f)
{e=(i=fe(Nj(a.b,g),4),fe((Nk(f,i.c),i.b[f]),13));b.i(e)}}else{for(f=0;f<d;++f){e=(j=fe(Nj(a.b,g),
4),fe((Nk(f,j.c),j.b[f]),13));b.i(e)}}}
function Fb(a){var b,c,d,e,f,g;b=false;d=a.length;f=(new Date).getTime();while((new Date).getTime()-f<100)
{for(c=0;c<d;++c){g=a[c];if(!g){continue}if(!g[0].h()){a[c]=null;b=true}}}if(b){e=[];for(c=0;c<d;++c){if(!a[c])
{continue}e[e.length]=a[c]}return e}else{return a}}
function cf()
{cf=gm;af={};bf=[];af[pn]=[lg,kg,mg];af[qn]=[tg,sg];af[rn]=[xg,wg];af[sn]=[Bg,Ag,Cg];_e(bf,se,pn);_e(bf,te,qn);_e(bf,u
e,rn);_e(bf,ve,sn)}                                       14
I can haz pretty print plz




                             Simply adjust
                             the output
                             style of the
                             compiler via
                             the plugin




                       15
Yes, a Java to Javascript compiler
function init(){
  $GreetingService_Proxy(new GreetingService_Proxy);
  $add_0(($clinit_99() , get_0(null)), $Label(new Label, 'Foo'));
  $wnd.alert('foo');
}

function caught_0(e){
  if (e != null && canCast(e.typeId$, 11)) {
    return e;
  }
  return $JavaScriptException(new JavaScriptException, e);
}

function $RemoteServiceProxy(this$static){
  return this$static;
}

function RemoteServiceProxy(){
}                                 16
But wait...thereʼs more




           17
Don’t take my word for it




   Juan Carlos Campos Martínez
            Developer - GWT User




                     18
A deeper dive




19
From Eclipse to your browser



 Eclipse




                                                                     Browser Plugins
 package com.google.gwt.samples.eclipsecon.client;



                                                              TCP
 import com.google.gwt.core.client.EntryPoint;
 import com.google.gwt.core.client.GWT;

 @SuppressWarnings("unused")
                                                     Code
 public class EclipseCon implements EntryPoint {
                                                     Server
     public void onModuleLoad() {
       Window.alert("foo");
     }


                                                              HTTP
 }


                                                      Jetty
                                                     Server




                                                        20
From Eclipse to deployment




Your code...                                        Generators   Translators   Linkers
package com.google.gwt.samples.eclipsecon.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;

@SuppressWarnings("unused")
public class EclipseCon implements EntryPoint {

    public void onModuleLoad() {
      Window.alert("foo");
    }
}




                                                         21
From Eclipse to deployment




Your code...                                        Generators   Translators   Linkers
package com.google.gwt.samples.eclipsecon.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;

@SuppressWarnings("unused")
public class EclipseCon implements EntryPoint {

    public void onModuleLoad() {
      Window.alert("foo");
    }
}




                                                         22
Generators   Provide the power behind your
             GWT app

             Automate away boilerplate code

             Foundation for permutations




             23
Use Case: GWT RPCs


Typical Ajax call


            Serialization         Serialization
               Code                  Code
   Client                   XHR                   Server




                            24
Use Case: GWT RPCs


GWT-enabled Ajax


                      Serialization         Serialization
          GWT Proxy




                                                            GWT Proxy
                         Code                  Code
 Client                               XHR                               Server




                                      25
Use Case: GWT RPCs


Goals:
 • Serialization code begone
 • RPCs like theyʼre meant to be -
   interface methods

 • Make it fast to boot


                     26
Use Case: GWT RPCs



You write code that looks like this:
@RemoteServiceRelativePath("suggest")
public interface SuggestService extends RemoteService {
  String getSuggestions(String str) throws IllegalArgumentException;
}




                                   27
Simple enough.




      28
He’s an Ajax pro




                   29
From Eclipse to your browser




Your code...                                        Generators   Translators   Linkers
package com.google.gwt.samples.eclipsecon.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;

@SuppressWarnings("unused")
public class EclipseCon implements EntryPoint {

    public void onModuleLoad() {
      Window.alert("foo");
    }
}




                                                         30
Java



        Javascript




   31
From Eclipse to your browser




Your code...                                        Generators   Translators   Linkers
package com.google.gwt.samples.eclipsecon.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;

@SuppressWarnings("unused")
public class EclipseCon implements EntryPoint {

    public void onModuleLoad() {
      Window.alert("foo");
    }
}




                                                         32
Entry points for your GWT app
                       33
GWT Tips and Tricks




   -gen will output a copy of the
        generated classes



                      34
GWT Tips and Tricks


Reduce optimizations, reduce compile time

 -draftCompile
 • Skip all optimizations
 • Development only
GWT Tips and Tricks


Reduce optimizations, reduce compile time

 -draftCompile
 • Skip all optimizations
 • Development only

   Why worry about compiling at all?
A more efficient SDLC




Refresh        Does it work?   Yes   Compile

                    No


          Develop                    Deploy
We’re happy




37
But what about
 our users?




                 38
Optimize for the user


• Bundle resources
• Split code
Resource Bundling


• Example - associating icons with a contact
Resource Bundling


One at a time
Image image = new Image("images/image1.gif");
image.setHeight("50px");
image.setWidth("50px");
imagesPanel.add(image);
Resource Bundling


Initial download


Call to display images
Resource Bundling


All at once
public interface Resources extends ClientBundle {
  public static final Resources INSTANCE = GWT.create(Resources.class);

    @Source("Contacts.css")
    public ContactsCss contactsCss();

    @Source("images0.gif")
    public ImageResource image0();

    @Source("images1.gif")
    public ImageResource image1();

    ...

}
Resource Bundling


Initial download


Call to display images
Code splitting


Initial download



            Not needed on startup
Code splitting


Split points - runAsync()
@UiHandler("showImagesButton")
void onOkClicked(ClickEvent event) {
  GWT.runAsync(new RunAsyncCallback() {
    public void onSuccess() {
      showImagesDialog();
    }
  });
}
Code splitting


Initial download


Call to display images
Real world results - Google Wave
                                           1500
                                                                                                                 1400 KB
Size of Initial JavaScript Download (KB)




                                           1125




                                            750

                                                                             7x Decrease In
                                                                             Initial Download Size

                                            375




                                                                                                                 200 KB


                                              0
                                                  26-Nov   29-Apr   18-Jun   28-Jul   12-Sep   27-Oct   24-Dec   16-Mar
Creating GWT apps - “Direct” approach


Write a bunch of widgets with self-contained
logic
Problems:
 •   Hard to test - need GWTTestCase
 •   Mocks not encouraged - harder to write smaller tests
 •   Platform specific UI code - limits code reuse
 •   Too many dependencies - difficult to optimize
Creating GWT apps - MVP approach


 Cast:
 • Model - DTOs, and business logic
 • View - The display
 • Presenter - Application logic

 Goals:
 •   Be practical
 •   Avoid rigid patterns
 •   Put the complex logic in your Presenters
 •   Put the widget code in your Views
 •   Make the Views as dumb as possible
MVC
MVP
MVP
The MVP Relationship




         Model         Presenter   View
The MVP Relationship




         Model         Presenter   View
The MVP Relationship




         Model   History   Presenter   View
The MVP Relationship
   RPC




         Model   History   Presenter   View
The MVP Relationship

         Cache
   RPC




                 Model   History   Presenter   View
The MVP Relationship

         Cache
   RPC




                 Model   History      Presenter   View




                          Event Bus
The MVP Relationship

         Cache
   RPC




                 Model   History      Presenter   View




                          Event Bus
The MVP Relationship

         Cache
   RPC




                 Model   History      Presenter   View




                          Event Bus
Making the Cloud a Reality
Making the Cloud a Reality


               Contacts
      Email
                    Sales Force Automation
Calendar

      Your next big idea
  Banking                    Collaboration
              Social Network
Making the Cloud a Reality
Making the Cloud a Reality




  The right languages and tools
              are key
</presentation>


Chris Ramsdale
cramsdale@google.com
Twitter: @cramsdale
http://googlewebtoolkit.blogspot.com/

Google Developer Fest 2010

  • 1.
    Google Web Toolkit Building Web Apps Sanely Chris Ramsdale Developer Relations, Google
  • 2.
    Between us andlunch • Overview • Deeper dive • Optimizations for developers • Optimizations for users • Intro to GWT & MVP
  • 3.
    From 25,000 feet •Development toolkit, not a framework • Code in Java, run as Javascript • One codebase, any browser • Makes Ajax a piece of cake...and faster • Used within many Google products, including Google Wave and Ad Words
  • 4.
    The GWT Family GWT SDK Google Plugin Speed Tracer For Eclipse
  • 5.
    It’s a lovingrelationship
  • 6.
    It’s a lovingrelationship Develop
  • 7.
    It’s a lovingrelationship Develop Debug
  • 8.
    It’s a lovingrelationship Develop Debug Optimize
  • 9.
    Focus on theusers Our users - developers • Leverage existing IDEs and tools • Minimize refresh time between codes changes • Automate where possible Your users - customers • Minimize startup time • Make it a comfortable experience • Allow them to select the browser
  • 10.
  • 11.
    Different Goals Developers •Next killer feature • Making it look good • Code refactoring
  • 12.
    Different Goals Developers Customers • Next killer feature • Make it fast • Making it look good • ...oh, and don’t charge my credit card twice • Code refactoring
  • 13.
    Different Goals Developers Customers • Next killer feature • Make it fast • Making it look good • ...oh, and don’t charge my credit card twice • Code refactoring
  • 14.
    No plugins required Silverlight VML Flash
  • 15.
    Nothing against them,but... Foo Player not available for your device We restrict use of technologies required by products like Foo Player...
  • 16.
    Quirkiness Firefox Webkit (Safari) Opera IE Typical portable 2876 ms 1276 ms 2053 ms 4078 ms setInnerText() textContent=... - 908 ms 1386 ms - innerText=... 2477 ms 918 ms 1520 ms 2469 ms DOM manipulation 7148 ms 1997 ms 4836 ms 14800 ms
  • 17.
    Quirkiness Firefox Webkit (Safari) Opera IE Typical portable 2876 ms 1276 ms 2053 ms 4078 ms setInnerText() textContent=... - 908 ms 1386 ms - innerText=... 2477 ms 918 ms 1520 ms 2469 ms DOM manipulation 7148 ms 1997 ms 4836 ms 14800 ms Improvement 14% 29% 32% 39%
  • 18.
    Quirkiness Firefox Webkit (Safari) Opera IE Typical portable 2876 ms 1276 ms 2053 ms 4078 ms setInnerText() textContent=... - 908 ms 1386 ms - innerText=... 2477 ms 918 ms 1520 ms 2469 ms DOM manipulation 7148 ms 1997 ms 4836 ms 14800 ms Improvement 14% 29% 32% 39% http://quirksmode.org/blog/
  • 19.
    Can you findthe bug? function getMax(values) { var maximum = values[0]; for (var i = 0; i < values.length; ++i) { if (values[i] > maximum) { maxinum = values[i]; } } return maximum; }
  • 20.
    Can you findthe bug? function getMax(values) { var maximum = values[0]; for (var i = 0; i < values.length; ++i) { if (values[i] > maximum) { maxinum = values[i]; } } return maximum; } Hint: Javascript is a dynamic language
  • 21.
    Our plugin can Java is a static language
  • 22.
    A Java toJavascript compiler right? 13
  • 23.
    More like assembly-levelJS function rd(a,b){var c;if(b.b){b.b=false;b.c=null}c=b.c;b.c=a.f;try{++a.c;Cd(a.e,b,a.d)}finally{-- a.c;a.c==0&&sd(a)}if(c==null){b.b=true;b.c=null}else{b.c=c}} function Hb(b,c){yb();$wnd.setTimeout(function(){var a=$entry(Eb)(b);a&&$wnd.setTimeout(arguments.callee,c)},c)} function ih(a,b){var c,d;if(b.e!=a){return false}try{Vg(b,null)}finally{c=b.f;(d=(hc(),c).parentNode,(!d||d.nodeType! =1)&&(d=null),d).removeChild(c);ki(a.b,b)}return true} function hj(c){if(c.length==0||c[0]>ao&&c[c.length-1]>ao){return c}var a=c.replace(/^(s*)/,cn);var b=a.replace(/s* $/,cn);return b} function qj(a){var b,c,d,e;b=0;d=a.length;e=d-4;c=0;while(c<e){b=a.charCodeAt(c+3)+31*(a.charCodeAt(c +2)+31*(a.charCodeAt(c+1)+31*(a.charCodeAt(c)+31*b)))|0;c+=4}while(c<d){b=b*31+a.charCodeAt(c++)}return b|0} function Bj(a){var b,c,d,e;e=this.v();a.length<e&&(a=Pd(a,e));d=a;c=this.p();for(b=0;b<e;++b) {Ud(d,b,c.s())}a.length>e&&Ud(a,e,null);return a} function xl(a){var b,c,d;a.length<this.c&&(a=(c=a,d=Qd(0,this.c),Sd(c.aC,c.tI,c.qI,d),d));for(b=0;b<this.c;++b) {Ud(a,b,this.b[b])}a.length>this.c&&Ud(a,this.c,null);return a} function Ud(a,b,c){if(c!=null){if(a.qI>0&&!ee(c.tI,a.qI)){throw wi(new ui)}if(a.qI<0&&(c.tM==gm||c.tI==2)){throw wi(new ui)}}return a[b]=c} function hi(a,b,c){var d,e;if(c<0||c>a.c){throw Qi(new Oi)}if(a.c==a.b.length){e=Rd(we, 47,8,a.b.length*2,0);for(d=0;d<a.b.length;++d){Ud(e,d,a.b[d])}a.b=e}++a.c;for(d=a.c-1;d>c;--d) {Ud(a.b,d,a.b[d-1])}Ud(a.b,c,b)} function th(b,c){var i;rh();var a,e,f,g,h;e=null;for(h=b.p();h.r();){g=fe(h.s(),8);try{c.q(g)}catch(a) {a=Ge(a);if(ie(a,11)){f=a;!e&&(e=Fl(new Dl));i=Sj(e.b,f,e)}else throw a}}if(e){throw sh(new oh,e)}} function Tj(j,a,b,c){var d=j.b[c];if(d){for(var e=0,f=d.length;e<f;++e){var g=d[e];var h=g.y();if(j.x(a,h)){var i=g.z();g.A(b);return i}}}else{d=j.b[c]=[]}var g=Ul(new Sl,a,b);d.push(g);++j.e;return null} function bk(a){var b,c,d;if((a==null?null:a)===this){return true}if(!(a!=null&&de(a.tI,18))){return false}c=fe(a, 18);if(c.v()!=this.v()){return false}for(b=c.p();b.r();){d=b.s();if(!this.u(d)){return false}}return true} function Cd(a,b,c){var d,e,f,g,h,i,j;g=b.j();d=(h=fe(Nj(a.b,g),4),!h?0:h.c);if(c){for(f=d-1;f>=0;--f) {e=(i=fe(Nj(a.b,g),4),fe((Nk(f,i.c),i.b[f]),13));b.i(e)}}else{for(f=0;f<d;++f){e=(j=fe(Nj(a.b,g), 4),fe((Nk(f,j.c),j.b[f]),13));b.i(e)}}} function Fb(a){var b,c,d,e,f,g;b=false;d=a.length;f=(new Date).getTime();while((new Date).getTime()-f<100) {for(c=0;c<d;++c){g=a[c];if(!g){continue}if(!g[0].h()){a[c]=null;b=true}}}if(b){e=[];for(c=0;c<d;++c){if(!a[c]) {continue}e[e.length]=a[c]}return e}else{return a}} function cf() {cf=gm;af={};bf=[];af[pn]=[lg,kg,mg];af[qn]=[tg,sg];af[rn]=[xg,wg];af[sn]=[Bg,Ag,Cg];_e(bf,se,pn);_e(bf,te,qn);_e(bf,u e,rn);_e(bf,ve,sn)} 14
  • 24.
    I can hazpretty print plz Simply adjust the output style of the compiler via the plugin 15
  • 25.
    Yes, a Javato Javascript compiler function init(){ $GreetingService_Proxy(new GreetingService_Proxy); $add_0(($clinit_99() , get_0(null)), $Label(new Label, 'Foo')); $wnd.alert('foo'); } function caught_0(e){ if (e != null && canCast(e.typeId$, 11)) { return e; } return $JavaScriptException(new JavaScriptException, e); } function $RemoteServiceProxy(this$static){ return this$static; } function RemoteServiceProxy(){ } 16
  • 26.
  • 27.
    Don’t take myword for it Juan Carlos Campos Martínez Developer - GWT User 18
  • 28.
  • 29.
    From Eclipse toyour browser Eclipse Browser Plugins package com.google.gwt.samples.eclipsecon.client; TCP import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; @SuppressWarnings("unused") Code public class EclipseCon implements EntryPoint { Server public void onModuleLoad() { Window.alert("foo"); } HTTP } Jetty Server 20
  • 30.
    From Eclipse todeployment Your code... Generators Translators Linkers package com.google.gwt.samples.eclipsecon.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; @SuppressWarnings("unused") public class EclipseCon implements EntryPoint { public void onModuleLoad() { Window.alert("foo"); } } 21
  • 31.
    From Eclipse todeployment Your code... Generators Translators Linkers package com.google.gwt.samples.eclipsecon.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; @SuppressWarnings("unused") public class EclipseCon implements EntryPoint { public void onModuleLoad() { Window.alert("foo"); } } 22
  • 32.
    Generators Provide the power behind your GWT app Automate away boilerplate code Foundation for permutations 23
  • 33.
    Use Case: GWTRPCs Typical Ajax call Serialization Serialization Code Code Client XHR Server 24
  • 34.
    Use Case: GWTRPCs GWT-enabled Ajax Serialization Serialization GWT Proxy GWT Proxy Code Code Client XHR Server 25
  • 35.
    Use Case: GWTRPCs Goals: • Serialization code begone • RPCs like theyʼre meant to be - interface methods • Make it fast to boot 26
  • 36.
    Use Case: GWTRPCs You write code that looks like this: @RemoteServiceRelativePath("suggest") public interface SuggestService extends RemoteService { String getSuggestions(String str) throws IllegalArgumentException; } 27
  • 37.
  • 38.
  • 39.
    From Eclipse toyour browser Your code... Generators Translators Linkers package com.google.gwt.samples.eclipsecon.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; @SuppressWarnings("unused") public class EclipseCon implements EntryPoint { public void onModuleLoad() { Window.alert("foo"); } } 30
  • 40.
    Java Javascript 31
  • 41.
    From Eclipse toyour browser Your code... Generators Translators Linkers package com.google.gwt.samples.eclipsecon.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; @SuppressWarnings("unused") public class EclipseCon implements EntryPoint { public void onModuleLoad() { Window.alert("foo"); } } 32
  • 42.
    Entry points foryour GWT app 33
  • 43.
    GWT Tips andTricks -gen will output a copy of the generated classes 34
  • 44.
    GWT Tips andTricks Reduce optimizations, reduce compile time -draftCompile • Skip all optimizations • Development only
  • 45.
    GWT Tips andTricks Reduce optimizations, reduce compile time -draftCompile • Skip all optimizations • Development only Why worry about compiling at all?
  • 46.
    A more efficientSDLC Refresh Does it work? Yes Compile No Develop Deploy
  • 47.
  • 48.
    But what about our users? 38
  • 49.
    Optimize for theuser • Bundle resources • Split code
  • 50.
    Resource Bundling • Example- associating icons with a contact
  • 51.
    Resource Bundling One ata time Image image = new Image("images/image1.gif"); image.setHeight("50px"); image.setWidth("50px"); imagesPanel.add(image);
  • 52.
  • 53.
    Resource Bundling All atonce public interface Resources extends ClientBundle { public static final Resources INSTANCE = GWT.create(Resources.class); @Source("Contacts.css") public ContactsCss contactsCss(); @Source("images0.gif") public ImageResource image0(); @Source("images1.gif") public ImageResource image1(); ... }
  • 54.
  • 55.
    Code splitting Initial download Not needed on startup
  • 56.
    Code splitting Split points- runAsync() @UiHandler("showImagesButton") void onOkClicked(ClickEvent event) { GWT.runAsync(new RunAsyncCallback() { public void onSuccess() { showImagesDialog(); } }); }
  • 57.
  • 58.
    Real world results- Google Wave 1500 1400 KB Size of Initial JavaScript Download (KB) 1125 750 7x Decrease In Initial Download Size 375 200 KB 0 26-Nov 29-Apr 18-Jun 28-Jul 12-Sep 27-Oct 24-Dec 16-Mar
  • 59.
    Creating GWT apps- “Direct” approach Write a bunch of widgets with self-contained logic Problems: • Hard to test - need GWTTestCase • Mocks not encouraged - harder to write smaller tests • Platform specific UI code - limits code reuse • Too many dependencies - difficult to optimize
  • 61.
    Creating GWT apps- MVP approach Cast: • Model - DTOs, and business logic • View - The display • Presenter - Application logic Goals: • Be practical • Avoid rigid patterns • Put the complex logic in your Presenters • Put the widget code in your Views • Make the Views as dumb as possible
  • 62.
  • 63.
  • 64.
  • 65.
    The MVP Relationship Model Presenter View
  • 66.
    The MVP Relationship Model Presenter View
  • 67.
    The MVP Relationship Model History Presenter View
  • 68.
    The MVP Relationship RPC Model History Presenter View
  • 69.
    The MVP Relationship Cache RPC Model History Presenter View
  • 70.
    The MVP Relationship Cache RPC Model History Presenter View Event Bus
  • 71.
    The MVP Relationship Cache RPC Model History Presenter View Event Bus
  • 72.
    The MVP Relationship Cache RPC Model History Presenter View Event Bus
  • 73.
  • 74.
    Making the Clouda Reality Contacts Email Sales Force Automation Calendar Your next big idea Banking Collaboration Social Network
  • 75.
  • 76.
    Making the Clouda Reality The right languages and tools are key
  • 77.

Editor's Notes

  • #3 - So what is GWT.... - It&amp;#x2019;s a toolkit and not a framework. With GWT you can pick an choose to use certain tools that we offer without buying into all of them. - Maybe you want to use GWT&amp;#x2019;s RPC mechanism alongside your existing Javascript, or you may want to write your frontend in GWT and leave your server-side code as it exists today. - It&amp;#x2019;s all completely doable. In fact the only thing you have to buy into, is writing Web Apps in Java. - Which leads me to point #2, Code in Java...run as Javascript. At the heart of GWT is a Java to Javascript compiler that (besides producing Javascript) optimizes and obfuscates this Javascript - Separate Javascript is produced for each browser, we refer to these as permutations, and it&amp;#x2019;s what allows facilitates correct behavior within each browser. - You maintain a single Java codebase, and let GWT handle the browser quirks. - XHRs aren&amp;#x2019;t rocket science, by the code to handle them can get messy. RPCs in a GWT app look like nothing more than a method call on a class, and on top of that GWT&amp;#x2019;s RPC generator helps optimize the serialization of objects over the wire. - Finally, we eat generous amounts of our own dogfood. As mentioned before, this presentation is largely about what other teams learned over the past year. Wave and Ad Words are two products that, not only challenged browser capabilities, but GWT capabilities as well.
  • #4 - So what is GWT.... - It&amp;#x2019;s a toolkit and not a framework. With GWT you can pick an choose to use certain tools that we offer without buying into all of them. - Maybe you want to use GWT&amp;#x2019;s RPC mechanism alongside your existing Javascript, or you may want to write your frontend in GWT and leave your server-side code as it exists today. - It&amp;#x2019;s all completely doable. In fact the only thing you have to buy into, is writing Web Apps in Java. - Which leads me to point #2, Code in Java...run as Javascript. At the heart of GWT is a Java to Javascript compiler that (besides producing Javascript) optimizes and obfuscates this Javascript - Separate Javascript is produced for each browser, we refer to these as permutations, and it&amp;#x2019;s what allows facilitates correct behavior within each browser. - You maintain a single Java codebase, and let GWT handle the browser quirks. - XHRs aren&amp;#x2019;t rocket science, by the code to handle them can get messy. RPCs in a GWT app look like nothing more than a method call on a class, and on top of that GWT&amp;#x2019;s RPC generator helps optimize the serialization of objects over the wire. - Finally, we eat generous amounts of our own dogfood. As mentioned before, this presentation is largely about what other teams learned over the past year. Wave and Ad Words are two products that, not only challenged browser capabilities, but GWT capabilities as well.
  • #5 Alright, a quick demo to give you a baseline idea of what we&amp;#x2019;re talking about. Here I have a simple HelloWorld demo that has a textbox, a few labels, and a button. Upon button click, we&amp;#x2019;ll make an RPC call that returns the string we sent it plus some other stats regarding the app server it&amp;#x2019;s running on. All pretty straight forward stuff...right? Let&amp;#x2019;s set some breakpoints.... Change the defaults text values... Swap out the &amp;#x201C;Send&amp;#x201D; button with a demo button...what do I need to define to implement ClickHanlder?...ahh thanks Plugin Btw...note that we&amp;#x2019;re running in our browser of choice, a big improvement in 2.0
  • #6 Alright, a quick demo to give you a baseline idea of what we&amp;#x2019;re talking about. Here I have a simple HelloWorld demo that has a textbox, a few labels, and a button. Upon button click, we&amp;#x2019;ll make an RPC call that returns the string we sent it plus some other stats regarding the app server it&amp;#x2019;s running on. All pretty straight forward stuff...right? Let&amp;#x2019;s set some breakpoints.... Change the defaults text values... Swap out the &amp;#x201C;Send&amp;#x201D; button with a demo button...what do I need to define to implement ClickHanlder?...ahh thanks Plugin Btw...note that we&amp;#x2019;re running in our browser of choice, a big improvement in 2.0
  • #7 Alright, a quick demo to give you a baseline idea of what we&amp;#x2019;re talking about. Here I have a simple HelloWorld demo that has a textbox, a few labels, and a button. Upon button click, we&amp;#x2019;ll make an RPC call that returns the string we sent it plus some other stats regarding the app server it&amp;#x2019;s running on. All pretty straight forward stuff...right? Let&amp;#x2019;s set some breakpoints.... Change the defaults text values... Swap out the &amp;#x201C;Send&amp;#x201D; button with a demo button...what do I need to define to implement ClickHanlder?...ahh thanks Plugin Btw...note that we&amp;#x2019;re running in our browser of choice, a big improvement in 2.0
  • #8 Alright, a quick demo to give you a baseline idea of what we&amp;#x2019;re talking about. Here I have a simple HelloWorld demo that has a textbox, a few labels, and a button. Upon button click, we&amp;#x2019;ll make an RPC call that returns the string we sent it plus some other stats regarding the app server it&amp;#x2019;s running on. All pretty straight forward stuff...right? Let&amp;#x2019;s set some breakpoints.... Change the defaults text values... Swap out the &amp;#x201C;Send&amp;#x201D; button with a demo button...what do I need to define to implement ClickHanlder?...ahh thanks Plugin Btw...note that we&amp;#x2019;re running in our browser of choice, a big improvement in 2.0
  • #9 Alright, a quick demo to give you a baseline idea of what we&amp;#x2019;re talking about. Here I have a simple HelloWorld demo that has a textbox, a few labels, and a button. Upon button click, we&amp;#x2019;ll make an RPC call that returns the string we sent it plus some other stats regarding the app server it&amp;#x2019;s running on. All pretty straight forward stuff...right? Let&amp;#x2019;s set some breakpoints.... Change the defaults text values... Swap out the &amp;#x201C;Send&amp;#x201D; button with a demo button...what do I need to define to implement ClickHanlder?...ahh thanks Plugin Btw...note that we&amp;#x2019;re running in our browser of choice, a big improvement in 2.0
  • #10 Alright, a quick demo to give you a baseline idea of what we&amp;#x2019;re talking about. Here I have a simple HelloWorld demo that has a textbox, a few labels, and a button. Upon button click, we&amp;#x2019;ll make an RPC call that returns the string we sent it plus some other stats regarding the app server it&amp;#x2019;s running on. All pretty straight forward stuff...right? Let&amp;#x2019;s set some breakpoints.... Change the defaults text values... Swap out the &amp;#x201C;Send&amp;#x201D; button with a demo button...what do I need to define to implement ClickHanlder?...ahh thanks Plugin Btw...note that we&amp;#x2019;re running in our browser of choice, a big improvement in 2.0
  • #11 Alright, a quick demo to give you a baseline idea of what we&amp;#x2019;re talking about. Here I have a simple HelloWorld demo that has a textbox, a few labels, and a button. Upon button click, we&amp;#x2019;ll make an RPC call that returns the string we sent it plus some other stats regarding the app server it&amp;#x2019;s running on. All pretty straight forward stuff...right? Let&amp;#x2019;s set some breakpoints.... Change the defaults text values... Swap out the &amp;#x201C;Send&amp;#x201D; button with a demo button...what do I need to define to implement ClickHanlder?...ahh thanks Plugin Btw...note that we&amp;#x2019;re running in our browser of choice, a big improvement in 2.0
  • #12 Alright, a quick demo to give you a baseline idea of what we&amp;#x2019;re talking about. Here I have a simple HelloWorld demo that has a textbox, a few labels, and a button. Upon button click, we&amp;#x2019;ll make an RPC call that returns the string we sent it plus some other stats regarding the app server it&amp;#x2019;s running on. All pretty straight forward stuff...right? Let&amp;#x2019;s set some breakpoints.... Change the defaults text values... Swap out the &amp;#x201C;Send&amp;#x201D; button with a demo button...what do I need to define to implement ClickHanlder?...ahh thanks Plugin Btw...note that we&amp;#x2019;re running in our browser of choice, a big improvement in 2.0
  • #13 Alright, a quick demo to give you a baseline idea of what we&amp;#x2019;re talking about. Here I have a simple HelloWorld demo that has a textbox, a few labels, and a button. Upon button click, we&amp;#x2019;ll make an RPC call that returns the string we sent it plus some other stats regarding the app server it&amp;#x2019;s running on. All pretty straight forward stuff...right? Let&amp;#x2019;s set some breakpoints.... Change the defaults text values... Swap out the &amp;#x201C;Send&amp;#x201D; button with a demo button...what do I need to define to implement ClickHanlder?...ahh thanks Plugin Btw...note that we&amp;#x2019;re running in our browser of choice, a big improvement in 2.0
  • #14 Alright, a quick demo to give you a baseline idea of what we&amp;#x2019;re talking about. Here I have a simple HelloWorld demo that has a textbox, a few labels, and a button. Upon button click, we&amp;#x2019;ll make an RPC call that returns the string we sent it plus some other stats regarding the app server it&amp;#x2019;s running on. All pretty straight forward stuff...right? Let&amp;#x2019;s set some breakpoints.... Change the defaults text values... Swap out the &amp;#x201C;Send&amp;#x201D; button with a demo button...what do I need to define to implement ClickHanlder?...ahh thanks Plugin Btw...note that we&amp;#x2019;re running in our browser of choice, a big improvement in 2.0
  • #15 In the context of &amp;#x201C;Best Practices&amp;#x201D; I&amp;#x2019;m going to focus on these features today....
  • #16 In the context of &amp;#x201C;Best Practices&amp;#x201D; I&amp;#x2019;m going to focus on these features today....
  • #17 In the context of &amp;#x201C;Best Practices&amp;#x201D; I&amp;#x2019;m going to focus on these features today....
  • #18 In the context of &amp;#x201C;Best Practices&amp;#x201D; I&amp;#x2019;m going to focus on these features today....
  • #19 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #20 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #21 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #22 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #23 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #24 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #25 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #26 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #27 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #28 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #29 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #30 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #31 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #32 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #33 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #34 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #35 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #36 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #37 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #38 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #39 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #40 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #41 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #42 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #43 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #44 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #45 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #46 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #47 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #48  Now, if you just jump into writing a GWT application, as we&amp;#x2019;ve done a fair number of times, what&apos;s the most obvious approach? - Subclass composite or complex panel or whatever, run the app, debug with developer mode, etc. - First of all, as your application grows, it&amp;#x2019;s going to become harder to test because it relies on GWTTestCase * What&amp;#x2019;s GWTTestCase you say? Good question. GWTTestCase wraps a JUnit test case and runs your tests within a headless browser. Which is really cool because you can easily test code that would require some testing harness, selenium integration, etc... That said, it does take longer (much longer) to execute these tests because...well...you&amp;#x2019;re starting large parts of your application within a browser. * And any test that requires a DOM to perform layout, amongst other tasks, is going to require a GWTTestCase. Put another way, GWT Widgets require you to test in the browser. - Secondly, mocks are not encouraged. Tools like EasyMock don&amp;#x2019;t play well within a GWTTestCase. - You increase the chance that you have platform independent and dependent code intertwined, which limits code reuse. Use this for context...we want to create an app that will run in both desktop and mobile browsers. The one glaring differences in these platforms is their UI, so it makes sense to limit the amount of code we place here. - Finally, you end up with dependency spaghetti. Your UI code knows about your DTOs, can make some RPCs, has all of the application logic built in to handle UI events, etc...
  • #49  Now, if you just jump into writing a GWT application, as we&amp;#x2019;ve done a fair number of times, what&apos;s the most obvious approach? - Subclass composite or complex panel or whatever, run the app, debug with developer mode, etc. - First of all, as your application grows, it&amp;#x2019;s going to become harder to test because it relies on GWTTestCase * What&amp;#x2019;s GWTTestCase you say? Good question. GWTTestCase wraps a JUnit test case and runs your tests within a headless browser. Which is really cool because you can easily test code that would require some testing harness, selenium integration, etc... That said, it does take longer (much longer) to execute these tests because...well...you&amp;#x2019;re starting large parts of your application within a browser. * And any test that requires a DOM to perform layout, amongst other tasks, is going to require a GWTTestCase. Put another way, GWT Widgets require you to test in the browser. - Secondly, mocks are not encouraged. Tools like EasyMock don&amp;#x2019;t play well within a GWTTestCase. - You increase the chance that you have platform independent and dependent code intertwined, which limits code reuse. Use this for context...we want to create an app that will run in both desktop and mobile browsers. The one glaring differences in these platforms is their UI, so it makes sense to limit the amount of code we place here. - Finally, you end up with dependency spaghetti. Your UI code knows about your DTOs, can make some RPCs, has all of the application logic built in to handle UI events, etc...
  • #50  Now, if you just jump into writing a GWT application, as we&amp;#x2019;ve done a fair number of times, what&apos;s the most obvious approach? - Subclass composite or complex panel or whatever, run the app, debug with developer mode, etc. - First of all, as your application grows, it&amp;#x2019;s going to become harder to test because it relies on GWTTestCase * What&amp;#x2019;s GWTTestCase you say? Good question. GWTTestCase wraps a JUnit test case and runs your tests within a headless browser. Which is really cool because you can easily test code that would require some testing harness, selenium integration, etc... That said, it does take longer (much longer) to execute these tests because...well...you&amp;#x2019;re starting large parts of your application within a browser. * And any test that requires a DOM to perform layout, amongst other tasks, is going to require a GWTTestCase. Put another way, GWT Widgets require you to test in the browser. - Secondly, mocks are not encouraged. Tools like EasyMock don&amp;#x2019;t play well within a GWTTestCase. - You increase the chance that you have platform independent and dependent code intertwined, which limits code reuse. Use this for context...we want to create an app that will run in both desktop and mobile browsers. The one glaring differences in these platforms is their UI, so it makes sense to limit the amount of code we place here. - Finally, you end up with dependency spaghetti. Your UI code knows about your DTOs, can make some RPCs, has all of the application logic built in to handle UI events, etc...
  • #51  Now, if you just jump into writing a GWT application, as we&amp;#x2019;ve done a fair number of times, what&apos;s the most obvious approach? - Subclass composite or complex panel or whatever, run the app, debug with developer mode, etc. - First of all, as your application grows, it&amp;#x2019;s going to become harder to test because it relies on GWTTestCase * What&amp;#x2019;s GWTTestCase you say? Good question. GWTTestCase wraps a JUnit test case and runs your tests within a headless browser. Which is really cool because you can easily test code that would require some testing harness, selenium integration, etc... That said, it does take longer (much longer) to execute these tests because...well...you&amp;#x2019;re starting large parts of your application within a browser. * And any test that requires a DOM to perform layout, amongst other tasks, is going to require a GWTTestCase. Put another way, GWT Widgets require you to test in the browser. - Secondly, mocks are not encouraged. Tools like EasyMock don&amp;#x2019;t play well within a GWTTestCase. - You increase the chance that you have platform independent and dependent code intertwined, which limits code reuse. Use this for context...we want to create an app that will run in both desktop and mobile browsers. The one glaring differences in these platforms is their UI, so it makes sense to limit the amount of code we place here. - Finally, you end up with dependency spaghetti. Your UI code knows about your DTOs, can make some RPCs, has all of the application logic built in to handle UI events, etc...
  • #52  Now, if you just jump into writing a GWT application, as we&amp;#x2019;ve done a fair number of times, what&apos;s the most obvious approach? - Subclass composite or complex panel or whatever, run the app, debug with developer mode, etc. - First of all, as your application grows, it&amp;#x2019;s going to become harder to test because it relies on GWTTestCase * What&amp;#x2019;s GWTTestCase you say? Good question. GWTTestCase wraps a JUnit test case and runs your tests within a headless browser. Which is really cool because you can easily test code that would require some testing harness, selenium integration, etc... That said, it does take longer (much longer) to execute these tests because...well...you&amp;#x2019;re starting large parts of your application within a browser. * And any test that requires a DOM to perform layout, amongst other tasks, is going to require a GWTTestCase. Put another way, GWT Widgets require you to test in the browser. - Secondly, mocks are not encouraged. Tools like EasyMock don&amp;#x2019;t play well within a GWTTestCase. - You increase the chance that you have platform independent and dependent code intertwined, which limits code reuse. Use this for context...we want to create an app that will run in both desktop and mobile browsers. The one glaring differences in these platforms is their UI, so it makes sense to limit the amount of code we place here. - Finally, you end up with dependency spaghetti. Your UI code knows about your DTOs, can make some RPCs, has all of the application logic built in to handle UI events, etc...
  • #53 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #54 - Now that we&amp;#x2019;re all on the same page, let&amp;#x2019;s jump into the discussion of GWT Best Practices - Not that this is a comprehensive list, but these are the items that have been top of mind for a few months now - We&amp;#x2019;ll tackle the largest first, how to reap the benefits of a MVP-based app when using GWT - In the process, we&amp;#x2019;ll explain how to integrate Declarative UIs (mainly how to hook up UI events) - With our architecture in place, we&amp;#x2019;ll follow-up with several optimization techniques * Bundling Resources * Code Splitting * And Prefetching RPCs
  • #55 Now that we&amp;#x2019;ve tackled architecture and testing, it&amp;#x2019;s time to look at how we can optimize our application While there are a plethora of techniques, here are 3 that we&amp;#x2019;ve found useful when building large scale applications Resource bundling...
  • #56 So let&amp;#x2019;s assume we want to allow users to associate icons with their contacts... Yes, typically this would be facilitated by users selecting icons or images from disk...but bear with me for the sake of this example, and assume we&amp;#x2019;re pulling them down from a server
  • #57 We could choose to pull these images one at a time...
  • #58 In which case we&amp;#x2019;d end up with a request pattern that looks like this Fetch the initial html page, followed-up by a request for our nocache.js file And then at some point in time we&amp;#x2019;ll request all of the images to select from Not bad, but there&amp;#x2019;s a large amount of HTTP overhead that we can remove from this flow Remember, your users aren&amp;#x2019;t always right next to your data center...even worse, more and more of them will be on mobile networks 3G networks are fast, but drop off points can be frequent and the cost of building that connection back up can be more than noticeable
  • #59 Instead of pulling the images one at a time, we can define a Resources interface that overlays methods on top of our images The ClientBundle generator will then - Pull the necessary files together - Generate code that allows us to access each accordingly Think of it as spriting for all file types...we don&amp;#x2019;t discriminate
  • #60 You can see that our images are now bundled along with our initial JS call And the subsequent call to display the images has almost zero overhead...basically all we&amp;#x2019;re paying for is the images that make up the decorator panel
  • #61 But we can do better While we&amp;#x2019;ve managed to reduce HTTP overhead by bundling all of our resources, they&amp;#x2019;re in turn downloaded during application load When in reality we only need them when the user navigates to the select Contact icon page
  • #65  Now, if you just jump into writing a GWT application, as we&amp;#x2019;ve done a fair number of times, what&apos;s the most obvious approach? - Subclass composite or complex panel or whatever, run the app, debug with developer mode, etc. - First of all, as your application grows, it&amp;#x2019;s going to become harder to test because it relies on GWTTestCase * What&amp;#x2019;s GWTTestCase you say? Good question. GWTTestCase wraps a JUnit test case and runs your tests within a headless browser. Which is really cool because you can easily test code that would require some testing harness, selenium integration, etc... That said, it does take longer (much longer) to execute these tests because...well...you&amp;#x2019;re starting large parts of your application within a browser. * And any test that requires a DOM to perform layout, amongst other tasks, is going to require a GWTTestCase. Put another way, GWT Widgets require you to test in the browser. - Secondly, mocks are not encouraged. Tools like EasyMock don&amp;#x2019;t play well within a GWTTestCase. - You increase the chance that you have platform independent and dependent code intertwined, which limits code reuse. Use this for context...we want to create an app that will run in both desktop and mobile browsers. The one glaring differences in these platforms is their UI, so it makes sense to limit the amount of code we place here. - Finally, you end up with dependency spaghetti. Your UI code knows about your DTOs, can make some RPCs, has all of the application logic built in to handle UI events, etc...
  • #66 Another way of approaching the problem is with the MVP pattern. A couple of points tough: - Be practical, don&amp;#x2019;t assume that every aspect of the MVP pattern is applicable to your application - Put the complex logic in your Presenters, and make them testable using vanilla JRE tests - Try to contain your widget code, minimize logic that requires GWTTestCase. - Don&amp;#x2019;t create views in your presenter&amp;#x2019;s ctors, doing so makes it impossible to mock them out for testing later - Make the Views as dumb as possible, widget/display code is ideally &quot;correct by construction&quot;
  • #67 Another way of approaching the problem is with the MVP pattern. A couple of points tough: - Be practical, don&amp;#x2019;t assume that every aspect of the MVP pattern is applicable to your application - Put the complex logic in your Presenters, and make them testable using vanilla JRE tests - Try to contain your widget code, minimize logic that requires GWTTestCase. - Don&amp;#x2019;t create views in your presenter&amp;#x2019;s ctors, doing so makes it impossible to mock them out for testing later - Make the Views as dumb as possible, widget/display code is ideally &quot;correct by construction&quot;