GWT Extreme!

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

1 comments

Comments 1 - 1 of 1 previous next Post a comment

Post a comment
Embed Video
Edit your comment Cancel

12 Favorites

GWT Extreme! - Presentation Transcript

  1.  
  2. GWT Extreme! Performance and Flexibility
    • Ray Cromwell, CTO, Timefire, Inc
    • 05/29/2008
  3. BUDD: Why did he call it GWT Extreme? BILL: I guess he thought it sounded kinda cool.
  4. Extreme Performance and Flexibility
      • “ Faster (and Smaller) than Possible” code
        • Parsing and Evaluating CSS Selector Queries
        • High Performance Graphics
      • Bridging GWT with other execution environments
        • Remote procedure calls to Android, Flash, and Gears
      • Writing Flash and Gears Workers in Java
        • Tricks to compile subsets of your source as separate packages
      • Q&A if time permits
  5. GWT Bloated and Slow? Think Again
      • Faster
        • Generate Java code on the fly at compile time
        • Compiler inlines small Java and Javascript methods
        • Devirtualizes most other method calls
        • And tons more, too many to list….
      • Smaller
        • Prunes and eliminates anything not used
        • Aggressively obfuscates code
          • Obfuscated identifiers chosen to maximize DEFLATE compression
        • Replace runtime operations with compile time
    “ Faster and Smaller than Possible” Code
  6. GwtQuery (aka GQuery)
      • JQuery-like API in GWT
      • Uses GWT 1.5 language features for succinct code
      • Run-time CSS3 Selector parsing and evaluation
      • Compile-time CSS3 Selector parsing
      • Leverages modern browser features when available:
        • XPath ( document.evaluate )
        • W3C CSS Selector API ( document.querySelectorAll )
        • getElementsByClassName()
  7. GwtQuery Example Runtime Evaluation
    • Find all “menus”, make first element text “Hello”
    import gwtquery.client.GwtQuery; import static gwtquery.client.GwtQuery.$; public class GwtQueryModule implements EntryPoint { public void onModuleLoad() { $( “ul.menu > li:first-child” ).html(“hello”); } }
  8. GwtQuery Example What does the $(selector) function translate into?
    • On Safari 3.1
    • document.querySelectorAll(selector)
    • On Firefox, Opera, older Safari
    • Lots of Regexp parsing to compute xpathExpression
    • document.evaluate(xpathExpression)
    • On IE < 8 and others, a bunch of Regexp and DOM calls
    • Note: Each browser gets separately compiled JS
  9. Digression: Generators
    • Feature of Deferred Binding Mechanism
    • GWT.create(RequestedType.class)
    • Replace requested type with generated implementation
    • Turns into new GeneratedType()
  10. GwtQuery Example Compile-time parsing
    • Selectors usually literal strings, known at compile time
    • Why parse and translate these at runtime?!
    • Perform parsing and translation to XPath or JS-DOM navigation calls at compile-time
    public MySelectors extends Selectors { @Selector ( “ul.menu > li:first-child” ) GQuery allFirstMenuItems (); } MySelectors selector = GWT.create ( MySelectors.class ); selector. allFirstMenuItems ().html(“hello”);
  11. GwtQuery Example Compile-time parsing
    • GWT.create(MySelectors.class) triggers Generator
    • Different Generator for each browser (DOM, XPath, etc)
    • Generator creates implementation of MySelectors interface
    • For each method with a @Selector annotation
    • Parses CSS Selector, emits implementation of method
    • Compiler inlines method, elides everything else
  12. GwtQuery Example Compile Time Parsing: Bottom Line ul > li:first-child becomes document.evaluate(“ul/li[position() = 1]”)
  13. GwtQuery Example How big is the output?
    • jQuery 1.2.3
    • ~3400 lines of Javascript
    • 98kb unprocessed source
    • 15kb obfuscated and gzipped
    • GwtQuery
    • ~3400 lines of Java
    • 116kb on disk
    • How big is it compiled?
    • 15kb or larger?
    • How about 7kb, a 50% reduction?
    • 3kb sounds about right!
    • 712 bytes is the answer!
    • Smaller than single packet, HTTP headers
  14. Caveats and Objections
    • Trivial example
    • More reasonable example would exercise larger part of API
    • and reduce amount of pruned code
    • Example shows how aggressive GWT optimizer is
    • past GWT critics have used Hello World examples to demonstrate purported “bloat”
  15. Demo: Progressively Enhancing <UL> into PowerPoint-like slide transitions Sample Code < div class =&quot; slide transition-fade&quot;> Slide 1 < ul class=&quot;transition-fade&quot;> < li > Point One </li> < li > Point Two </li> < li > Point Three </li> </ul> </div> < div class =&quot; slide transition-fade&quot;> Slide 2 < ul class=&quot;transition-appear&quot;> < li > Slide 2 Point One </li> < li > Slide 2 Point Two </li> < li > Slide 3 Point Three </li> </ul> </div>
  16. GwtQuery code Sample Code for Selectors needed interface Slide extends Selectors { // find all LI elements rooted at ctx @Selector ( &quot;li&quot; ) NodeList<Element> slideBulletsCtx ( Node ctx ); // Find all DIV elements with class 'slide' @Selector ( &quot;div.slide&quot; ) NodeList<Element> allSlides (); }
  17. GwtQuery code Sample Code for Event Handling final Slide s = GWT.create ( Slide.class ) ; $(Document.get().getBody()).click(new Function() { int curSlide = 0; int curBullet = 0; GQuery slides = $(s. allSlides() ); GQuery bullets = $(s. slideBulletsCtx( slides.get(curSlide) ) ); public boolean f(Event e) { if (curBullet < bullets.size()) bullets.eq(curBullet++).as(Effects).fadeIn(); else bullets.css(&quot;opacity&quot;,&quot;0&quot;); slides.eq(curSlide).css(&quot;display&quot;, &quot;none&quot;); curSlide++; if(curSlide == slides.size()) curSlide = 0; curBullet = 0; bullets = $(s.slideBulletsCtx(slides.get(curSlide))); slides.eq(curSlide).css(&quot;display&quot;,&quot;block&quot;) .as(Effects).fadeIn(); return true; } });
  18. Sample of Generated Output for Selector “.slide li” W3C Selector API version public class SlideNativeImpl extends SelectorEngine implements MySelectors { public final NodeList<Element> slideBullets() { return querySelectorAll ( &quot;.slide li&quot; ); } }
  19. Sample of Generated Output for Selector “.slide li” XPath Version public class SlideXPathImpl extends SelectorEngine implements Slide { public final NodeList<Element> slideBullets() { return xpathEvaluate ( &quot;./descendant::*[contains(concat(' ', @class, ' '), ' slide ')]/descendant::li&quot; ); } }
  20. GWT Query
    • Alpha Released Today
    • Available at http://gwtquery.com
    • Help Contribute to Core and Plugins!
  21. High Performance Graphics
  22. Extreme Graphics Performance
    • Immediate Mode vs Retained Mode
      • Canvas vs SVG/VML
    • JS VMs top out at between 1000-10000 method calls on Canvas
    • Can we cache/reuse work?
    • Take a page from OpenGL’s Playbook: Display Lists
  23. Extreme Graphics Performance: Display Lists
    • Record a sequence of draw calls
    • Replay sequence like a macro
    • Framework/driver can perform optimizations
      • Collapse sequence of scale/rotate/translate operations into setTransform call
      • Cull/Clip some operations if possible
      • Cache result as bitmap where possible
    • DEMO!
  24. Extreme Graphics Performance and Flexibility: Chronoscope Chart Library Chronoscope Chart Library
    • 20,000 lines of code
      • 500kb of source
      • compiles to 58kb compressed
    • 30,000+ points at interactive rates
    • Javascript, Flash, Applet, Servlet, and Android
    • Multi-grained API
      • Full control with Java+GWT
      • Higher level with Javascript API
      • Or with no coding at all via Microformats and CSS
    • DEMO!
  25. Some insights from porting to GWT 1.5
    • Method inlining yields up to 100% perf gains
    • Ability to inline JSNI provided huge gains for IE/Flash version
    • Slight increase in size
    • Abstractions don’t hurt much
    • Beware usage of long, costs of non-double types
    • Static initializers can be harmful
  26. Chronoscope and Mobile Code with GWT
    • Platform neutral code
    • Only 4 classes needed to run in other environments or on the “cloud”
      • Flash, Android, Applet, Servlet
    • GWT methods automatically exported to Javascript via GWT-Exporter library
  27. Integrating GWT with other Environments
  28. Integrating GWT with other environments
    • GWT already integrates with Servlets
    • JSNI is used to integrate with Browser/JS
    • Extend RPC model to arbitrary containers
      • Android
      • Flash
      • Gears Workers
  29. Example: Syndroid Gadgets can span many Platforms Android iGoogle OSX Google Desktop Yahoo And many Flash widget startups
  30. Example: Syndroid
    • Synthesis of Android and GWT
    • Write Gadgets to a restricted API
    • Compile to Javascript or Dalvik or (later) Actionscript
    • Deploy on Android, iGoogle, OSX, Yahoo, et al
    • Prototype DEMO!
  31. Example: Android Native Interface What if Android browser had a window.locationService object? public class LocationServiceClient implements LocationService { public native String getLocation() /*-{ return $wnd. locationService . getLocation() ; }-*/; }
  32. Generators + Linkers = Awesomeness
    • Define RPC interface (sync or async)
    • Use Generator to generate client stub
      • Params may or may not need to be serialized
    • Also generate “server” to handle request
    • “ Server” handling code may need bootstrapping
    • Linker used to generate bootstrap code
    • If needed, use Linker to package/compile
  33. Android Native Interface AndroidNativeInterface LocationService String getLocation(); extends LocationServiceClient String getLocation() { return $wnd.locationService.getLocation(); } implements Emitted by Generator LocationServiceImpl String getLocation() { return ...android native code... } impl Written by Developer Android Bootstrap Bind LocationServiceImpl to window.locationService Provided by Linker
  34. Example: Android Native Interface Synchronous RPC public interface AndroidNativeInterface {} @ANIBinding ( &quot;locationService&quot; ) @ImplementedBy ( &quot;LocationServiceImpl&quot; ) public interface LocationService extends AndroidNativeInterface { String getLocation (); }
  35. Example: Android Native Interface Implement Android side (not legal GWT code!) public class LocationServiceImpl implements LocationService { public String getLocation () { try { Location currentLocation = ((LocationManager) context.getSystemService(Context.LOCATION_SERVICE)) .getCurrentLocation(&quot;gps&quot;); return &quot;Lat: &quot;+currentLocation.getLatitude()+ &quot;, Long: &quot;+currentLocation.getLongitude() ; } catch (Throwable e) { return &quot;ExceptionInNativeAndroid:&quot;+e.getClass().getName()+&quot;: &quot;+e.getMessage(); } } }
  36. Example: Android Native Interface To use LocationService service = GWT.create ( LocationService.class ); Window.alert(“Your location is: “+ service.getLocation() );
  37. Example: Linker Generated BootstrapActivity LocationServiceImpl gets exposed as window.locationService public class BootstrapActivity extends Activity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(getBootstrapView()); } public WebView getBootstrapView() { WebView wv=new WebView(this); wv.getSettings().setJavaScriptEnabled(true); wv.getSettings().setUseDesktopUserAgent(true); wv.getSettings().setLoadsImagesAutomatically(true); wv.addJavascriptInterface(new ContactsServiceImpl(this), &quot;contactsService&quot;); wv.addJavascriptInterface(new LocationServiceImpl (this), &quot;locationService&quot; ); wv.loadUrl(&quot;file:///android_asset/index.html&quot;); return wv; } } @ImplementedBy @ANIBinding
  38. Example: Linker Generated Manifest Needed by Android <manifest xmlns:android=&quot; http://schemas.android.com/apk/res/android &quot; package=&quot;syndroid.demo.SyndroidDemo&quot;><uses-permission android:name=&quot;android.permission.ACCESS_LOCATION&quot;/><uses-permission android:name=&quot;android.permission.ACCESS_GPS&quot;/><uses-permission android:name=&quot;android.permission.ACCESS_ASSISTED_GPS&quot;/> <application> <activity android:name=&quot;BootstrapActivity&quot; android:label=&quot;SyndroidDemo&quot;> <intent-filter> <action android:name=&quot;android.intent.action.MAIN&quot;/> <category android:name=&quot;android.intent.category.LAUNCHER&quot;/> </intent-filter> </activity> </application></manifest>
  39. Example: Linker Generated Build Script Used to compile and package APK file mkdir resmkdir classes $ANDROID_HOME/tools/aapt compile -m -J src -M AndroidManifest.xml -I $ANDROID_HOME/android.jar find src -name '*.java' -print >src.list javac -cp $ANDROID_HOME/android.jar @src.list -d classes $ANDROID_HOME/tools/dx -JXmx384M --dex --output=classes.dex -- locals=full --positions=lines classes/ $ANDROID_HOME/tools/aapt package -f -c -M AndroidManifest.xml -A assets -I $ANDROID_HOME/android.jar SyndroidDemo.apk zip SyndroidDemo.apk classes.dex
  40. Client Stub Generator
    • Use @ ImplementedBy annotation to find Android implementing class
    • Copy this class as resource (for Linker step)
    • Generate new Client stub
      • Generate JSNI native method on Client Stub
      • JSNI method invokes Javascript object named by @ANIBinding annotation
  41. Generator to Linker Communication
    • Generators work on types, can’t see build artifacts (compiler output)
    • Linkers work out build artifacts, can’t explore the type system
    • Some Linkers need type information
      • e.g. Bootstrap scripts, manifests
    • Communicate with linker by emitting a build artifact (e.g. text file)
    • Linker can scan for this special file and read contents
    • In our case, we write out mapping of @ANIBinding to @ImplementedBy
  42. Using Linker Generate Bootstrap/Package for APT
    • Read info from Generator (ANIBindings/ImplementedBy)
    • Copy implementation classes to build dir
    • Copy public resources to assets dir
    • Generate Android Manifest.xml
    • Generate Android Bootstrap Activity
      • Set WebView as view
      • Enable Javascript
      • For each ANIBinding, bind instance of implementing class to Javascript
    • Run Android Tools
      • javac
      • dx
      • aapt to create final .apt
  43. Future Directions
    • Use Special GWT bootstrap script to detect Android browsers
    • Offer user choice of “over the air” provision of Android-specific app
    • See http://timepedia.blogspot.com/2008/01/project-syndroidsynthesis-of-gwt-and.html for detailed architecture
  44. Compiling GWT to Flash
  45. Reusing the same Design Pattern for Flash
    • Define ActionScriptNativeInterface
    • Place all “Flash” java code in .flash package
      • Use generator to copy it to output as a resource
    • Use Generator to create JSNI stubs to invoke Flash methods
    • But how do we turn Java code into SWF for the server side?
  46. ActionScript Native Interface ActionScriptNativeInterface DrawService void drawLine(x,y); extends DrawServiceClient void drawLine(int x, int y) { $wnd.flashPlugin.drawLine(x, y); } implements Emitted by Generator package foo.flash; native void drawLine(int x, int y) /*-{ ... actionscript code to draw line ... }-*/; impl Written by Developer Flash Bootstrap generate main() Export drawLine(x,y) via ExternalInterface Provided by Linker
  47. Compiling Java to ActionScript with GWT
    • IDEA: Invoke GWT compiler recursively
    • Use Linker to create new GWT Project
    • Copy “flash” Java code to source path
    • Emit Module.gwt.xml file
    • Generate entrypoint
      • For each ActionScriptNativeInterface add ExternalInterface
    • Invoke GWT Compiler to produce SWF?
    • Emit SWF as output artifact
  48. Packaging GWT output as SWF?
    • GWT Compiler produces JS
    • Avoid GWT APIs which call DOM JSNI methods
      • JRE generally safe
    • Use Linker to
      • add custom bootstrap script to invoke EntryPoint
      • invoke Flex3 SDK in non-strict mode
      • Emit resulting SWF as output artifact
    • Generator+Linker+Generator+Linker Pattern
  49. Writing Gears Workers in GWT
    • Reuse same pattern as Flash
      • e.g. place Gears-translatable Java in ‘.gears’ package
    • Use Async RPC interfaces
    • JSON to marshal simple object types to Gears and back
    • Use SSO-like Linker
  50. Q&A?
    • GwtQuery available at
      • http://gwtquery.com
    • Chronoscope available
      • http://timepedia.org
    • For in-depth articles/code, see blog at:
      • http://timepedia.blogspot.com
    • Upcoming articles on Syndroid, and ActionScriptNativeInterface
  51.  

+ cromwelliancromwellian, 2 years ago

custom

9456 views, 12 favs, 6 embeds more stats

In this session, see Google Web Toolkit used in exo more

More info about this document

© All Rights Reserved

Go to text version

  • Total Views 9456
    • 8536 on SlideShare
    • 920 from embeds
  • Comments 1
  • Favorites 12
  • Downloads 173
Most viewed embeds
  • 910 views on http://timepedia.blogspot.com
  • 4 views on http://www.feedbite.com
  • 2 views on https://craftler.dyndns.org:1111
  • 2 views on http://feeds.feedburner.com
  • 1 views on http://localhost

more

All embeds
  • 910 views on http://timepedia.blogspot.com
  • 4 views on http://www.feedbite.com
  • 2 views on https://craftler.dyndns.org:1111
  • 2 views on http://feeds.feedburner.com
  • 1 views on http://localhost
  • 1 views on http://203.208.39.132

less

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

Cancel
File a copyright complaint
Having problems? Go to our helpdesk?

Categories