{"id":679,"date":"2011-01-08T14:39:53","date_gmt":"2011-01-08T20:39:53","guid":{"rendered":"http:\/\/www.mooreds.com\/wordpress\/?p=679"},"modified":"2011-01-08T14:39:53","modified_gmt":"2011-01-08T20:39:53","slug":"gwt-code-splitting-process-tips","status":"publish","type":"post","link":"https:\/\/www.mooreds.com\/wordpress\/archives\/679","title":{"rendered":"GWT Code Splitting Process Tips"},"content":{"rendered":"<p>I have <a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/589\">written before<\/a> about <a href=\"http:\/\/code.google.com\/webtoolkit\/doc\/latest\/DevGuideCodeSplitting.html\">GWT code splitting<\/a>, a cool feature available in GWT.\u00a0 While I am definitely no expert, it seems to be different that options offered by other, comparable web toolkits.\u00a0 Just doing a quick survey (thanks, <a href=\"http:\/\/ajaxian.com\/index.php?s=compile\">Ajaxian<\/a>!), there seems to be a lot of code compilation happening.\u00a0 Some of it is at deployment, pruning unused library code (like <a href=\"http:\/\/dojotoolkit.org\/reference-guide\/build\/\">here<\/a>, and <a href=\"http:\/\/mootools.net\/core\/\">here<\/a>).\u00a0 Some of it is aimed at making whatever javascript you write, better (like <a href=\"http:\/\/developer.yahoo.com\/yui\/compressor\/\">this<\/a> and <a href=\"http:\/\/code.google.com\/closure\/compiler\/\">this<\/a>).\u00a0 There&#8217;s even <a href=\"http:\/\/google-caja.googlecode.com\/svn\/trunk\/doc\/html\/jskb.html\">tools aiming to document<\/a> (in json) all javascript features supported by browsers, so that you can intelligently target user agents.<\/p>\n<p>GWT code splitting is different from all of that.\u00a0 It is developer determined split points in javascript code.\u00a0 A developer says, essentially, all code after &#8216;this call&#8217; should be downloaded and made accessible to the runtime when &#8216;this call&#8217; is made.\u00a0 More at <a href=\"http:\/\/code.google.com\/webtoolkit\/doc\/latest\/DevGuideCodeSplitting.html\">the canonical reference<\/a>; you should read this multiple times if you want to really understand code splitting.<\/p>\n<p>As the document above mentions, &#8220;effective code splitting requires iteration&#8221;.\u00a0 I&#8217;ve spent a fair bit of time in the last week doing some code splitting, and wanted to share my punch list (and build on my previous <a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/589\">code splitting post<\/a>).<\/p>\n<p>First, understand the three major types of chunks your code will be split into.<\/p>\n<ul>\n<li>Initial download<\/li>\n<li>Leftover code<\/li>\n<li>Exclusive fragments<\/li>\n<\/ul>\n<p>The document above has a great diagram, which also includes other types of code which I have not run into.\u00a0\u00a0 The important thing to realize is that minimizing the initial download is important, but if any of the exclusive fragments are download, the leftover fragment will be downloaded.\u00a0 Therefore, a better goal is to maximize the exclusive fragment size.<\/p>\n<p>Here are places places to put split points, in order of preference<\/p>\n<ul>\n<li>subsystems easily isolated (encryption library, etc).\u00a0 Consider using the <a href=\"http:\/\/google-web-toolkit.googlecode.com\/svn\/javadoc\/2.1\/com\/google\/gwt\/user\/client\/AsyncProxy.html\">AsyncProxy<\/a>, which is a great way to hide a subsystem<\/li>\n<li>user actions (onclick events, etc).\u00a0 Be aware of latency when toe code is downloaded and executed<\/li>\n<li>when <a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/448\">enabling spans<\/a> are present<\/li>\n<\/ul>\n<p>Use GWT.runAsync directly.\u00a0 I tried to get all fancy with commands and abstracting it away, and didn&#8217;t have much success.\u00a0 You can surround it with a timer, though, and that<br \/>\nmay make sense when you are using an enabling span.<\/p>\n<p><code><\/p>\n<pre>if (span is present) {\r\nTimer t = new Timer() {\r\n\r\n@Override\r\npublic void run() {\r\nGWT.runAsync(new RunAsyncCallback() {\r\npublic void onFailure(Throwable caught) {\r\n\/\/ handle error\r\n}\r\n\r\npublic void onSuccess() {\r\nfoo();\r\n}\r\n});\r\n}\r\n};\r\nt.schedule(150); \/\/ wait 150 ms before trying to download this code\r\n}<\/pre>\n<p><\/code><\/p>\n<p>You will spend a lot of time compiling, so <a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/574\">only target a few browsers<\/a> for compilation.\u00a0 When I added the <code>-compileReport<\/code> option, the compile time for the main module went from 2 minutes to 8 minutes.\u00a0 However, once you have the url for the compile report (something like <code>\/extras\/modulename\/soycReport\/compile-report\/SoycDashboard-0-index.html<\/code>) you can actually see the results about a minute in.\u00a0 At that point, you can stop the compile process.<\/p>\n<p>Method call hunting will make you love your IDE java method search (control-H in eclipse&#8211;here&#8217;s a <a href=\"http:\/\/www.n0sl33p.org\/dev\/eclipse_keys.html\">useful cheat sheet<\/a>)<\/p>\n<p>Watch out for constants and static methods.\u00a0 In fact, I end up pulling out my constants to a class shared between GWT and my java server so that I can name spans like this<br \/>\n<code>&lt;div id=\"&lt;%=Constants.SCROLL_ANCHOR_ID%&gt;\"&gt;&lt;\/div&gt;<\/code> and be assured that GWT components will always be able to attach to those spans.<\/p>\n<p>If module A is called by module B, C and D, avoid putting the <code>GWT.runAsync<\/code> calls in modules B, C and D.\u00a0 This would force module A into the leftover code chunk, increases the number of split points, compilation time, and memory needs.\u00a0 Instead, put the <code>GWT.runAsync<\/code> calls into module A, which pushes all that code into an exclusive chunk.\u00a0 If you have a bunch of small splits points in your compile report, look at it carefully, especially if they are in the same class and see if you can push the split points back into the common code.<\/p>\n<p>Code splitting failures (<code>onFailure<\/code>) should be dealt with the same way any remote access failure is dealt with in your application.\u00a0 I haven&#8217;t found a more intelligent method than informing the user that the operation failed, however.<\/p>\n<p>Set goals for splitting and try to avoid getting sucked in.\u00a0 Because it is an iterative process, you can end up spending a lot of time with this.\u00a0 Sometimes changes can have counter intuitive side effects, so make sure you track both total, initial and leftover code chunk sizes.<\/p>\n<p>This post was based on a system with total obfuscated code size of approx 750kb, compiled using GWT 2.1.1.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have written before about GWT code splitting, a cool feature available in GWT.\u00a0 While I am definitely no expert, it seems to be different that options offered by other, [&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-679","post","type-post","status-publish","format-standard","hentry","category-gwt"],"_links":{"self":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/679","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=679"}],"version-history":[{"count":3,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/679\/revisions"}],"predecessor-version":[{"id":682,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/679\/revisions\/682"}],"wp:attachment":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/media?parent=679"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/categories?post=679"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/tags?post=679"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}