SlideShare une entreprise Scribd logo
1  sur  71
Google Web Toolkit
       Building Web Apps Sanely


Chris Ramsdale
Developer Relations, Google
Agenda

• Overview
• Demo
• Deeper dive
• Optimizations for developers
• Optimizations for users
• Testing and deployment
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

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
Demo time


To see this in action, letʼs:
• Create a new web app
• Debug within the browser
• Update, refresh, run




                      13
Simple enough.




      14
He’s an Ajax pro




                   15
A Java to Javascript compiler right?




                 16
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()                                             17
I can haz pretty print plz



                             Simply adjust
                             the output
                             style of the
                             compiler via
                             the plugin




                     18
Yes, a Java to Javascript compiler
function init(){
  !!$stats && $stats({moduleName:$moduleName, sessionId:$sessionId, subSystem:'startup', evtGroup:'moduleStartup',
millis:(new Date).getTime(), type:'onModuleLoadStart',
className:'com.google.gwt.samples.eclipsecon.client.EclipseCon'});
  $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(){
}




                                                         19
But wait...thereʼs more




           20
Let’s take a look under
the hood




             21
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




                                                        22
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");
    }
}




                                                         23
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");
    }
}




                                                         24
Generators   Provide the power behind your
             GWT app

             Automate away boilerplate code

             Foundation for permutations




             25
Use Case #1: GWT RPCs

Typical Ajax call


            Serialization         Serialization
               Code                  Code
   Client                   XHR                   Server




                            26
Use Case #1: GWT RPCs

GWT-enabled Ajax


                      Serialization         Serialization
          GWT Proxy




                                                            GWT Proxy
                         Code                  Code
 Client                               XHR                               Server




                                      27
Use Case #1: GWT RPCs

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

 • Make it fast to boot


                     28
Use Case #1: GWT RPCs


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




                                   29
Use Case #2: Creating UIs

Goals:
 • Utilize common dev practices
 • Minimize boilerplate code
   interface methods
 • Remove a few other frustrations
   along the way

                   30
Use Case #2: Creating UIs


You write code that looks like this:
<ui:UiBinder
  xmlns:ui="urn:ui:com.google.gwt.uibinder"
  xmlns:g="urn:import:com.google.gwt.user.client.ui">
	
  <ui:style>
    .contactsViewButtonHPanel {
      margin: 5px 0px 0x 5px;	
    }
  </ui:style>

 <g:HorizontalPanel addStyleNames="{style.contactsViewButtonHPanel}">
   <g:Button ui:field="addButton">Add</g:Button>
   <g:Button ui:field="deleteButton">Delete</g:Button>
 </g:HorizontalPanel>

</ui:UiBinder>

                                          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
Java



        Javascript




   33
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");
    }
}




                                                         34
Entry points for your GWT app
                       35
GWT Tips and Tricks




   -gen will output a copy of the
        generated classes



                      36
Question: What’s up with those compile times?




                      37
Question: What’s up with those compile times?




       Answer: Permutations




                      37
Question: What’s up with those compile times?




  Answer: ...and optimizations




                      38
Permutations



               Each *.cache.html is a
               browser and language
               specific version of the
               app
Permutations




               They’re a matrix, and will
               grow fast
GWT Tips and Tricks

Reduce permutations, reduce compile time
EclipseCon.gwt.xml

<extend-property name="locale" values="en_US" />
<set-property name="user.agent" value="gecko" />



                                  Now a single
                                  permutation targeting
                                  US versions of English
                                  in Firefox browsers
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?
Is it done yet?
A more efficient SDLC




Refresh        Does it work?   Yes   Compile

                    No


          Develop                    Deploy
We’re happy




45
But what about
 our users?




                 46
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

                                                                                        56
Testing

• Can be run as vanilla JRE tests
• Can be run as GwtTestCase(s)
 - Requires a headless browser
 - 15 sec vs 15 ms runtime
 - Rely on design patterns such as MVP
Deployment and App Engine
Deployment and App Engine




 Stick around for the next talk
Google Plugin for Eclipse 1.3

• Configurable WAR directory
• Transparent program and VM args
• Minor bug fixes
Takeaways

1. Large Javascript projects can get messy
2. Browsers can be a bit quirky at times
3. Web developers haven’t always had the best
   tools
4. Ajax tends to require a fair amount of
   boilerplate code

5. With GWT, you can forget 1-4 and focus on the
   next killer feature
</presentation>


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

Contenu connexe

Tendances

Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3ICS
 
Best Practices in Qt Quick/QML - Part III
Best Practices in Qt Quick/QML - Part IIIBest Practices in Qt Quick/QML - Part III
Best Practices in Qt Quick/QML - Part IIIICS
 
Best Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part IBest Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part IICS
 
Performance #1: Memory
Performance #1: MemoryPerformance #1: Memory
Performance #1: MemoryYonatan Levin
 
Serving QML applications over the network
Serving QML applications over the networkServing QML applications over the network
Serving QML applications over the networkJeremy Lainé
 
Qt and QML performance tips & tricks for Qt 4.7
Qt and QML performance tips & tricks for Qt 4.7Qt and QML performance tips & tricks for Qt 4.7
Qt and QML performance tips & tricks for Qt 4.7Pasi Kellokoski
 
Best Practices in Qt Quick/QML - Part 2
Best Practices in Qt Quick/QML - Part 2Best Practices in Qt Quick/QML - Part 2
Best Practices in Qt Quick/QML - Part 2Janel Heilbrunn
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James NelsonGWTcon
 
GR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul KingGR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul KingGR8Conf
 
Qt Internationalization
Qt InternationalizationQt Internationalization
Qt InternationalizationICS
 
Lockless Producer Consumer Threads: Asynchronous Communications Made Easy
Lockless Producer Consumer Threads: Asynchronous Communications Made EasyLockless Producer Consumer Threads: Asynchronous Communications Made Easy
Lockless Producer Consumer Threads: Asynchronous Communications Made EasyICS
 
GQuery a jQuery clone for Gwt, RivieraDev 2011
GQuery a jQuery clone for Gwt, RivieraDev 2011GQuery a jQuery clone for Gwt, RivieraDev 2011
GQuery a jQuery clone for Gwt, RivieraDev 2011Manuel Carrasco Moñino
 
Meet the Widgets: Another Way to Implement UI
Meet the Widgets: Another Way to Implement UIMeet the Widgets: Another Way to Implement UI
Meet the Widgets: Another Way to Implement UIICS
 
QVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI developmentQVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI developmentICS
 
Basics of Model/View Qt programming
Basics of Model/View Qt programmingBasics of Model/View Qt programming
Basics of Model/View Qt programmingICS
 
iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術Yuji Hato
 
Apache Aries Overview
Apache Aries   OverviewApache Aries   Overview
Apache Aries OverviewIan Robinson
 
Qt & Webkit
Qt & WebkitQt & Webkit
Qt & WebkitQT-day
 
Grails EE
Grails EEGrails EE
Grails EEGR8Conf
 

Tendances (20)

Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3
 
Best Practices in Qt Quick/QML - Part III
Best Practices in Qt Quick/QML - Part IIIBest Practices in Qt Quick/QML - Part III
Best Practices in Qt Quick/QML - Part III
 
Best Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part IBest Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part I
 
Performance #1: Memory
Performance #1: MemoryPerformance #1: Memory
Performance #1: Memory
 
Serving QML applications over the network
Serving QML applications over the networkServing QML applications over the network
Serving QML applications over the network
 
Qt and QML performance tips & tricks for Qt 4.7
Qt and QML performance tips & tricks for Qt 4.7Qt and QML performance tips & tricks for Qt 4.7
Qt and QML performance tips & tricks for Qt 4.7
 
Best Practices in Qt Quick/QML - Part 2
Best Practices in Qt Quick/QML - Part 2Best Practices in Qt Quick/QML - Part 2
Best Practices in Qt Quick/QML - Part 2
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
 
GR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul KingGR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul King
 
Qt Internationalization
Qt InternationalizationQt Internationalization
Qt Internationalization
 
Lockless Producer Consumer Threads: Asynchronous Communications Made Easy
Lockless Producer Consumer Threads: Asynchronous Communications Made EasyLockless Producer Consumer Threads: Asynchronous Communications Made Easy
Lockless Producer Consumer Threads: Asynchronous Communications Made Easy
 
GQuery a jQuery clone for Gwt, RivieraDev 2011
GQuery a jQuery clone for Gwt, RivieraDev 2011GQuery a jQuery clone for Gwt, RivieraDev 2011
GQuery a jQuery clone for Gwt, RivieraDev 2011
 
Meet the Widgets: Another Way to Implement UI
Meet the Widgets: Another Way to Implement UIMeet the Widgets: Another Way to Implement UI
Meet the Widgets: Another Way to Implement UI
 
QVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI developmentQVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI development
 
Basics of Model/View Qt programming
Basics of Model/View Qt programmingBasics of Model/View Qt programming
Basics of Model/View Qt programming
 
iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術
 
GWT Extreme!
GWT Extreme!GWT Extreme!
GWT Extreme!
 
Apache Aries Overview
Apache Aries   OverviewApache Aries   Overview
Apache Aries Overview
 
Qt & Webkit
Qt & WebkitQt & Webkit
Qt & Webkit
 
Grails EE
Grails EEGrails EE
Grails EE
 

En vedette

En vedette (16)

Schi Legal in Carpati
Schi Legal in CarpatiSchi Legal in Carpati
Schi Legal in Carpati
 
La adivina
La adivinaLa adivina
La adivina
 
Comunicare Coalitie 2010
Comunicare Coalitie 2010Comunicare Coalitie 2010
Comunicare Coalitie 2010
 
Hardware Revision
Hardware RevisionHardware Revision
Hardware Revision
 
Music Industry Audience Revision
Music Industry  Audience  RevisionMusic Industry  Audience  Revision
Music Industry Audience Revision
 
Visit to El Porton Verde EcoLodge in Managua, Nicaragua
Visit to El Porton Verde EcoLodge in Managua, NicaraguaVisit to El Porton Verde EcoLodge in Managua, Nicaragua
Visit to El Porton Verde EcoLodge in Managua, Nicaragua
 
Mrs. Hall's Poetry Reading
Mrs. Hall's Poetry ReadingMrs. Hall's Poetry Reading
Mrs. Hall's Poetry Reading
 
FELIZ NAVIDAD
FELIZ NAVIDADFELIZ NAVIDAD
FELIZ NAVIDAD
 
Android android + app engine a developer's dream combination copy
Android android + app engine  a developer's dream combination copyAndroid android + app engine  a developer's dream combination copy
Android android + app engine a developer's dream combination copy
 
FELIZ NAVIDAD
FELIZ NAVIDADFELIZ NAVIDAD
FELIZ NAVIDAD
 
Android android + app engine a developer's dream combination
Android android + app engine  a developer's dream combinationAndroid android + app engine  a developer's dream combination
Android android + app engine a developer's dream combination
 
Agent Green DN 66 a
Agent Green DN 66 aAgent Green DN 66 a
Agent Green DN 66 a
 
Ariile protejate din Romania, Notiuni introductive
Ariile protejate din Romania, Notiuni introductiveAriile protejate din Romania, Notiuni introductive
Ariile protejate din Romania, Notiuni introductive
 
Prezentare Scoli Parcul National Cozia 2009
Prezentare Scoli Parcul National Cozia 2009Prezentare Scoli Parcul National Cozia 2009
Prezentare Scoli Parcul National Cozia 2009
 
How to build business web apps using GWT and Spring Tools
How to build business web apps using GWT and Spring ToolsHow to build business web apps using GWT and Spring Tools
How to build business web apps using GWT and Spring Tools
 
Ghid Indrumar Trasele Tematice In Ariile Protejate
Ghid Indrumar Trasele Tematice In Ariile ProtejateGhid Indrumar Trasele Tematice In Ariile Protejate
Ghid Indrumar Trasele Tematice In Ariile Protejate
 

Similaire à Building Web Apps Sanely - EclipseCon 2010

Hybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitHybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitAriya Hidayat
 
Hybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKitHybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKitAriya Hidayat
 
Cannibalising The Google App Engine
Cannibalising The  Google  App  EngineCannibalising The  Google  App  Engine
Cannibalising The Google App Enginecatherinewall
 
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13Fred Sauer
 
Devfest09 Cschalk Gwt
Devfest09 Cschalk GwtDevfest09 Cschalk Gwt
Devfest09 Cschalk GwtChris Schalk
 
Marvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey BuzdinMarvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey BuzdinJava User Group Latvia
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVMSylvain Wallez
 
Performance measurement and tuning
Performance measurement and tuningPerformance measurement and tuning
Performance measurement and tuningAOE
 
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...DataStax Academy
 
Dev fest 2020 taiwan how to debug microservices on kubernetes as a pros (ht...
Dev fest 2020 taiwan   how to debug microservices on kubernetes as a pros (ht...Dev fest 2020 taiwan   how to debug microservices on kubernetes as a pros (ht...
Dev fest 2020 taiwan how to debug microservices on kubernetes as a pros (ht...KAI CHU CHUNG
 
Testing of javacript
Testing of javacriptTesting of javacript
Testing of javacriptLei Kang
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?Doug Hawkins
 
Google Dev Day2007
Google Dev Day2007Google Dev Day2007
Google Dev Day2007lucclaes
 
Introduction to QtWebKit
Introduction to QtWebKitIntroduction to QtWebKit
Introduction to QtWebKitAriya Hidayat
 
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰KAI CHU CHUNG
 
Gretty: Managing Web Containers with Gradle
Gretty: Managing Web Containers with GradleGretty: Managing Web Containers with Gradle
Gretty: Managing Web Containers with GradleAndrey Hihlovsky
 
Docker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline ExecutionDocker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline ExecutionBrennan Saeta
 
Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2JooinK
 
Backend, app e internet das coisas com NodeJS no Google Cloud Platform
Backend, app e internet das coisas com NodeJS no Google Cloud PlatformBackend, app e internet das coisas com NodeJS no Google Cloud Platform
Backend, app e internet das coisas com NodeJS no Google Cloud PlatformAlvaro Viebrantz
 

Similaire à Building Web Apps Sanely - EclipseCon 2010 (20)

Hybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKitHybrid Apps (Native + Web) using WebKit
Hybrid Apps (Native + Web) using WebKit
 
Hybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKitHybrid Apps (Native + Web) via QtWebKit
Hybrid Apps (Native + Web) via QtWebKit
 
Cannibalising The Google App Engine
Cannibalising The  Google  App  EngineCannibalising The  Google  App  Engine
Cannibalising The Google App Engine
 
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13
 
Devfest09 Cschalk Gwt
Devfest09 Cschalk GwtDevfest09 Cschalk Gwt
Devfest09 Cschalk Gwt
 
Marvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey BuzdinMarvel of Annotation Preprocessing in Java by Alexey Buzdin
Marvel of Annotation Preprocessing in Java by Alexey Buzdin
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVM
 
Performance measurement and tuning
Performance measurement and tuningPerformance measurement and tuning
Performance measurement and tuning
 
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
Cassandra Summit 2014: Highly Scalable Web Application in the Cloud with Cass...
 
Dev fest 2020 taiwan how to debug microservices on kubernetes as a pros (ht...
Dev fest 2020 taiwan   how to debug microservices on kubernetes as a pros (ht...Dev fest 2020 taiwan   how to debug microservices on kubernetes as a pros (ht...
Dev fest 2020 taiwan how to debug microservices on kubernetes as a pros (ht...
 
Testing of javacript
Testing of javacriptTesting of javacript
Testing of javacript
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Google Dev Day2007
Google Dev Day2007Google Dev Day2007
Google Dev Day2007
 
GWT MVP Case Study
GWT MVP Case StudyGWT MVP Case Study
GWT MVP Case Study
 
Introduction to QtWebKit
Introduction to QtWebKitIntroduction to QtWebKit
Introduction to QtWebKit
 
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
 
Gretty: Managing Web Containers with Gradle
Gretty: Managing Web Containers with GradleGretty: Managing Web Containers with Gradle
Gretty: Managing Web Containers with Gradle
 
Docker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline ExecutionDocker & ECS: Secure Nearline Execution
Docker & ECS: Secure Nearline Execution
 
Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2
 
Backend, app e internet das coisas com NodeJS no Google Cloud Platform
Backend, app e internet das coisas com NodeJS no Google Cloud PlatformBackend, app e internet das coisas com NodeJS no Google Cloud Platform
Backend, app e internet das coisas com NodeJS no Google Cloud Platform
 

Building Web Apps Sanely - EclipseCon 2010

  • 1. Google Web Toolkit Building Web Apps Sanely Chris Ramsdale Developer Relations, Google
  • 2. Agenda • Overview • Demo • Deeper dive • Optimizations for developers • Optimizations for users • Testing and deployment
  • 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 loving relationship
  • 6. It’s a loving relationship Develop
  • 7. It’s a loving relationship Develop Debug
  • 8. It’s a loving relationship Develop Debug Optimize
  • 9. 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
  • 10. 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
  • 11. 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
  • 12. No plugins required Silverlight VML Flash
  • 13. Nothing against them, but... Foo Player not available for your device We restrict use of technologies required by products like Foo Player...
  • 14. 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
  • 15. 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%
  • 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 Improvement 14% 29% 32% 39% http://quirksmode.org/blog/
  • 17. 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; }
  • 18. 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
  • 19. Our plugin can Java is a static language
  • 20. Demo time To see this in action, letʼs: • Create a new web app • Debug within the browser • Update, refresh, run 13
  • 22. He’s an Ajax pro 15
  • 23. A Java to Javascript compiler right? 16
  • 24. 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() 17
  • 25. I can haz pretty print plz Simply adjust the output style of the compiler via the plugin 18
  • 26. Yes, a Java to Javascript compiler function init(){ !!$stats && $stats({moduleName:$moduleName, sessionId:$sessionId, subSystem:'startup', evtGroup:'moduleStartup', millis:(new Date).getTime(), type:'onModuleLoadStart', className:'com.google.gwt.samples.eclipsecon.client.EclipseCon'}); $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(){ } 19
  • 28. Let’s take a look under the hood 21
  • 29. 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 22
  • 30. 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"); } } 23
  • 31. 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"); } } 24
  • 32. Generators Provide the power behind your GWT app Automate away boilerplate code Foundation for permutations 25
  • 33. Use Case #1: GWT RPCs Typical Ajax call Serialization Serialization Code Code Client XHR Server 26
  • 34. Use Case #1: GWT RPCs GWT-enabled Ajax Serialization Serialization GWT Proxy GWT Proxy Code Code Client XHR Server 27
  • 35. Use Case #1: GWT RPCs Goals: • Serialization code begone • RPCs like theyʼre meant to be - interface methods • Make it fast to boot 28
  • 36. Use Case #1: GWT RPCs You write code that looks like this: @RemoteServiceRelativePath("suggest") public interface SuggestService extends RemoteService { String getSuggestions(String str) throws IllegalArgumentException; } 29
  • 37. Use Case #2: Creating UIs Goals: • Utilize common dev practices • Minimize boilerplate code interface methods • Remove a few other frustrations along the way 30
  • 38. Use Case #2: Creating UIs You write code that looks like this: <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"> <ui:style> .contactsViewButtonHPanel { margin: 5px 0px 0x 5px; } </ui:style> <g:HorizontalPanel addStyleNames="{style.contactsViewButtonHPanel}"> <g:Button ui:field="addButton">Add</g:Button> <g:Button ui:field="deleteButton">Delete</g:Button> </g:HorizontalPanel> </ui:UiBinder> 31
  • 39. 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
  • 40. Java Javascript 33
  • 41. 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"); } } 34
  • 42. Entry points for your GWT app 35
  • 43. GWT Tips and Tricks -gen will output a copy of the generated classes 36
  • 44. Question: What’s up with those compile times? 37
  • 45. Question: What’s up with those compile times? Answer: Permutations 37
  • 46. Question: What’s up with those compile times? Answer: ...and optimizations 38
  • 47. Permutations Each *.cache.html is a browser and language specific version of the app
  • 48. Permutations They’re a matrix, and will grow fast
  • 49. GWT Tips and Tricks Reduce permutations, reduce compile time EclipseCon.gwt.xml <extend-property name="locale" values="en_US" /> <set-property name="user.agent" value="gecko" /> Now a single permutation targeting US versions of English in Firefox browsers
  • 50. GWT Tips and Tricks Reduce optimizations, reduce compile time -draftCompile • Skip all optimizations • Development only
  • 51. GWT Tips and Tricks Reduce optimizations, reduce compile time -draftCompile • Skip all optimizations • Development only Why worry about compiling at all?
  • 52. Is it done yet?
  • 53. A more efficient SDLC Refresh Does it work? Yes Compile No Develop Deploy
  • 55. But what about our users? 46
  • 56. Optimize for the user • Bundle resources • Split code
  • 57. Resource Bundling • Example - associating icons with a contact
  • 58. Resource Bundling One at a time Image image = new Image("images/image1.gif"); image.setHeight("50px"); image.setWidth("50px"); imagesPanel.add(image);
  • 60. 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(); ... }
  • 62. Code splitting Initial download Not needed on startup
  • 63. Code splitting Split points - runAsync() @UiHandler("showImagesButton") void onOkClicked(ClickEvent event) { GWT.runAsync(new RunAsyncCallback() { public void onSuccess() { showImagesDialog(); } }); }
  • 65. 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 56
  • 66. Testing • Can be run as vanilla JRE tests • Can be run as GwtTestCase(s) - Requires a headless browser - 15 sec vs 15 ms runtime - Rely on design patterns such as MVP
  • 68. Deployment and App Engine Stick around for the next talk
  • 69. Google Plugin for Eclipse 1.3 • Configurable WAR directory • Transparent program and VM args • Minor bug fixes
  • 70. Takeaways 1. Large Javascript projects can get messy 2. Browsers can be a bit quirky at times 3. Web developers haven’t always had the best tools 4. Ajax tends to require a fair amount of boilerplate code 5. With GWT, you can forget 1-4 and focus on the next killer feature

Notes de l'éditeur

  1. - Good morning everyone. My name is Chris Ramsdale and I work with the GWT team here in Atlanta. - Today I want to discuss some of the techniques, patterns, and tricks that we and other internal Google teams find useful when building large scale applications. - Before we get started, how many of you have used GWT before? - How many have shipped a product of project with GWT? - Great, so to make sure we&amp;#x2019;re on the same page, I&amp;#x2019;m going to take a few minutes to give an overview of GWT...which will also give me a chance talk about some of the new 2.0 features - From there well jump right into the meat of this presentation.
  2. - 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.
  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. 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
  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. In the context of &amp;#x201C;Best Practices&amp;#x201D; I&amp;#x2019;m going to focus on these features today....
  13. In the context of &amp;#x201C;Best Practices&amp;#x201D; I&amp;#x2019;m going to focus on these features today....
  14. In the context of &amp;#x201C;Best Practices&amp;#x201D; I&amp;#x2019;m going to focus on these features today....
  15. In the context of &amp;#x201C;Best Practices&amp;#x201D; I&amp;#x2019;m going to focus on these features today....
  16. - 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
  17. - 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
  18. - 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
  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, 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...
  45. 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...
  46. 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...
  47. 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...
  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 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
  51. - 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
  52. 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...
  53. 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
  54. We could choose to pull these images one at a time...
  55. 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
  56. 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
  57. 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
  58. 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
  59. In case any of you haven&amp;#x2019;t seen Google Wave yet, I&amp;#x2019;ll give you the 10 sec tour The important point here, is that there is large amount of UI, data, and logic taking place within this app And as the app grew, so did there initial start time