Successfully reported this slideshow.
Google Web Toolkit Can help you create amazing apps Can help you create amazing apps <ul><li>San Francisco Java User Group...
Agenda <ul><li>Introduction </li></ul><ul><li>Selecting a language </li></ul><ul><li>Feature tour </li></ul><ul><li>Develo...
Google Web Toolkit Write Core Java APIs Widgets Libraries Java IDEs Debug JVM Debugging Development Mode A real browser De...
3+ years in review May 2006 GWT 1.0 Launch at JavaOne Aug 2008 GWT 1.5 Java 5 language support Apr 2009 GWT 1.7 Dedicated ...
Mission statement <ul><li>&quot;GWT's mission is to  radically  improve </li></ul><ul><li>the web experience for  users  b...
Focus <ul><li>Productivity for developers </li></ul><ul><ul><li>Language, IDEs, tools, libraries </li></ul></ul><ul><ul><l...
No plugins required VML Flash Silverlight
What we don't want
GWT Browser-Proofs Your JavaScript Code... IE Firefox Safari Chrome Opera
Deferred Binding 14800 ms 4836 ms 1997 ms 7148 ms DOM manipulation 2469 ms 1520 ms 918 ms 2477 ms innerText=... - 1386 ms ...
A More Powerful Web, Made Easier
Eating our own dogfood
GWT App Gallery http://gwtgallery.appspot.com / /
GWT App Gallery http://gwtgallery.appspot.com / /
Selecting a language
Rich ecosystem of tools and libraries + + =
Code completion and javadoc
Can you find the bug? Hint: JavaScript is a dynamic language
Catch errors at compile time Java is a static language
Feature tour
Pluggable Architecture
More than just a compiler Development Mode
Sprites for  free 20,558 bytes 6,824 bytes 11 separate images 1 bundled image
Without  ClientBundle
Roundtrips are deadly <ul><li>1 round trip for TCP connection setup </li></ul><ul><li>(1 round trip for HTTP redirect?) </...
Reducing round trip time <ul><li>Use HTTP Expires and Cache-Control headers </li></ul><ul><li>Use GWT 'Perfect Caching' </...
Know your HTTP Headers <ul><li><!-- See RFC 2616. Here's an example: </li></ul><ul><li>Expires: Thu, 02 Sep 2010 03:21:55 ...
History just works
Rich Text Area
RTL, I18N, L10N, A11Y
Widget Libraries <ul><ul><li>GWT  ( http://code.google.com/webtoolkit/ )   </li></ul></ul><ul><ul><li>Incubator    ( http:...
GUI Editing
Simple, Powerful RPCs <ul><li>interface SpellService extends RemoteService { </li></ul><ul><li>/** </li></ul><ul><li>   * ...
Shameless plugs for: gwt-dnd, gwt-log, gwt-voices gwt-dnd, gwt-log, gwt-voices
Developer productivity for you for you
GWT 2.0 operating modes <ul><li>Development Mode  (Hosted Mode) </li></ul><ul><ul><li>All about productivity </li></ul></u...
Development Mode (Hosted Mode) <ul><li>JVM debugging </li></ul><ul><ul><li>Server & Client code in the same IDE </li></ul>...
Development Mode Code Server Web Server Duke, the Java mascot Copyright © Sun Microsystems Inc., all rights reserved. Java...
Google Plugin for Eclipse
Eclipse plugin highlights <ul><li>Extensive JSNI support </li></ul><ul><li>RPC sync/async quick fixes  </li></ul><ul><li>L...
GWT Debugging in the browser
Complete Java development stack
Developer productivity  on larger projects on larger projects
Do or do not. There is no try. <ul><li>Test, test, test </li></ul><ul><ul><li>JUnit, CI, TDD </li></ul></ul><ul><ul><li>Se...
Do or do not. There is no try. <ul><li>gwt-api-checker </li></ul><ul><li>Design </li></ul><ul><ul><li>EventBus, MVP, embra...
Testing & TDD tools your should know <ul><li>GWTTestCase extends UnitTest </li></ul><ul><li>GWTMockUtilities  - neutralizi...
Modules you should know <ul><li><!-- Selenium, WebDriver, etc. --> </li></ul><ul><li><inherits name=&quot;com.google.gwt.u...
Compiler arguments you should know <ul><li>// Story of your compile </li></ul><ul><li>-soyc </li></ul><ul><li>// Symbols m...
-extra  files you should know <ul><li>stuff/…/…GreetingService .rpc.log </li></ul><ul><li>stuff/…/rpcPolicyManifest/ manif...
Collaboration hints you should know <ul><li>Source control, use   svn:ignore </li></ul><ul><ul><li>war/WEB-INF/lib/<sdk-ja...
Project Organization <ul><li>war/  layout </li></ul><ul><li>Multiple modules, single compile, single script </li></ul><ul>...
Configuration parameters you should know <ul><li><extend-configuration-property </li></ul><ul><ul><li>name=&quot; rpc.blac...
System properties you should know <ul><li>// Specify benchmark output directory </li></ul><ul><li>-Dcom.google.gwt.junit.r...
Compiler arguments you should know <ul><li>// Human readable code </li></ul><ul><li>-style PRETTY </li></ul><ul><li>// fas...
RunAsync package pattern - Gateway class <ul><li>package  com.foo.client.addressbookasync; </li></ul><ul><li>public class ...
RunAsync package pattern - Gateway class <ul><li>…  </li></ul><ul><li>// Async interface to obtain an </li></ul><ul><li>//...
RunAsync package pattern - Gateway class <ul><li>… </li></ul><ul><li>public  static void  get (final Callback cb) { </li><...
Compiler magic
GWT quote to remember <ul><li>“The fastest code is that </li></ul><ul><li>which does not run.” </li></ul><ul><ul><li>Joel ...
Conventional and non-conventional <ul><li>Java transformations </li></ul><ul><ul><li>Dead-code elimination </li></ul></ul>...
EXPERIMENTAL  arguments you should know <ul><li>// Don't care what Class#getName() returns? </li></ul><ul><li>-XdisableCla...
EXPERIMENTAL  arguments you should know <ul><li>// In a real-world (very large) Google app... </li></ul><ul><li>//  1% scr...
Need for speed
Speed matters perceived as instantaneous. maintains the feeling that a single task is being carried out. limit for keeping...
Another reason speed matters 2. UI Changes 3. User Learns 1. User Action Performance for your users
GWT Helps Apps Startup More Quickly 26-Nov  29-Apr  18-Jun  28-Jul  12-Sep  27-Oct  24-Dec  16-Mar Size of Initial JavaScr...
Developer guided code splitting
Developer guided code splitting
Manual code splitting - Don't try this at home
Developer guided code splitting <ul><li>GWT. runAsync (new RunAsyncCallback() { </li></ul><ul><li>  public void onSuccess(...
Story of Your Compile (SOYC) <ul><li>-C </li></ul>
Disappearing code that just works
JSON - JavaScript Object Notation <ul><li>{ </li></ul><ul><li>&quot;firstName&quot;: &quot;Fred&quot;, </li></ul><ul><li>&...
Using JSON <ul><li>// 1.  Server responds </li></ul><ul><li>{&quot;firstName&quot;: &quot;Fred&quot;, &quot;lastName&quot;...
Using JSON // Brittle var greeting = 'Hello, ' + p.firstName + ' ' + p.lastName; // Additional payload for user to downloa...
The amazing disappearing code trick Using JSO Types Using JSO Types <ul><li>// This class is about to disappear! </li></ul...
The amazing disappearing code trick <ul><li>public class Person extends JavaScriptObject { </li></ul><ul><li>… </li></ul><...
The amazing disappearing code trick <ul><li>… </li></ul><ul><li>// Go ahead, use your type-safe abstractions </li></ul><ul...
ClientBundle
Sprites for free ( ImageBundle ) <ul><li>public interface MyDialogImages </li></ul><ul><li>extends ImageBundle  { </li></u...
Injecting / inspecting resources at compile-time <ul><li>interface MyBundle  extends ClientBundle  { </li></ul><ul><li>pub...
Injecting / inspecting resources at compile-time <ul><li>interface MyBundle extends ClientBundle { </li></ul><ul><li>@Sour...
Injecting / inspecting resources at compile-time <ul><li>interface MyBundle extends ClientBundle { </li></ul><ul><li>… </l...
Injecting / inspecting resources at compile-time <ul><li>interface MyBundle extends ClientBundle { </li></ul><ul><li>… </l...
Compile time CSS awesomeness http://code.google.com/p/google-web-toolkit/wiki/CssResource http://code.google.com/p/google-...
Gadgets
Corporate Gadgets
Making gadgets <ul><li>@ModulePrefs ( </li></ul><ul><li>   title = &quot;Hello World!&quot;, </li></ul><ul><li>   director...
Making gadgets <ul><li>@ModulePrefs(…) </li></ul><ul><li>public class HelloGadget extends Gadget<HelloPreferences> { </li>...
Making gadget preferences <ul><li>public interface MealPreferences  extends UserPreferences  { </li></ul><ul><li>   @Prefe...
Expecting the unexpected
Expecting the unexpected in Development <ul><li>public void  onModuleLoad () { </li></ul><ul><li>// This isn't going to he...
Expecting the unexpected in Development Mode <ul><li>// Hyperlink your stack traces </li></ul><ul><li>Throwable#printStrac...
Expecting the unexpected in Development Mode <ul><li>// Logging with zero overhead in production mode </li></ul><ul><li><i...
Make the compiler output human readable <ul><li>//  -draftCompile -style PRETTY </li></ul><ul><li>function $onModuleLoad()...
Expecting the unexpected in Production Mode <ul><li><inherits name=&quot; compiler.emulatedStack &quot; /> </li></ul><ul><...
Expecting the unexpected in Production Mode <ul><li>Even with  -style OBF </li></ul><ul><ul><li>Server side symbol maps, e...
Expecting the unexpected in Production Mode <ul><li>You still get stack traces in JavaScript! </li></ul><ul><ul><li>Throwa...
<ul><li>Development Mode </li></ul><ul><li>Declarative UI (UiBinder) </li></ul><ul><li>Developer Guided Code Splitting </l...
Thank you <ul><li>Read more </li></ul><ul><ul><ul><li>http://code.google.com/webtoolkit/ </li></ul></ul></ul><ul><li>Conta...
Upcoming SlideShare
Loading in …5
×

SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13

4,404 views

Published on

Published in: Technology

SF JUG - GWT Can Help You Create Amazing Apps - 2009-10-13

  1. 1. Google Web Toolkit Can help you create amazing apps Can help you create amazing apps <ul><li>San Francisco Java User Group </li></ul><ul><ul><li>Oct 13, 2009 </li></ul></ul>Fred Sauer Developer Advocate [email_address] Twitter: @fredsa
  2. 2. Agenda <ul><li>Introduction </li></ul><ul><li>Selecting a language </li></ul><ul><li>Feature tour </li></ul><ul><li>Developer productivity </li></ul><ul><li>Compiler magic </li></ul><ul><li>Need for speed </li></ul><ul><li>Q&A </li></ul>
  3. 3. Google Web Toolkit Write Core Java APIs Widgets Libraries Java IDEs Debug JVM Debugging Development Mode A real browser Developer Productivity Optimize GWT Compiler Image Bundle (Sprites) CSS Magic End User Performance Run Desktop Mobile Online/Offline Gadgets
  4. 4. 3+ years in review May 2006 GWT 1.0 Launch at JavaOne Aug 2008 GWT 1.5 Java 5 language support Apr 2009 GWT 1.7 Dedicated IE8 support Fall 2009 GWT 2.0 LOTS of interesting stuff
  5. 5. Mission statement <ul><li>&quot;GWT's mission is to radically improve </li></ul><ul><li>the web experience for users by </li></ul><ul><li>enabling developers to use existing </li></ul><ul><li>Java tools to build no-compromise </li></ul><ul><li>AJAX for any modern browser.&quot; </li></ul>
  6. 6. Focus <ul><li>Productivity for developers </li></ul><ul><ul><li>Language, IDEs, tools, libraries </li></ul></ul><ul><ul><li>People, ecosystem </li></ul></ul><ul><li>Performance for your users </li></ul><ul><ul><li>'Perfect' caching </li></ul></ul><ul><ul><li>Whole program optimization </li></ul></ul><ul><ul><li>Better than practical hand written code </li></ul></ul>
  7. 7. No plugins required VML Flash Silverlight
  8. 8. What we don't want
  9. 9. GWT Browser-Proofs Your JavaScript Code... IE Firefox Safari Chrome Opera
  10. 10. Deferred Binding 14800 ms 4836 ms 1997 ms 7148 ms DOM manipulation 2469 ms 1520 ms 918 ms 2477 ms innerText=... - 1386 ms 908 ms - textContent=... 4078 ms 2053 ms 1276 ms 2876 ms Typical portable setInnerText() IE Opera Webkit (Safari) Firefox Improvement 39% 32% 29% 14%
  11. 11. A More Powerful Web, Made Easier
  12. 12. Eating our own dogfood
  13. 13. GWT App Gallery http://gwtgallery.appspot.com / /
  14. 14. GWT App Gallery http://gwtgallery.appspot.com / /
  15. 15. Selecting a language
  16. 16. Rich ecosystem of tools and libraries + + =
  17. 17. Code completion and javadoc
  18. 18. Can you find the bug? Hint: JavaScript is a dynamic language
  19. 19. Catch errors at compile time Java is a static language
  20. 20. Feature tour
  21. 21. Pluggable Architecture
  22. 22. More than just a compiler Development Mode
  23. 23. Sprites for free 20,558 bytes 6,824 bytes 11 separate images 1 bundled image
  24. 24. Without ClientBundle
  25. 25. Roundtrips are deadly <ul><li>1 round trip for TCP connection setup </li></ul><ul><li>(1 round trip for HTTP redirect?) </li></ul><ul><li>1 round trip for each HTTP request </li></ul>$ ping ohare.comPING ohare.com (70.142.247.22): 56 data bytes64 bytes from 70.142.247.22: icmp_seq=0 ttl=113 time= 54.689 ms 64 bytes from 70.142.247.22: icmp_seq=1 ttl=113 time= 55.500 ms 64 bytes from 70.142.247.22: icmp_seq=2 ttl=113 time= 54.728 ms
  26. 26. Reducing round trip time <ul><li>Use HTTP Expires and Cache-Control headers </li></ul><ul><li>Use GWT 'Perfect Caching' </li></ul><ul><ul><li>Cache 'forever' - your entire app and all its resources </li></ul></ul><ul><ul><li>Bundle, bundle, bundle </li></ul></ul><ul><li>Enable HTTP Pipelining </li></ul><ul><li>Use multiple hostnames </li></ul><ul><ul><li>Defeat browser's two connection limit </li></ul></ul><ul><ul><li>Watch out for DNS lookup overhead though </li></ul></ul>
  27. 27. Know your HTTP Headers <ul><li><!-- See RFC 2616. Here's an example: </li></ul><ul><li>Expires: Thu, 02 Sep 2010 03:21:55 GMT </li></ul><ul><li>Cache-Control: public, max-age=31536000 </li></ul><ul><li>--> </li></ul><ul><li><Files *.cache.* > </li></ul><ul><li>ExpiresDefault &quot;now plus 1 year&quot; </li></ul><ul><li></Files> </li></ul><ul><li><Files *.nocache.* > </li></ul><ul><li>ExpiresDefault &quot;access&quot; </li></ul><ul><li></Files> </li></ul>
  28. 28. History just works
  29. 29. Rich Text Area
  30. 30. RTL, I18N, L10N, A11Y
  31. 31. Widget Libraries <ul><ul><li>GWT  ( http://code.google.com/webtoolkit/ )   </li></ul></ul><ul><ul><li>Incubator    ( http://code.google.com/p/google-web-toolkit-incubator/ ) </li></ul></ul><ul><ul><li>Smart GWT  ( http://code.google.com/p/smartgwt/ ) </li></ul></ul><ul><ul><li>GWT-Ext ( http://code.google.com/p/gwt-ext/ ) </li></ul></ul><ul><ul><li>Vaadin (IT Mill Toolkit)  ( http://vaadin.com / ) </li></ul></ul><ul><ul><li>GWT mosaic  ( http://code.google.com/p/gwt-mosaic/ ) </li></ul></ul><ul><ul><li>Ext GWT  ( http://extjs.com/products/gxt/ ) </li></ul></ul><ul><ul><li>Advanced GWT Components </li></ul></ul><ul><li>     ( http://advanced-gwt.sourceforge.net / )  </li></ul>
  32. 32. GUI Editing
  33. 33. Simple, Powerful RPCs <ul><li>interface SpellService extends RemoteService { </li></ul><ul><li>/** </li></ul><ul><li>  * Checks spelling and suggests </li></ul><ul><li>  * alternatives. </li></ul><ul><li>  * @param the word to check </li></ul><ul><li>  * @return the list of alternatives </li></ul><ul><li>  */ </li></ul><ul><li>String[] suggest(String word); </li></ul><ul><li>} </li></ul>
  34. 34. Shameless plugs for: gwt-dnd, gwt-log, gwt-voices gwt-dnd, gwt-log, gwt-voices
  35. 35. Developer productivity for you for you
  36. 36. GWT 2.0 operating modes <ul><li>Development Mode (Hosted Mode) </li></ul><ul><ul><li>All about productivity </li></ul></ul><ul><ul><li>Java + JavaScript </li></ul></ul><ul><ul><li>Now in any supported browser </li></ul></ul><ul><li>Production Mode (Web Mode) </li></ul><ul><ul><li>All about performance </li></ul></ul><ul><ul><li>Compiled, Pure JavaScript </li></ul></ul>
  37. 37. Development Mode (Hosted Mode) <ul><li>JVM debugging </li></ul><ul><ul><li>Server & Client code in the same IDE </li></ul></ul><ul><ul><li>Step in / over / out </li></ul></ul><ul><ul><li>Introspect & modify variables </li></ul></ul><ul><ul><li>Hot swap code (ignore the IDE warning!) </li></ul></ul>NOT TRUE
  38. 38. Development Mode Code Server Web Server Duke, the Java mascot Copyright © Sun Microsystems Inc., all rights reserved. Java Virtual Machine
  39. 39. Google Plugin for Eclipse
  40. 40. Eclipse plugin highlights <ul><li>Extensive JSNI support </li></ul><ul><li>RPC sync/async quick fixes </li></ul><ul><li>Launch configurations </li></ul><ul><li>GWT JUnit tests </li></ul><ul><li>Contributor SDKs (gwt-user, gwt-dev- <platform> ) </li></ul><ul><li>Development Mode (GWT 2.0) </li></ul><ul><ul><li>Hosted Mode (GWT 1.7) </li></ul></ul><ul><li>Constantly improving; check back often </li></ul>
  41. 41. GWT Debugging in the browser
  42. 42. Complete Java development stack
  43. 43. Developer productivity on larger projects on larger projects
  44. 44. Do or do not. There is no try. <ul><li>Test, test, test </li></ul><ul><ul><li>JUnit, CI, TDD </li></ul></ul><ul><ul><li>Selenium, WebDriver, enableDedugId </li></ul></ul><ul><ul><li>http://mymachine:8080/Foo.html ?gwt.codesvr= … </li></ul></ul><ul><ul><li>Code coverage </li></ul></ul><ul><li>Logging </li></ul><ul><ul><li>http://code.google.com/p/gwt-log/ ; incubator logging </li></ul></ul>
  45. 45. Do or do not. There is no try. <ul><li>gwt-api-checker </li></ul><ul><li>Design </li></ul><ul><ul><li>EventBus, MVP, embrace asynchrony </li></ul></ul><ul><li>Separation & specialization </li></ul><ul><ul><li>CSS, HTML, Java/JavaScript; UiBinder; MVP </li></ul></ul>
  46. 46. Testing & TDD tools your should know <ul><li>GWTTestCase extends UnitTest </li></ul><ul><li>GWTMockUtilities - neutralizing GWT.create() </li></ul><ul><li>FakeMessagesMaker </li></ul><ul><li>Lightweight metrics </li></ul><ul><ul><li>http://code.google.com/p/google-web-toolkit/wiki/LightweightMetricsDesign </li></ul></ul>
  47. 47. Modules you should know <ul><li><!-- Selenium, WebDriver, etc. --> </li></ul><ul><li><inherits name=&quot;com.google.gwt.user. Debug &quot; /> </li></ul><ul><li><set-property </li></ul><ul><ul><li>name=&quot; gwt.enableDebugId &quot; value=&quot;true&quot; /> </li></ul></ul><ul><li>// Setup my ids for QA </li></ul><ul><li>Button searchButton = new Button(); </li></ul><ul><li>searchButton. ensureDebugId (&quot;srch&quot;); </li></ul>
  48. 48. Compiler arguments you should know <ul><li>// Story of your compile </li></ul><ul><li>-soyc </li></ul><ul><li>// Symbols maps, SOYC reports, RPC info </li></ul><ul><li>-extra stuff </li></ul><ul><li>-logLevel </li></ul><ul><li>// Note: use as a GWT Compiler argument! </li></ul><ul><li>-ea </li></ul>
  49. 49. -extra files you should know <ul><li>stuff/…/…GreetingService .rpc.log </li></ul><ul><li>stuff/…/rpcPolicyManifest/ manifest.txt </li></ul><ul><li>stuff/…/ soycReport /splitPoints0.xml.gz </li></ul><ul><li>stuff/…/symbolMaps/04065D…5D6433CF. symbolMap </li></ul><ul><li>stuff/…/symbolMaps/24B10B…3859D5C9.symbolMap </li></ul><ul><li>stuff/…/symbolMaps/2814EF…CF2746BA.symbolMap </li></ul><ul><li>stuff/…/symbolMaps/32793E…8754FAC1.symbolMap </li></ul><ul><li>stuff/…/symbolMaps/C23998…9827C30B.symbolMap </li></ul>
  50. 50. Collaboration hints you should know <ul><li>Source control, use svn:ignore </li></ul><ul><ul><li>war/WEB-INF/lib/<sdk-jars> </li></ul></ul><ul><ul><li>war/WEB-INF/classes </li></ul></ul><ul><ul><li>war/<module-name> </li></ul></ul><ul><li>OS/platform browser issues / setup, code formatting </li></ul><ul><ul><li>trunk/gwt/eclipse/README.txt </li></ul></ul><ul><li>Eclipse, Checkstyle </li></ul><ul><ul><li>Prefs: Java Editor -> Save Actions </li></ul></ul>
  51. 51. Project Organization <ul><li>war/ layout </li></ul><ul><li>Multiple modules, single compile, single script </li></ul><ul><li>Java package naming conventions </li></ul><ul><ul><li>client </li></ul></ul><ul><ul><li>server </li></ul></ul><ul><ul><li>rebind </li></ul></ul><ul><ul><li>model </li></ul></ul>
  52. 52. Configuration parameters you should know <ul><li><extend-configuration-property </li></ul><ul><ul><li>name=&quot; rpc.blacklist &quot; </li></ul></ul><ul><ul><li>value=&quot;com.foo.myapp.client.WidgetList&quot; /> </li></ul></ul><ul><li><extend-configuration-property </li></ul><ul><ul><li>name=&quot; rpc.blacklist &quot; </li></ul></ul><ul><ul><li>value=&quot;com.foo.myapp.client.TimerList&quot; /> </li></ul></ul><ul><li>… </li></ul>
  53. 53. System properties you should know <ul><li>// Specify benchmark output directory </li></ul><ul><li>-Dcom.google.gwt.junit.reportPath= … </li></ul><ul><li>// watch the compiler optimize a method </li></ul><ul><li>-Dgwt.jjs.traceMethods= foo.Bar.onModuleLoad </li></ul>
  54. 54. Compiler arguments you should know <ul><li>// Human readable code </li></ul><ul><li>-style PRETTY </li></ul><ul><li>// fast (for development) </li></ul><ul><li>-draftCompile </li></ul><ul><li>// Compile N permutations in parallel </li></ul><ul><li>// (N = number of cores) </li></ul><ul><li>-localWorkers= N </li></ul>
  55. 55. RunAsync package pattern - Gateway class <ul><li>package com.foo.client.addressbookasync; </li></ul><ul><li>public class AddressBook { </li></ul><ul><li>// Can't construct directly </li></ul><ul><li>private AddressBook() { } </li></ul><ul><li>// Only callable once you have an instance </li></ul><ul><li>public show() { </li></ul><ul><li>// use package restricted code here </li></ul><ul><li>} </li></ul><ul><li>… </li></ul>
  56. 56. RunAsync package pattern - Gateway class <ul><li>… </li></ul><ul><li>// Async interface to obtain an </li></ul><ul><li>// instance of AddressBook </li></ul><ul><li>public interface Callback { </li></ul><ul><li>void onCreated (AddressBook addressBook); </li></ul><ul><li>void onCreateFailure (Throwable e); </li></ul><ul><li>} </li></ul><ul><li>… </li></ul>
  57. 57. RunAsync package pattern - Gateway class <ul><li>… </li></ul><ul><li>public static void get (final Callback cb) { </li></ul><ul><li>GWT.runAsync(new RunAsyncCallback() { </li></ul><ul><li>public void onSuccess() { </li></ul><ul><li>cb.onCreated(new AddressBook()); </li></ul><ul><li>} </li></ul><ul><li>public void onFailure(Throwable e) { </li></ul><ul><li>cb.onCreateFailure(e); </li></ul><ul><li>} </li></ul><ul><li>}); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  58. 58. Compiler magic
  59. 59. GWT quote to remember <ul><li>“The fastest code is that </li></ul><ul><li>which does not run.” </li></ul><ul><ul><li>Joel Webber </li></ul></ul><ul><ul><ul><li>GWT co-creator </li></ul></ul></ul>
  60. 60. Conventional and non-conventional <ul><li>Java transformations </li></ul><ul><ul><li>Dead-code elimination </li></ul></ul><ul><ul><li>Method inlining </li></ul></ul><ul><ul><li>Constant folding & propagation </li></ul></ul><ul><li>JavaScript transformations (gzip motivated) </li></ul><ul><ul><li>Method reordering </li></ul></ul><ul><ul><li>Argument renaming </li></ul></ul>
  61. 61. EXPERIMENTAL arguments you should know <ul><li>// Don't care what Class#getName() returns? </li></ul><ul><li>-XdisableClassMetadata </li></ul>5% - 10% script reduction Showcase metadata before Showcase metadata after
  62. 62. EXPERIMENTAL arguments you should know <ul><li>// In a real-world (very large) Google app... </li></ul><ul><li>// 1% script size reduction </li></ul><ul><li>// 10% faster in performance-sensitive code </li></ul><ul><li>-XdisableCastChecking </li></ul><ul><li>try { </li></ul><ul><li>((Quacker) animal).quack(); </li></ul><ul><li>} catch (ClassCastException c) { </li></ul><ul><li>Window.alert(&quot;Found a non-quacker&quot;); </li></ul><ul><li>} </li></ul>
  63. 63. Need for speed
  64. 64. Speed matters perceived as instantaneous. maintains the feeling that a single task is being carried out. limit for keeping user’s attention. 0.1 seconds 1 second 10 seconds
  65. 65. Another reason speed matters 2. UI Changes 3. User Learns 1. User Action Performance for your users
  66. 66. GWT Helps Apps Startup More Quickly 26-Nov 29-Apr 18-Jun 28-Jul 12-Sep 27-Oct 24-Dec 16-Mar Size of Initial JavaScript Download (KB) 375 750 1125 1500 0 7x Decrease In Initial Download Size with runAsync() 1400 KB 200 KB
  67. 67. Developer guided code splitting
  68. 68. Developer guided code splitting
  69. 69. Manual code splitting - Don't try this at home
  70. 70. Developer guided code splitting <ul><li>GWT. runAsync (new RunAsyncCallback() { </li></ul><ul><li>  public void onSuccess() { </li></ul><ul><li>    … </li></ul><ul><li>  } </li></ul><ul><li>  public void onFailure(Throwable caught) { </li></ul><ul><li>    … </li></ul><ul><li>  } </li></ul><ul><li>}); </li></ul>
  71. 71. Story of Your Compile (SOYC) <ul><li>-C </li></ul>
  72. 72. Disappearing code that just works
  73. 73. JSON - JavaScript Object Notation <ul><li>{ </li></ul><ul><li>&quot;firstName&quot;: &quot;Fred&quot;, </li></ul><ul><li>&quot;lastName&quot;: &quot;Sauer&quot;, </li></ul><ul><li>&quot;contactInfo&quot;: </li></ul><ul><li>{ </li></ul><ul><li>&quot;email&quot;: &quot; [email_address] &quot;, … </li></ul><ul><li>} </li></ul><ul><li>&quot;likes&quot;: </li></ul><ul><li>[ </li></ul><ul><li>&quot;Open Source&quot;, &quot;GWT&quot;, &quot;Chocolate&quot; </li></ul><ul><li>] </li></ul><ul><li>} </li></ul>
  74. 74. Using JSON <ul><li>// 1. Server responds </li></ul><ul><li>{&quot;firstName&quot;: &quot;Fred&quot;, &quot;lastName&quot;: &quot;Sauer&quot;, … } </li></ul><ul><li>// 2. Client parses </li></ul><ul><li>p = safeJsonParse(responseText); </li></ul><ul><li>// or Client evaluates (Danger, Will Robinson!) </li></ul><ul><li>p = eval(responseText); </li></ul><ul><li>… </li></ul>
  75. 75. Using JSON // Brittle var greeting = 'Hello, ' + p.firstName + ' ' + p.lastName; // Additional payload for user to download function getName(p) { return p.firstName + ' ' + p.lastName; } // Additional method invocation overhead var greeting = 'Hello, ' + getName(p);
  76. 76. The amazing disappearing code trick Using JSO Types Using JSO Types <ul><li>// This class is about to disappear! </li></ul><ul><li>public class Person extends JavaScriptObject { </li></ul><ul><li>// assume 'this' has 'firstName' property </li></ul><ul><li>public native String getFirstName() </li></ul><ul><li>/*-{ return this. firstName; }-*/; </li></ul><ul><li>public native String getLastName() </li></ul><ul><li>/*-{ return this. lastName; }-*/; </li></ul><ul><li>… </li></ul>
  77. 77. The amazing disappearing code trick <ul><li>public class Person extends JavaScriptObject { </li></ul><ul><li>… </li></ul><ul><li>// This method is about to disappear as well! </li></ul><ul><li>public String getDisplayName() { </li></ul><ul><li>return getFirstName() + &quot; &quot; + getLastName(); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  78. 78. The amazing disappearing code trick <ul><li>… </li></ul><ul><li>// Go ahead, use your type-safe abstractions </li></ul><ul><li>// You get to keep your wrapper classes </li></ul><ul><li>Person person; </li></ul><ul><li>// Also keep your convenience methods </li></ul><ul><li>String name = person.getDisplayName() ; </li></ul><ul><li>// GWT performs disappearing trick </li></ul><ul><li>var name = p.firstName + ' ' + p.lastName ; </li></ul>
  79. 79. ClientBundle
  80. 80. Sprites for free ( ImageBundle ) <ul><li>public interface MyDialogImages </li></ul><ul><li>extends ImageBundle { </li></ul><ul><li>// Look for 'saveButton.{png|jpg|gif|bmp}' </li></ul><ul><li>AbstractImagePrototype saveButton(); </li></ul><ul><li>AbstractImagePrototype okButton(); </li></ul><ul><li>@ Resource (&quot;com/foo/myapp/btn_cancel.png&quot;) </li></ul><ul><li>AbstractImagePrototype cancelButton(); </li></ul><ul><li>} </li></ul>
  81. 81. Injecting / inspecting resources at compile-time <ul><li>interface MyBundle extends ClientBundle { </li></ul><ul><li>public static final MyBundle INSTANCE = </li></ul><ul><li>GWT.create(MyBundle.class); </li></ul><ul><li>@Source(&quot;app_config.xml&quot;) </li></ul><ul><li>TextResource appConfig1(); </li></ul><ul><li>@Source(&quot;wordlist.txt&quot;) </li></ul><ul><li>ExternalTextResource wordlist(); </li></ul><ul><li>… </li></ul>
  82. 82. Injecting / inspecting resources at compile-time <ul><li>interface MyBundle extends ClientBundle { </li></ul><ul><li>@Source(&quot;myCursor.cur&quot;) </li></ul><ul><li>  DataResource myCursor(); </li></ul><ul><li>} </li></ul><ul><li>MyBundle.INSTANCE.myCursor().getUrl(); </li></ul><ul><li>http: //localhost:8080/foo/B349934EA27D6EFFD949B88E6A116ED7. cache .cur </li></ul><ul><li>data: content/unknown;base64,c2FkIGprZ2xkZdqZGZrb </li></ul><ul><li>CBnamtkZmxnIGRma2xnaiBrZGxmZ2prbGRmamcga2xkaiBna </li></ul><ul><li>2w7ZGZqZy…IGRmamtsw7ZGZqZyBrbGRmZ2ogZGtsO </li></ul>
  83. 83. Injecting / inspecting resources at compile-time <ul><li>interface MyBundle extends ClientBundle { </li></ul><ul><li>… </li></ul><ul><li>@Source(&quot;arrow.png&quot;) // locale sensitive! </li></ul><ul><li>  @ImageOptions( flipRtl = true) </li></ul><ul><li>  ImageResource pointer(); </li></ul><ul><li>} </li></ul><ul><li>MyBundle.INSTANCE.pointer().getUrl(); </li></ul><ul><li>MyBundle.INSTANCE.pointer().getWidth(); </li></ul><ul><li>MyBundle.INSTANCE.pointer().getHeight(); </li></ul><ul><li>… </li></ul>
  84. 84. Injecting / inspecting resources at compile-time <ul><li>interface MyBundle extends ClientBundle { </li></ul><ul><li>… </li></ul><ul><li>@ Strict // or @NotStrict </li></ul><ul><li>@Source(&quot;address_book.css&quot;) </li></ul><ul><li>CssResource addressBookCSS(); </li></ul><ul><li>} </li></ul>
  85. 85. Compile time CSS awesomeness http://code.google.com/p/google-web-toolkit/wiki/CssResource http://code.google.com/p/google-web-toolkit/wiki/CssResource <ul><li>@def small 1px; /* Constants */ </li></ul><ul><li>@if user.agent safari gecko1_8 { … } </li></ul><ul><li>@if locale en { … } </li></ul><ul><li>@noflip { … } /* no automatic left/right swap */ </li></ul><ul><li>@external </li></ul>
  86. 86. Gadgets
  87. 87. Corporate Gadgets
  88. 88. Making gadgets <ul><li>@ModulePrefs ( </li></ul><ul><li>  title = &quot;Hello World!&quot;, </li></ul><ul><li>  directory_title = &quot;My first gadget&quot;, </li></ul><ul><li>  screenshot = &quot;gadget.png&quot;, </li></ul><ul><li>  thumbnail = &quot;thumb.png&quot;, </li></ul><ul><li>… </li></ul><ul><li>height = 210) </li></ul><ul><li>public class HelloGadget </li></ul><ul><li>extends </li></ul><ul><li>Gadget<HelloPreferences> </li></ul><ul><li>{ </li></ul><ul><li>… </li></ul>
  89. 89. Making gadgets <ul><li>@ModulePrefs(…) </li></ul><ul><li>public class HelloGadget extends Gadget<HelloPreferences> { </li></ul><ul><li>public void onModuleLoad() { /* ... */} </li></ul><ul><li>  protected void init( </li></ul><ul><li>final HelloPreferences prefs) { </li></ul><ul><li>… </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  90. 90. Making gadget preferences <ul><li>public interface MealPreferences extends UserPreferences { </li></ul><ul><li>  @PreferenceAttributes( </li></ul><ul><li>display_name = &quot;Vegetarian&quot;, </li></ul><ul><li>default_value = &quot;false&quot;) </li></ul><ul><li>  BooleanPreference noMeat(); </li></ul><ul><li>} </li></ul>
  91. 91. Expecting the unexpected
  92. 92. Expecting the unexpected in Development <ul><li>public void onModuleLoad () { </li></ul><ul><li>// This isn't going to help us now </li></ul><ul><li>GWT.setUncaughtExceptionHandler(…); </li></ul><ul><li>  // Your initialization code goes wrong here :( </li></ul><ul><li>// Cross your fingers </li></ul><ul><li>} </li></ul>public void onModuleLoad() { Log. setUncaughtExceptionHandler() ;  DeferredCommand.addCommand(new Command() {    public void execute() {      onModuleLoad2();    }  }); }private void onModuleLoad2 () {  // Your module initialization code goes here}
  93. 93. Expecting the unexpected in Development Mode <ul><li>// Hyperlink your stack traces </li></ul><ul><li>Throwable#printStrackTrace() </li></ul>
  94. 94. Expecting the unexpected in Development Mode <ul><li>// Logging with zero overhead in production mode </li></ul><ul><li><inherits </li></ul><ul><ul><li>name=&quot;com.allen_sauer.gwt.log.gwt-log-DEBUG&quot;/> </li></ul></ul><ul><li>Log.debug(&quot;This is a 'DEBUG' test message&quot;); </li></ul>
  95. 95. Make the compiler output human readable <ul><li>// -draftCompile -style PRETTY </li></ul><ul><li>function $onModuleLoad() { </li></ul><ul><li>$showArea(getClientWidth(),getClientHeight()); </li></ul><ul><li>} </li></ul><ul><li>function $showArea(width, height){ </li></ul><ul><li>alert_0('area=' + width * height); </li></ul><ul><li>} </li></ul>// Production Mode (-style OBF) Ee='area=';function nc(){$wnd.alert(Ee+(u(new q),Hb($doc))*Gb($doc))}
  96. 96. Expecting the unexpected in Production Mode <ul><li><inherits name=&quot; compiler.emulatedStack &quot; /> </li></ul><ul><li><set-configuration-property </li></ul><ul><li>name=&quot;compiler.emulatedStack. recordLineNumbers &quot; </li></ul><ul><li>value=&quot;true&quot; /> </li></ul><ul><li><set-configuration-property </li></ul><ul><li>name=&quot;compiler.emulatedStack. recordFileNames &quot; </li></ul><ul><li>value=&quot;true&quot; /> </li></ul>
  97. 97. Expecting the unexpected in Production Mode <ul><li>Even with -style OBF </li></ul><ul><ul><li>Server side symbol maps, e.g. </li></ul></ul><ul><ul><li>xQ() -> MyClass.myOriginalJavaMethod() </li></ul></ul>
  98. 98. Expecting the unexpected in Production Mode <ul><li>You still get stack traces in JavaScript! </li></ul><ul><ul><li>Throwable#getStackTrace() </li></ul></ul>
  99. 99. <ul><li>Development Mode </li></ul><ul><li>Declarative UI (UiBinder) </li></ul><ul><li>Developer Guided Code Splitting </li></ul><ul><li>ClientBundle </li></ul><ul><li>SOYC </li></ul>Roadmap Fall 2009
  100. 100. Thank you <ul><li>Read more </li></ul><ul><ul><ul><li>http://code.google.com/webtoolkit/ </li></ul></ul></ul><ul><li>Contact info </li></ul><ul><ul><ul><li>Fred Sauer </li></ul></ul></ul><ul><ul><ul><li>Developer Advocate </li></ul></ul></ul><ul><ul><ul><li>[email_address] </li></ul></ul></ul><ul><ul><ul><li>Twitter @fredsa </li></ul></ul></ul><ul><li>Questions? </li></ul>

×