Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Turducken
Divide and conquer large GWT apps with
multiple teams

Rob Keane
Google / Ad Exchange Front End
rkeane@google.co...
Turducken
Complex GWT apps can involve multiple teams with
different release cycles. Compile times can quickly
become proh...
A note on the name...

Turkey + Duck + Chicken
For this...

...not this
Large projects
Multiple...
teams?
release cycles?
testers?
frameworks?
Terminology
In the context of this talk...

Module == GWT Module with entry point
One last note...
This is a design pattern not a library
Turducken
1. Bob’s Sticker Emporium
2. Conquering Multiple Entry Points
3. Other uses
Bob’s GWT App
Bob has a sticker site
bobs-sticker-emporium.com

BOB’S STICKERS
Stickers

BUY!

BUY!

BUY!
Success!
Bob adds more options...
bobs-sticker-emporium.com

Your Cart (2)

BOB’S STICKERS
Stickers

Create your own!

BUY...
Things are getting complex
➔ Still one giant GWT module
➔ Compilation takes several minutes
➔ A few megabytes of JS
➔ 5 te...
What should Bob do?
How do you split up a large GWT project?
One GWT module
× One release
× One build
× Very large if code isn’t split properly
× Difficult to test
Many GWT modules
× Full page reloads
× Code can’t be split between modules
One GWT module?

ಠ_ಠ

Many GWT modules?

ಠ_ಠ
Ultimately multiple GWT modules
is the only real option
Multiple modules
Split into multiple GWT entry points
bobs-sticker-emporium.com

Your Cart (2)

BOB’S STICKERS
Stickers

C...
Bob

Full page refresh
between each module
Research showed that

half of aggregate user latency
was due to full page reloads
Turducken
1. Bob’s Sticker Emporium
2. Conquering Multiple Entry Points
3. Other uses
Container (GWT Module)
Inter-app Event Bus (JSNI)
Virtual
historian

Virtual
historian

Virtual
historian

Tab A

Tab B

T...
The container
➔
➔
➔
➔

A GWT module (mostly)
The first thing to load on the page
Loads the other modules on demand
Communi...
Loading all of the modules?

Yes.
This actually works
Bob’s container
bobs-sticker-emporium.com

Your Cart (2)

BOB’S STICKERS
Stickers

Create your own!

Sell a sticker!

BUY!
Load multiple GWT modules?
➔ When a module is loaded, a <script> tag is added to
the <head>
➔ Everything lives in the same...
Memory usage
➔ Browsers are good at hiding elements
➔ Memory only increases marginally when
loading new modules
DOM Assumptions
// Old
RootPanel.get().add(myRootWidget);

// New
ContainerHelper.getModulePanel().add(myRootWidget);

<bo...
CSS
➔ Avoid @external as much as possible
➔ Avoid styling tags
... unless the style is truly global
➔ Should be in a “glob...
But I really want @external CSS...
When Module “TAB_1” is loaded →

When Module “TAB_2” is loaded
→
CSS example
/* no, no, no */
@external .title;
.title {
color: pink;
font-size: 72px;
}

/* that’s better */
@external .ti...
There’s just one tiny, little issue...
“

All problems in computer
science can be solved by
another level of indirection

Butler Lampson
Container (GWT Module)
Inter-app Event Bus (JSNI)
Virtual
historian

Virtual
historian

Virtual
historian

Tab A

Tab B

T...
Virtual History Implementation
An history implementation that doesn’t alter
the “real” URL but instead sends an event
Container History
Produces a “safe” URL that contains
information about the module
For example:
#MODULE_A/MyPlace
instead ...
Container (GWT Module)
Inter-app Event Bus (JSNI)
Virtual
historian

Virtual
historian

Virtual
historian

Tab A

Tab B

T...
Event bus implementation
The event bus that broadcasts between
modules needs to be JSNI since it must
communicate between ...
Code example
// Container
InterAppEventBus.subscribe(“HISTORY_CHANGE”, updateUrlHandler);
// Virtual History in a submodul...
Message trace for history
Virtual Historian

Event bus

Container

Browser

Change to virtual history

Module load event

...
Summary of Turducken
➔ Separate your app into multiple entry points
➔ A container module manages loading the
submodules
➔ ...
The future
➔ Shadow DOM eliminates a lot of the issues
➔ Eliminate JSNI with GWT 3.0
But wait!
There’s more.
Turducken
1. Bob’s Sticker Emporium
2. Conquering Multiple Entry Points
3. Other uses
It’s all about the event bus
An inter-app event bus opens up some
interesting doors
Inter-app communication
Load another module via an event
➔ Settings Module
◆ Change settings from other modules
◆ Global “...
Example
➔ One team maintains “Chat” functionality
➔ Another team maintains a “Profile” page
➔ Launch a chat with a person ...
Invisible Modules
There can be “background” modules that
aren’t visible but handle events
➔ Monitoring session
➔ Caching d...
Non-GWT “modules”
➔ Follow the same CSS approach
➔ Write an virtual history implementation
➔ Add hashPrefix to $location i...
Where’s the code?
➔ A few small parts
➔ A design pattern, not a library
➔ Tends to be application specific
...but we are c...
Turducken
Complex GWT apps can involve multiple teams with
different release cycles. Compile times can quickly
become proh...
no reloads
many modules

wow

such performance
different releases

wow

Questions?
Turducken - Divide and Conquer large GWT apps with multiple teams
Upcoming SlideShare
Loading in …5
×

Turducken - Divide and Conquer large GWT apps with multiple teams

5,435 views

Published on

Complex GWT apps can involve multiple teams with different release cycles. Compile times can quickly become prohibitive when your codebase grows into millions of lines. “Turducken” is a technique to combine multiple GWT apps that can be built and released by separate teams while providing a seamless, snappy user experience.

Published in: Technology, Self Improvement

Turducken - Divide and Conquer large GWT apps with multiple teams

  1. 1. Turducken Divide and conquer large GWT apps with multiple teams Rob Keane Google / Ad Exchange Front End rkeane@google.com
  2. 2. Turducken Complex GWT apps can involve multiple teams with different release cycles. Compile times can quickly become prohibitive when your codebase grows into millions of lines. “Turducken” is a design pattern to combine multiple GWT apps that can be built and released by separate teams while providing a seamless, snappy user experience
  3. 3. A note on the name... Turkey + Duck + Chicken
  4. 4. For this... ...not this
  5. 5. Large projects Multiple... teams? release cycles? testers? frameworks?
  6. 6. Terminology In the context of this talk... Module == GWT Module with entry point
  7. 7. One last note... This is a design pattern not a library
  8. 8. Turducken 1. Bob’s Sticker Emporium 2. Conquering Multiple Entry Points 3. Other uses
  9. 9. Bob’s GWT App Bob has a sticker site bobs-sticker-emporium.com BOB’S STICKERS Stickers BUY! BUY! BUY!
  10. 10. Success! Bob adds more options... bobs-sticker-emporium.com Your Cart (2) BOB’S STICKERS Stickers Create your own! BUY! Customize BUY! Customize Sell a sticker! BUY! Customize
  11. 11. Things are getting complex ➔ Still one giant GWT module ➔ Compilation takes several minutes ➔ A few megabytes of JS ➔ 5 teams! ➔ Continuous integration ➔ Release coordination
  12. 12. What should Bob do? How do you split up a large GWT project?
  13. 13. One GWT module × One release × One build × Very large if code isn’t split properly × Difficult to test
  14. 14. Many GWT modules × Full page reloads × Code can’t be split between modules
  15. 15. One GWT module? ಠ_ಠ Many GWT modules? ಠ_ಠ
  16. 16. Ultimately multiple GWT modules is the only real option
  17. 17. Multiple modules Split into multiple GWT entry points bobs-sticker-emporium.com Your Cart (2) BOB’S STICKERS Stickers Create your own! BUY! Customize BUY! Customize Sell a sticker! BUY! Customize
  18. 18. Bob Full page refresh between each module
  19. 19. Research showed that half of aggregate user latency was due to full page reloads
  20. 20. Turducken 1. Bob’s Sticker Emporium 2. Conquering Multiple Entry Points 3. Other uses
  21. 21. Container (GWT Module) Inter-app Event Bus (JSNI) Virtual historian Virtual historian Virtual historian Tab A Tab B Tab C (GWT) (GWT) (GWT)
  22. 22. The container ➔ ➔ ➔ ➔ A GWT module (mostly) The first thing to load on the page Loads the other modules on demand Communicates with modules through inter-app event bus
  23. 23. Loading all of the modules? Yes. This actually works
  24. 24. Bob’s container bobs-sticker-emporium.com Your Cart (2) BOB’S STICKERS Stickers Create your own! Sell a sticker! BUY!
  25. 25. Load multiple GWT modules? ➔ When a module is loaded, a <script> tag is added to the <head> ➔ Everything lives in the same container
  26. 26. Memory usage ➔ Browsers are good at hiding elements ➔ Memory only increases marginally when loading new modules
  27. 27. DOM Assumptions // Old RootPanel.get().add(myRootWidget); // New ContainerHelper.getModulePanel().add(myRootWidget); <body> <div id=”modules”> <div id=”TAB_1_ROOT”>...</div> <div id=”TAB_2_ROOT” style=”display:none”>...</div> <div id=”TAB_3_ROOT” style=”display:none”>...</div> </div> </body>
  28. 28. CSS ➔ Avoid @external as much as possible ➔ Avoid styling tags ... unless the style is truly global ➔ Should be in a “global” CSS file > global.css a { color: #999; }
  29. 29. But I really want @external CSS... When Module “TAB_1” is loaded → When Module “TAB_2” is loaded →
  30. 30. CSS example /* no, no, no */ @external .title; .title { color: pink; font-size: 72px; } /* that’s better */ @external .title; #TAB_1 .title { color: pink; font-size: 72px; }
  31. 31. There’s just one tiny, little issue...
  32. 32. “ All problems in computer science can be solved by another level of indirection Butler Lampson
  33. 33. Container (GWT Module) Inter-app Event Bus (JSNI) Virtual historian Virtual historian Virtual historian Tab A Tab B Tab C (GWT) (GWT) (GWT)
  34. 34. Virtual History Implementation An history implementation that doesn’t alter the “real” URL but instead sends an event
  35. 35. Container History Produces a “safe” URL that contains information about the module For example: #MODULE_A/MyPlace instead of #MyPlace
  36. 36. Container (GWT Module) Inter-app Event Bus (JSNI) Virtual historian Virtual historian Virtual historian Tab A Tab B Tab C (GWT) (GWT) (GWT)
  37. 37. Event bus implementation The event bus that broadcasts between modules needs to be JSNI since it must communicate between GWT modules A simple publish/subscribe interface will do
  38. 38. Code example // Container InterAppEventBus.subscribe(“HISTORY_CHANGE”, updateUrlHandler); // Virtual History in a submodule InterAppEventBus.publish(“HISTORY_CHANGE”, “myNewUrl”);
  39. 39. Message trace for history Virtual Historian Event bus Container Browser Change to virtual history Module load event Real URL is changed
  40. 40. Summary of Turducken ➔ Separate your app into multiple entry points ➔ A container module manages loading the submodules ➔ Carefully manage your CSS ➔ The submodules talk to a virtual historian ➔ A JavaScript/JSNI InterAppEventBus handles events between modules and the container ➔ Events are broadcast that the container handles to alter the real URL
  41. 41. The future ➔ Shadow DOM eliminates a lot of the issues ➔ Eliminate JSNI with GWT 3.0
  42. 42. But wait! There’s more.
  43. 43. Turducken 1. Bob’s Sticker Emporium 2. Conquering Multiple Entry Points 3. Other uses
  44. 44. It’s all about the event bus An inter-app event bus opens up some interesting doors
  45. 45. Inter-app communication Load another module via an event ➔ Settings Module ◆ Change settings from other modules ◆ Global “Accept ToS” message ➔ Chat module
  46. 46. Example ➔ One team maintains “Chat” functionality ➔ Another team maintains a “Profile” page ➔ Launch a chat with a person from their profile ➔ Chat module doesn’t always need to be loaded ➔ Limited coupling between modules
  47. 47. Invisible Modules There can be “background” modules that aren’t visible but handle events ➔ Monitoring session ➔ Caching data for multiple modules
  48. 48. Non-GWT “modules” ➔ Follow the same CSS approach ➔ Write an virtual history implementation ➔ Add hashPrefix to $location in Angular
  49. 49. Where’s the code? ➔ A few small parts ➔ A design pattern, not a library ➔ Tends to be application specific ...but we are considering it
  50. 50. Turducken Complex GWT apps can involve multiple teams with different release cycles. Compile times can quickly become prohibitive when your codebase grows into millions of lines. “Turducken” is a design pattern to combine multiple GWT apps that can be built and released by separate teams while providing a seamless, snappy user experience
  51. 51. no reloads many modules wow such performance different releases wow Questions?

×