{"id":589,"date":"2010-07-12T15:43:04","date_gmt":"2010-07-12T21:43:04","guid":{"rendered":"http:\/\/www.mooreds.com\/wordpress\/archives\/000589"},"modified":"2010-07-16T08:03:50","modified_gmt":"2010-07-16T14:03:50","slug":"more-on-code-splitting-and-gwt","status":"publish","type":"post","link":"https:\/\/www.mooreds.com\/wordpress\/archives\/589","title":{"rendered":"More on code splitting and GWT"},"content":{"rendered":"<p>Code splitting is one of the features of GWT that make it worth your while.\u00a0 See, using GWT is really a choice&#8211;do you want to use one of the lightweight javascript libraries like jquery, with all the agility that implies, or do you want to use GWT which lets you leverage all kinds of java tools and optimizations, but saddles you with a compile cycle?<\/p>\n<p>I&#8217;ve talked before about the situations that I think are <a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/000440\">good fits for GWT<\/a>.\u00a0 I just re-read that post and don&#8217;t feel that things have changed too much in the past 3 years, though I might argue with point 4 of that post.\u00a0 <a href=\"http:\/\/code.google.com\/webtoolkit\/doc\/latest\/DevGuideCodeSplitting.html\">Code splitting<\/a> is an optimization that would be hard to do with a more normal javascript library (dojo has something like it, but it looks like <a href=\"http:\/\/docs.dojocampus.org\/quickstart\/custom-builds\">you are responsible for maintaining dependencies<\/a>).<\/p>\n<p>I talked before about code splitting, and how <a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/000575\">it is a great fit<\/a> for the widget based html enhancing GWT development that I&#8217;ve done a lot of recently.\u00a0 I wanted to talk a bit more about my process for finding code to split.<\/p>\n<p><strong>With code splitting, the main goal is &#8220;never have the user download javascript that isn&#8217;t used&#8221;.<\/strong><\/p>\n<p>The first thing to do is run your GWT compile with the -compileReport option, as <a href=\"http:\/\/code.google.com\/webtoolkit\/doc\/latest\/DevGuideCompileReport.html\">outlined here<\/a>. This will show you your module code, and therefore let you focus your effort where it makes sense.<\/p>\n<p>The second thing to do is to find code dependencies.\u00a0 The compile report shows you that in a text format if you navigate all the way down to the class level in a class that is downloaded in the inital fragment via the &#8220;see why&#8221; link.\u00a0 I had a hard time understanding those dependency lists, so I went looking for a tool to help.\u00a0 After trying a number of <a href=\"http:\/\/java-source.net\/open-source\/code-analyzers\">open source dependency analyzers<\/a>, I stumbled on the <a href=\"http:\/\/www.dependency-analyzer.org\/\">Class Dependency Analyzer (CDA)<\/a> which is free as in beer, not as in speech.\u00a0 The key difference between this tool and others was its included <a href=\"http:\/\/www.mooreds.com\/files\/samplegraph.jpg\">dependency graphs<\/a>.\u00a0 You should set CDA up to ignore all the google code, as well as any third party tools you have.\u00a0 More <a href=\"http:\/\/www.dependency-analyzer.org\/#QuickStart\">documentation on CDA here<\/a>.\u00a0 (This is another example of leveraging java&#8217;s tool set.)<\/p>\n<p>Using CDA, you can see which packages (since modules are grouped in a java package) have dependencies on others.\u00a0 Packages that don&#8217;t have dependencies on any of your other packages are great candidates for code splitting, as well as packages that depend on other packages that are code split.\u00a0 However, if your packages depend on utility classes, especially those that share business logic between client and server side code, that&#8217;s OK.\u00a0 (This exercise can also help in general code quality.)<\/p>\n<p>Now you have a number of candidate modules.\u00a0 The next thing to do is dive into the code and see if these modules execute on every page.\u00a0 If they do, then doing code splitting is not a win.\u00a0 All you&#8217;ve done is forced GWT to make an extra network call.\u00a0 If, on the other hand, this code only executes when someone clicks a button or takes some other action, then you have a great candidate for code splitting.\u00a0 And if the module only executes on certain pages (perhaps using a <a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/000448\">DOM element to signal whether it should execute or not<\/a>), you have a good candidate&#8211;because with splitting that code will never be download on pages where it is not used.<\/p>\n<p>Now, add the following code around the candidates:<\/p>\n<pre>GWT.runAsync(new RunAsyncCallback() {\r\npublic void onFailure(Throwable caught) {\r\n\/\/ handle error\r\n}\r\n\r\npublic void onSuccess() {\r\n\/\/ do something\r\n}\r\n}<\/pre>\n<p>I actually added this code block to my eclipse templates ( more on <a href=\"http:\/\/firstclassthoughts.co.uk\/java\/eclipse_tip_templates_public_static_final.html\">templates here<\/a>) so it is super easy to set up a split point.\u00a0 Note that I haven&#8217;t found a generic good action to take on failure.\u00a0 For most widgets providing enhanced functionality, a safe fallback might be to just let the HTML execute.\u00a0 A custom message display might be ignored, and using <code>Window.alert<\/code> can confuse your users (and lock up a browser for a time if all of your code or the network suddenly becomes unavailable).<\/p>\n<p>The next step is to run the compile report again and see if the GWT compiler agrees with you that your candidate code is not reachable by any other path.\u00a0 If it does, you should see split points show up underneath the permutations menu.\u00a0 (BTW, the -compileReport flag easily doubles or triples the time it takes to compile GWT&#8211;I&#8217;d recommend focusing on one user-agent and doing other things to speed up your compile, as <a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/000574\">outlined here.<\/a>)\u00a0 You can also test this by just compiling your GWT without the -compileReport switch and looking under the deferredjs directory; it is quicker but doesn&#8217;t help you determine which modules are being downloaded.\u00a0 Firebug also lets you see the files downloaded on demand.<\/p>\n<p>I was able to decrease the initial download size of a project I&#8217;m working on by 20%.<\/p>\n<p>I&#8217;ve mentioned the <a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/000440\">caveats before<\/a> but they are worth mentioning again.<\/p>\n<ul>\n<li>The XS linker is not supported, so if any of your XS modules depend on a module which has code splitting, you&#8217;ll find out when your GWT does not compile.\u00a0 However, there is hope&#8211;<a href=\"http:\/\/code.google.com\/p\/google-web-toolkit\/issues\/detail?id=5046\">code splitting support for the XS linker is apparently coming with GWT 2.1<\/a>.\u00a0 If you need this functionality, vote for the bug.\u00a0 There are some work arounds in the meantime, but they involve a fair bit of hoop jumping so I&#8217;m going to avoid documenting them.<\/li>\n<li>Events that happen before code is asynchronously downloaded are not propagated to that code.<\/li>\n<\/ul>\n<p>Given the second issue, it&#8217;s important to test your code and make sure that the behavior is unchanged.\u00a0 That&#8217;s the final step.<\/p>\n<p>I hope this was a useful tour of the GWT code splitting process.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Code splitting is one of the features of GWT that make it worth your while.\u00a0 See, using GWT is really a choice&#8211;do you want to use one of the lightweight [&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],"tags":[],"class_list":["post-589","post","type-post","status-publish","format-standard","hentry","category-gwt"],"_links":{"self":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/589","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=589"}],"version-history":[{"count":1,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/589\/revisions"}],"predecessor-version":[{"id":591,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/589\/revisions\/591"}],"wp:attachment":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/media?parent=589"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/categories?post=589"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/tags?post=589"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}