GWT@Jazoon08 - Part 1/6 - First Impressions Count

2,123 views

Published on

A presentation about GWT which I presentaed at Jazoon '08
Part 1/6 - First Impressions Count

Published in: Technology, Business
  • very nice presentation
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

GWT@Jazoon08 - Part 1/6 - First Impressions Count

  1. 1. <ul><ul><li># 1 </li></ul></ul><ul><ul><li>first impressions count. </li></ul></ul>
  2. 2. checking in at a hotel ...
  3. 3. choosing a puppy ...
  4. 4. unboxing your iPhone ...
  5. 5. unboxing your iPhone ...
  6. 6. unboxing your iPhone ...
  7. 7. <ul><ul><li>start fast. </li></ul></ul><ul><ul><li>“ Every web usability study I have </li></ul></ul><ul><ul><li>conducted since 1994 has shown </li></ul></ul><ul><ul><li>the same thing: Users beg us to </li></ul></ul><ul><ul><li>speed up page downloads.” </li></ul></ul><ul><ul><li>- Jakob Nielsen </li></ul></ul>
  8. 8. <ul><ul><li>human attention. </li></ul></ul><ul><ul><li>0.1 seconds - perceived as instantaneous </li></ul></ul><ul><ul><li>1 second - maintains the feeling that a single task is being carried out </li></ul></ul><ul><ul><li>10 seconds - limit for keeping user’s attention </li></ul></ul>
  9. 9. <ul><ul><li>annoying. </li></ul></ul><ul><ul><li>slow apps are annoying </li></ul></ul><ul><ul><li>buggy apps are annoying </li></ul></ul><ul><ul><li>slow, buggy apps are not worth using </li></ul></ul>
  10. 10. <ul><ul><li>irrelevant. </li></ul></ul><ul><ul><li>source code elegance and maintainability </li></ul></ul><ul><ul><li>how much fun it is to develop </li></ul></ul><ul><ul><li>choice of programming language </li></ul></ul>
  11. 11. <ul><ul><li>GWT manifesto. </li></ul></ul><ul><ul><li>“ To radically improve </li></ul></ul><ul><ul><li>the web experience for users </li></ul></ul><ul><ul><li>by enabling developers </li></ul></ul><ul><ul><li>to use existing Java tools </li></ul></ul><ul><ul><li>to build no-compromise Ajax </li></ul></ul><ul><ul><li>for any modern browser .” </li></ul></ul>
  12. 12. <ul><ul><li>page load. </li></ul></ul><ul><ul><li>1. download resources </li></ul></ul><ul><ul><li>2. run JavaScript startup code </li></ul></ul><ul><ul><li>3. render layout </li></ul></ul>
  13. 14. <ul><ul><li>resource issues. </li></ul></ul><ul><ul><li>50kb = 1200ms </li></ul></ul><ul><ul><li>25kb = 950ms </li></ul></ul><ul><ul><li>2 x 25kb = 2 x 950 ms </li></ul></ul><ul><ul><li>50kb = 1900ms </li></ul></ul>ms kb
  14. 15. <ul><ul><li>startup issues. </li></ul></ul><ul><ul><li>lazy loading </li></ul></ul><ul><ul><li>lazy loading </li></ul></ul><ul><ul><li>lazy loading </li></ul></ul><ul><ul><li>lazy loading </li></ul></ul><ul><ul><li>lazy loading </li></ul></ul>
  15. 16. <ul><ul><li>rendering issues. </li></ul></ul>
  16. 17. <ul><ul><li>GWT </li></ul></ul><ul><ul><li>to the rescue </li></ul></ul>
  17. 18. <ul><ul><li>goal. </li></ul></ul><ul><ul><li>reduce # HTTP request by reducing file count </li></ul></ul><ul><ul><li>cache until the sun explodes </li></ul></ul><ul><ul><li>cross browser, cross platform at no cost </li></ul></ul><ul><ul><li>min usability compromises due to impl changes </li></ul></ul><ul><ul><li>extreme JavaScript code optimizations </li></ul></ul>
  18. 19. <ul><ul><li>compiler. </li></ul></ul><ul><ul><li>“ Seperate maintainability of the source code </li></ul></ul><ul><ul><li>from the effectiveness of the executable.” </li></ul></ul><ul><ul><li>- Bruce Johnson </li></ul></ul>
  19. 20. <ul><ul><li>compiler. </li></ul></ul><ul><ul><li>handwritten JavaScript has a conflict of interest </li></ul></ul><ul><ul><li>long, useful identifiers = bigger, slower apps </li></ul></ul><ul><ul><li>nice formatting = bigger, slower apps </li></ul></ul><ul><ul><li>comments = bigger, slower apps </li></ul></ul><ul><ul><li>zero-cost abstraction </li></ul></ul>
  20. 21. <ul><ul><li>compiler. </li></ul></ul><ul><ul><li>user feedback and usability testing are vital </li></ul></ul><ul><ul><li>you will never get it right the first N times </li></ul></ul><ul><ul><li>being able to iterate quickly is key </li></ul></ul><ul><ul><li>developers need tools with lots of leverage </li></ul></ul>
  21. 22. <ul><ul><li>compiler. </li></ul></ul><ul><ul><li>again, JavaScript has a conflict of interest </li></ul></ul><ul><ul><li>JavaScript = difficult to refactor </li></ul></ul><ul><ul><li>refactoring difficulty = maintenance worry </li></ul></ul><ul><ul><li>maintenance worry = the need to “get it right” the first time (framework-itis) </li></ul></ul>
  22. 23. <ul><ul><li>stop! </li></ul></ul><ul><ul><li>no more GWT introduction stuff </li></ul></ul><ul><ul><li>please... </li></ul></ul>
  23. 24. <ul><ul><li>so what makes </li></ul></ul><ul><ul><li>GWT so fast? </li></ul></ul>
  24. 25. is it magic?
  25. 26. <ul><ul><li>deferred binding. </li></ul></ul>
  26. 27. <ul><ul><li>only pay </li></ul></ul><ul><ul><li>for what you see </li></ul></ul>
  27. 29. <ul><ul><li>right code. </li></ul></ul><ul><ul><li>user agent </li></ul></ul><ul><ul><li>locale </li></ul></ul><ul><ul><li>debug vs. production </li></ul></ul><ul><ul><li>network characteristics </li></ul></ul><ul><ul><li>logging </li></ul></ul><ul><ul><li>debug id on html elements </li></ul></ul><ul><ul><li>… </li></ul></ul><ul><ul><li>anything that can make a difference for the user </li></ul></ul>
  28. 30. <ul><ul><li>modularize. </li></ul></ul>DOMImplIE6 DOMImplMozilla DOMImplSafari DOMImpl … DOM
  29. 31. <ul><ul><li>problems. </li></ul></ul><ul><ul><li>dynamic modules over HTTP suck </li></ul></ul><ul><ul><li>slow to start </li></ul></ul><ul><ul><li>awful network utilization </li></ul></ul><ul><ul><li>slow to execute </li></ul></ul><ul><ul><li>requires polymorphic dispatch at runtime </li></ul></ul><ul><ul><li>impossible to eliminate dead code </li></ul></ul><ul><ul><li>hard to maintain </li></ul></ul><ul><ul><li>“ DLL Hell” for the web </li></ul></ul>
  30. 32. <ul><ul><li>magic. </li></ul></ul><ul><ul><li>DOMImpl dom = GWT.create (DOMImpl.class); </li></ul></ul><ul><ul><li>generates permutations at compile time: </li></ul></ul><ul><ul><li>DOMImpl dom = new DOMImplMozilla(); </li></ul></ul><ul><ul><li>DOMImpl dom = new DOMImplIE6(); </li></ul></ul><ul><ul><li>DOMImpl dom = new DOMImplSafari(); </li></ul></ul>
  31. 33. <ul><ul><li>DOMIMPL EXAMPLE </li></ul></ul><ul><ul><ul><li>abstract class DOMImpl { </li></ul></ul></ul><ul><ul><ul><li> abstract void setInnerText(Element e, String s); </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><ul><li>public class DOMImplMozilla extends DOMImpl { </li></ul></ul></ul><ul><ul><ul><li> native void setInnerText(Element e, String s) </li></ul></ul></ul><ul><ul><ul><li> /*-- { e.textContent = s; } --*/ </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><ul><li>public class DOMImplIE6 extends DOMImpl { </li></ul></ul></ul><ul><ul><ul><li> native void setInnerText(Element e, String s) </li></ul></ul></ul><ul><ul><ul><li> /*-- { e.innerText = s; } --*/ </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul>
  32. 34. <ul><ul><li>advantages. </li></ul></ul><ul><ul><li>right code </li></ul></ul><ul><ul><li>smaller code </li></ul></ul><ul><ul><li>better optimizations </li></ul></ul><ul><ul><li>fewer network roundtrips </li></ul></ul><ul><ul><li>metaprogramming </li></ul></ul>
  33. 35. <ul><ul><li>BETTER OPTIMIZATIONS </li></ul></ul><ul><ul><ul><li>example </li></ul></ul></ul><ul><ul><ul><li>Label label = new Label(“test”); </li></ul></ul></ul><ul><ul><ul><li>output (not obfuscated) </li></ul></ul></ul><ul><ul><ul><li>Firefox e.textContent = s; </li></ul></ul></ul><ul><ul><ul><li>IE6 e.innerText = s; </li></ul></ul></ul>
  34. 36. <ul><ul><li>deferred binding. </li></ul></ul><ul><ul><li>[ dependency injection ] </li></ul></ul>
  35. 37. <ul><ul><li>CREATE AN INTERFACE / BASE CLASS </li></ul></ul><ul><ul><ul><li>public interface Animal { </li></ul></ul></ul><ul><ul><ul><li> String makeSound(); </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><li>CREATE IMPLEMENTATIONS </li></ul></ul><ul><ul><ul><li>public class Dog implements Animal { </li></ul></ul></ul><ul><ul><ul><li> public String makeSound() { return “bark”; } </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><ul><li>public class Cat implements Animal { </li></ul></ul></ul><ul><ul><ul><li> public String makeSound() { return “miauuwww”; } </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul>
  36. 38. <ul><ul><li>USE IT </li></ul></ul><ul><ul><ul><li>Animal animal = GWT.create(Animal.class); </li></ul></ul></ul><ul><ul><ul><li>Window.alert(animal.makeSound()); </li></ul></ul></ul><ul><ul><li>DECLARE REBIND RULES </li></ul></ul><ul><ul><ul><li><replace-with class=“org.animal.Cat”> </li></ul></ul></ul><ul><ul><ul><li> <when-type-is class=“org.animals.Animal”/> </li></ul></ul></ul><ul><ul><ul><li></replace-with> </li></ul></ul></ul>
  37. 39. <ul><ul><li>DECLARE PROPERTY / ENUMERATED SET OF VALUES </li></ul></ul><ul><ul><ul><li><define-property name=“animal” values=“cat,dog”/> </li></ul></ul></ul><ul><ul><li>DECLARE REBIND RULES </li></ul></ul><ul><ul><ul><li><replace-with class=“org.animal.Cat”> </li></ul></ul></ul><ul><ul><ul><li> <when-type-is class=“org.animals.Animal”/> </li></ul></ul></ul><ul><ul><ul><li> <when-property-is name=“animal” value=“cat”/> </li></ul></ul></ul><ul><ul><ul><li></replace-with> </li></ul></ul></ul><ul><ul><ul><li><replace-with class=“org.animal.Dog”> </li></ul></ul></ul><ul><ul><ul><li> <when-type-is class=“org.animals.Animal”/> </li></ul></ul></ul><ul><ul><ul><li> <when-property-is name=“animal” value=“dog”/> </li></ul></ul></ul><ul><ul><ul><li></replace-with> </li></ul></ul></ul>
  38. 40. <ul><ul><li>DECLARE REBIND RULES (other conditions) </li></ul></ul><ul><ul><ul><li><when-type-is class=“...”/><when-type-assignable class=“...”/> </li></ul></ul></ul><ul><ul><ul><li><when-property-is name=“...” value=“...”/><any><all><none> </li></ul></ul></ul><ul><ul><li>EXTEND PROPERTY VALUES (optional / inheritance) </li></ul></ul><ul><ul><ul><li><extend-property name=“animal” values=“fish”/> </li></ul></ul></ul><ul><ul><li>SET DEFAULT PROPERTY VALUE (optional) </li></ul></ul><ul><ul><ul><li><set-property name=“animal” values=“dog”/> </li></ul></ul></ul>
  39. 41. <ul><ul><li>SET PROPERTY VALUE AT RUNTIME (optional) </li></ul></ul><ul><ul><ul><li><property-provider name=“animal”><!CDATA[ </li></ul></ul></ul><ul><ul><ul><li> return isCat(document.cookie) ? “cat” : “dog”/> </li></ul></ul></ul><ul><ul><ul><li>]]></property-provider> </li></ul></ul></ul>
  40. 42. <ul><ul><li>deferred binding. </li></ul></ul><ul><ul><li>[ generators ] </li></ul></ul>
  41. 43. <ul><ul><li>CREATE A NEW GENERATOR </li></ul></ul><ul><ul><ul><li>public class CatGenerator extends Generator { </li></ul></ul></ul><ul><ul><ul><li> public String generate (TreeLogger logger, GeneratorContext ctx, String requestedClass) { </li></ul></ul></ul><ul><li>PrintWriter pw = ctx.tryCreate(logger, “test”, “ EvilCat ”); </li></ul><ul><li>pw.println(“package test;”); </li></ul><ul><li>pw.println(“public class EvilCat implements Animal {“); </li></ul><ul><li>pw.println(“public String makeSound() { return “Gshhh”; }”); </li></ul><ul><li>pw.println(“}”); </li></ul><ul><li>return “test.EvilCat”; </li></ul><ul><ul><ul><li> } </li></ul></ul></ul>
  42. 44. <ul><ul><li>DECLARE REBIND RULES </li></ul></ul><ul><ul><ul><li><generate-with class=“org.animals.CatGenerator”> </li></ul></ul></ul><ul><ul><ul><li> <when-type-is class=“org.animals.Animal”/> </li></ul></ul></ul><ul><ul><ul><li></generate-with> </li></ul></ul></ul><ul><ul><li>DECLARE REBIND RULES (other conditions) </li></ul></ul><ul><ul><ul><li><when-type-is class=“...”/> </li></ul></ul></ul><ul><ul><ul><li><when-type-assignable class=“...”/> </li></ul></ul></ul><ul><ul><ul><li><when-property-is name=“...” value=“...”/> </li></ul></ul></ul><ul><ul><ul><li><any> </li></ul></ul></ul><ul><ul><ul><li><all> </li></ul></ul></ul><ul><ul><ul><li><none> </li></ul></ul></ul>
  43. 45. <ul><ul><li>GWT REFLECTION VS JAVA REFLECTION </li></ul></ul><ul><ul><ul><li>TypeOracle oracle = generatorContext.getTypeOracle(); </li></ul></ul></ul>
  44. 46. <ul><ul><li>deferred binding. </li></ul></ul><ul><ul><li>[ demystified ] </li></ul></ul>
  45. 47. <ul><ul><li>runtime. </li></ul></ul><ul><ul><li>request generated selection script .nocache.js </li></ul></ul><ul><ul><li>property providers run to decide prop values </li></ul></ul><ul><ul><li>property values imply a permutation: </li></ul></ul><ul><ul><li>map([‘de, ‘ie6’, …], ‘blabla.cache.html’) </li></ul></ul><ul><ul><li>map([‘nl’, ‘ie6’, …], ‘ababab.cache.html’) </li></ul></ul><ul><ul><li>map([‘nl’, ‘safari’, …], ‘xyxyxy.cache.html’) </li></ul></ul><ul><ul><li>strongName = answers[computePropValue(‘locale’)] </li></ul></ul><ul><ul><li>[computePropValue(‘’user.agent)] </li></ul></ul>
  46. 48. <ul><ul><li>permutations. </li></ul></ul><ul><ul><li>.cache.html allows for perfect caching </li></ul></ul><ul><ul><li>cache until the sun explodes </li></ul></ul><ul><ul><li>never fail to get the newest when updated </li></ul></ul><ul><ul><li>never ask if it hasn’t been updated </li></ul></ul><ul><ul><li>not even an If-Modified-Since check </li></ul></ul><ul><ul><li>disk space is cheap </li></ul></ul><ul><ul><li>bandwith and user attention is expensive </li></ul></ul>
  47. 49. <ul><ul><li>deferred binding. </li></ul></ul><ul><ul><li>[ use case: form generation ] </li></ul></ul>
  48. 50. <ul><ul><li>GOAL </li></ul></ul><ul><ul><li>less boilerplate code </li></ul></ul><ul><ul><li>no more listener overhead / memory leaks </li></ul></ul><ul><ul><li>alternative for traditional MVC + GWTX (PropertyChangeListener) </li></ul></ul><ul><ul><li>DATA OBJECT + FORM ANNOTATIONS </li></ul></ul><ul><ul><li> @form.service (value=“com.WishService”) </li></ul></ul><ul><ul><li> public class Wish implements FormDataObject { </li></ul></ul><ul><ul><li> @form.field (length = 50, label = “name”, order = 2, required = true) </li></ul></ul><ul><ul><li> private String name; </li></ul></ul><ul><ul><li> @form.field (length = 200, label = “description”, order = 1, required = true) </li></ul></ul><ul><ul><li> private String description; </li></ul></ul><ul><ul><li> } </li></ul></ul>
  49. 51. <ul><ul><li>BINDING </li></ul></ul><ul><ul><li> <generate-with class=“ com.FormGenerator ”> </li></ul></ul><ul><ul><li> <when-type-assignable class=“ com.FormDataObject ”/> </li></ul></ul><ul><ul><li> </generate-with> </li></ul></ul><ul><ul><li>USAGE </li></ul></ul><ul><ul><li> public void onModuleLoad() { </li></ul></ul><ul><ul><li> Form wishForm = GWT.create(Wish.class); </li></ul></ul><ul><ul><li> RootPanel.get().add(wishForm); </li></ul></ul><ul><ul><li> } </li></ul></ul>
  50. 52. <ul><ul><li>deferred binding. </li></ul></ul><ul><ul><li>[ pages versus modules ] </li></ul></ul>
  51. 53. SEARCH 100% SEARCH EDIT 95% ACCOUNT 5%
  52. 54. <ul><ul><li>extreme graphics. </li></ul></ul>
  53. 55. <ul><ul><li>problems. </li></ul></ul><ul><ul><li>DOM operations are slow </li></ul></ul><ul><ul><li>CANVAS bails out at 1000 - 10000 DIV moves </li></ul></ul><ul><ul><li>JavaScript VM no match for JVM </li></ul></ul>
  54. 56. <ul><ul><li>solutions. </li></ul></ul><ul><ul><li>display lists (OpenGL concept) </li></ul></ul><ul><ul><li>recorded + compiled sequence of calls </li></ul></ul><ul><ul><li>replay sequence like a macro </li></ul></ul><ul><ul><li>fastest method to draw static data </li></ul></ul><ul><ul><li>compiler can do performance optimizations </li></ul></ul><ul><ul><li>cache results as bitmap where possible </li></ul></ul>
  55. 57. <ul><ul><li>solutions. </li></ul></ul><ul><ul><li>dual compile </li></ul></ul><ul><ul><li>measure average client side threshold </li></ul></ul><ul><ul><li>if too slow render on server </li></ul></ul><ul><ul><li> bare HTML (StringBuffer) / Java2D </li></ul></ul><ul><ul><li>SVG / VML / flash </li></ul></ul>
  56. 58. <ul><ul><li>solutions. </li></ul></ul><ul><ul><li>small enhancements </li></ul></ul><ul><ul><li>replace DOM.setStyleAttribute with CSS files </li></ul></ul><ul><ul><li>don’t use widgets when all you need is HTML </li></ul></ul><ul><ul><li>avoid many listeners </li></ul></ul><ul><ul><li>single listener on root -> DOM.sinkEvents </li></ul></ul>
  57. 59. <ul><ul><li>MAARTENVOLDERS. com </li></ul></ul><ul><ul><li>PASSIONATE ABOUT PEOPLE AND TECHNOLOGY </li></ul></ul>

×