{"id":575,"date":"2010-03-05T23:00:15","date_gmt":"2010-03-06T05:00:15","guid":{"rendered":"http:\/\/www.mooreds.com\/wordpress\/archives\/000575"},"modified":"2010-03-05T23:00:15","modified_gmt":"2010-03-06T05:00:15","slug":"gwt-widgets-and-code-splitting-a-match-made-in-heaven","status":"publish","type":"post","link":"https:\/\/www.mooreds.com\/wordpress\/archives\/575","title":{"rendered":"GWT widgets and code splitting, a match made in heaven"},"content":{"rendered":"<p>If you are writing a typical GWT application, which is monolithic and controls the entire viewport of the browser, you probably don&#8217;t want to read this post.\u00a0 Go on, read something else interesting&#8211;you probably have emails or tweets or something better to do with your time.<\/p>\n<p>OK, now we just have the people left who are using GWT to build widgets; that is small encapsulated pieces of functionality that integrate into an existing web based application (<a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/000440\">case #2 outlined here<\/a>).\u00a0 If you&#8217;re doing this, and you use the <a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/000448\">&#8220;span to enable&#8221;<\/a> gwt mini pattern, you want to upgrade to GWT 2.0 simply to get the <a href=\"http:\/\/code.google.com\/webtoolkit\/doc\/latest\/DevGuideCodeSplitting.html\">new code splitting functionality<\/a>.\u00a0 If you don&#8217;t want to read that previous link, the synopsis is that code splitting lets you define a number of pieces of distinct code, using <code>GWT.runAsync<\/code>.\u00a0 Then, that code won&#8217;t be downloaded until it is reached.<\/p>\n<p>Previous to this feature, if you had a number of widgets, you ended up with a large chunk of code to download on every page (this is an issue with GWT that the monolithic applications simply don&#8217;t have to deal with).\u00a0 Some of that code will be run.\u00a0 Some will not, but you&#8217;re still paying for download and parsing of that code.\u00a0 You had some unsavory options to deal with this&#8211;let all the code be downloaded, or manually split up code into separate modules that you managed (either by hand or with deferred binding).\u00a0 The second solution led to smaller downloads, but meant a lot more management&#8211;if you wanted to add a widget to a page, you not only had to add the enabling span, you had to recompile the entire GWT module&#8211;and much longer compilation when you deployed your entire web application.\u00a0 However, if your widgets were static, this path might have been an option.<\/p>\n<p>My client used the former solution (entire code download on every page), and was very excited about the code splitting, since that essentially automates the second choice above.\u00a0 In the space of about one half hour, I was able to reduce the initial download size of the GWT javascript by 10%, and there&#8217;s scope for much more, since the code is pretty naturally split up into separate chunks for each widget.<\/p>\n<p>It&#8217;s not perfect, however. The two concerns I&#8217;ve had so far:<\/p>\n<ol>\n<li>The XS linker is not supported.\u00a0 This means that if any of your widgets need to be cross domain, you need to create an additional module specifically for that.\u00a0 For example, if I have one module, A, which is used to start up all the widgets on the site, and inherits from both module B, which has some GWT code split calls, and module C, which needs to be cross domain, the compiler will error out when compiling module A.\u00a0 I need to create a second module XSModuleC which inherits from module C and is compiled by the XS linker, and then use that module for all cross domain purposes.<\/li>\n<li>If you call <code>GWT.runAsync<\/code> from an event handler, like onClick, you will not have a valid event on the first call (when the module is loaded) but will on all subsequent calls.\u00a0 This is easy to fix, but was a bit mystifying to me.\u00a0 Basically, if you have code like this:<\/li>\n<\/ol>\n<p><code \/><\/p>\n<pre>onClick(ClickEvent event) {\r\nif (event.getSource() instanceof Image) {\r\n\/\/ do something with image\r\n}\r\n}<\/pre>\n<p>you need to replace it with:<\/p>\n<p><code \/><\/p>\n<pre>onClick(ClickEvent event) {\r\nif (event.getSource() instanceof Image) {\r\n\/\/ save event.getSource into an instance variable\r\nGWT.runAsync(new RunAsyncCallback() {\r\n\/\/ do something with image in instance variable\r\n}\r\n}\r\n}<\/pre>\n<p>I'm sure there are other complications I'll find once I do more code splitting.\u00a0 (Here's an interesting post about <a href=\"http:\/\/jcheng.wordpress.com\/2010\/02\/16\/elegant-code-splitting-with-gwt\/\">code splitting in large applications, and simplifying the API of code that is split<\/a> (plus, you get to see the word cromulent in context).)\u00a0 But, for now, code splitting and GWT widget development seem like a match made in heaven.<br \/>\n[tags]gwt,code splitting[\/tags]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you are writing a typical GWT application, which is monolithic and controls the entire viewport of the browser, you probably don&#8217;t want to read this post.\u00a0 Go on, read [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18,37],"tags":[],"class_list":["post-575","post","type-post","status-publish","format-standard","hentry","category-gwt","category-tips"],"_links":{"self":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/575","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/comments?post=575"}],"version-history":[{"count":0,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/575\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/media?parent=575"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/categories?post=575"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/tags?post=575"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}