High Performance GWT. Part 1

    image
    This post is the beginning of a series of articles about optimizing and improving the performance of GWT applications. Since I have accumulated a lot of material, I decided to break it into 2-3 parts.
    We proceed to describe what awaits us in the first article.

    Questions to be addressed


    In the first part of a series of articles on optimizing GWT applications, I will talk about the following things:
    • Client code separation, on-demand download
    • Getting rid of the use of heavy classes on the client
    • Resource Caching
    • GWT RPC Performance Issues Using REST
    • Features of the impact of layout on the application
    • Transmission Optimization
    • Using Scheduler
    • Using dispatchers to aggregate server requests

    And now in detail about each of the mentioned points.

    Client code separation, on-demand download


    GWT has a built-in mechanism that allows the developer to "cut" the application into parts. This is necessary, first of all, for the following purposes:
    • Reducing the initial size of the downloaded data
    • Using the principle of delayed loading - the necessary data will be downloaded by the application as necessary

    In order to split the client code into parts, a call to the GWT.runAsync method is used.
    An example of using runAsync:

    GWT.runAsync(new RunAsyncCallback() {
        public void onSuccess() {
          new MySettingsDialog().show();
        }
        public void onFailure(Throwable ohNoes) {
          // indicate that something went wrong,
          // usually a connectivity or server problem
        }
      });
    

    In this case, the GWT compiler takes on the responsibility of not only doing the work of dividing the client code, but also analyzing how to cluster the code. It is guaranteed that the separation will be correct. However, separation may not occur. The reason for this may be cross-references in the code.
    In the GWT Can Do What presentation with Google I / O, you can see a comparison of the application download speed before and after cutting it into parts using runAsync:



    Thus, using runAsync can seriously reduce the initial application load time and reduce the amount of data transmitted to the client.
    It is worth paying attention to the AsyncProxy class. Probably, I will give his description in the second part of the article, now you can get acquainted with him according to his documentation .

    Getting rid of the use of heavy classes on the client


    On the Google Web Toolkit group page, you can find a discussion about ways to reduce the size of the compiled GWT application. In particular, the approach is noted, which consists in the rejection of the use of "heavy" classes on the client side, entailing the inclusion of a large amount of code on the client side.
    First of all, we can give an example of using Comparator on the client. Using it entails the inclusion in the client part of ~ 10 Kb of code related classes.
    Using RequestFactory leads to an even greater increase in the client - in the discussion above, the client part increased by 150 Kb.
    You should also be careful when using external modules - it is quite possible that their inclusion in the project will entail a significant increase in the client part due to the addition of many other classes.

    Resource Caching


    Client-side HTTP requests are significant performance limits on the client side of the application. If the application will request each resource separately, the fee for downloading all resources will be large.
    To prevent client application slowdowns, an approach related to resource caching is used.
    GWT has a mechanism called ClientBundle. ClientBundle caches various types of resources (text, graphic, CSS and others). Read about ClientBundle here .
    Benefits of the ClientBundle approach:
    • The required resource will be loaded once instead of loading every time as it is used
    • The total amount of stored resources will be less

    How does minimizing resource storage work with ClientBundle?
    Back to the GWT Can Do What presentation. In it we can see the following illustration:



    Thus, overhead is reduced to store the same data.
    How can resources be reduced as a result?



    GWT RPC Performance Issues Using REST


    GWT RPC is a really convenient tool. Providing an interface for organizing client and server code for the service, having support from the IDE, it is one of the amazing features of building AJAX applications in GWT. However, it is worth considering whether it suits you.
    The main disadvantages in the case of using the GWT RPC can be the addition of too much redundant data to the request and the complexity of debugging.
    The use of REST can be noted as a solution to these problems. In an article by Zack Grossbart, you can find an example of using REST for GWT projects.
    At the same time, in his article 4 More GWT Anti-patterns, the main advantages of REST are noted:
    • REST forces the developer to think about the API. The API can also be provided to external services and applications, adding additional convenience and functionality for interaction.
    • Usability testing
    • Clear separation of client and server

    Features of the impact of layout on the application


    Very often gwt developers use auto-adjust layout. An example of this is the use of height = "100%" in components. It is worth saying that contentHeight, offsetHeight are heavy operations. The following is the IEH offsetHeight runtime statistics, taken from the Measure in Milliseconds presentation from Google I / O 2009:



    Not only is the result of the operation poorly predicted; its peak value for 18 measurements reached a value of the order of 85 ms.
    The complete processing of the resize event takes some time. Often, a resize operation in the case of a forced layout takes several times more time than style recalculation.
    How can you get rid of this problem? You must use CSS. A CSS-defined layout will render much faster, eliminating the need to invoke heavyweight methods such as offsetHeight for the entire DOM hierarchy of components.
    You can use an updated DockPanel that does not use javaScript during the resize option.

    It is highly discouraged to create and store large trees of nested widgets. Widgets have an additional overhead that negatively affects the memory used and the size of the client (as a result, and speed). You can use HTMLPanel as a solution. To track the number of widgets on pages, there is an InspectorWidget tool. You can find out about the properties of the plugin on its page .

    Transmission Optimization


    Serializable objects are constantly transmitted between the client and server. The developer should ask himself - are only the most necessary data really transmitted? Large graphs of objects, nested subobjects, and unnecessary parameter sets take up valuable time and create an extra load. Only transmit what you need on the client. Often, only what the user sees. Everything you need can be obtained if necessary in the data. Of course, this approach should not contradict the policy of caching resources on the client side.

    Using Scheduler


    GWT has a pending call mechanism. Previously called DeferredCommand, it was declared deprecated. Now the mechanism is called Scheduler.
    Scheduler actually provides a class for performing an action asynchronously. It is guaranteed that the action will be performed after the end of the event loop of the browser.
    Benefits:
    • Doesn't block the thread of execution
    • Allows first UI events to complete.

    Quite often, Scheduler is used in the late construction of some objects. However, its proper use will in some cases make UI applications faster due to more prioritization of UI events.

    Using dispatchers to aggregate server requests


    Each call to the server imposes a certain delay in execution. If we need to make frequent multiple calls to the server, we can aggregate them into some batch units.
    Starting with version 2.3, the GWT has an opportunity to use RequestFactory: The advantages of this approach are obvious - the number of calls is significantly reduced, and, as a result, the delay in execution. In case we can cache server responses, we can use caching managers. You can find out about their use by clicking on the link .

    requestContext.method1().to(new Receiver(){...});
    requestContext.method2().to(new Receiver(){...});
    requestContext.fire(new Receiver(){...}); //called only 1
    




    Finally


    GWT is a powerful tool that allows you to create an excellent cross-browser interface and is widely used already outside of Google. However, some of its most convenient tools impose serious limitations on application performance. It is necessary to carefully optimize the speed of the application so that users are also satisfied with working with it.
    In the next article, I plan to continue talking about the features of improving performance and optimizing GWT applications. In particular, we will consider ways to improve the speed of GWT RPC, JS Shrink, features of using native code on the client, tips for reducing the size of the script; It is also planned to talk about optimizing compilation speed and give some tips on layout of the interface.

    Thanks for attention!

    Useful resources:
    1. static.googleusercontent.com/external_content/untrusted_dlcp/www.google.com/en//events/io/2011/static/presofiles/drfibonacci_devtools_high_performance_gwt.pdf
    2. dl.google.com/io/2009/pres/W_1115_GWTCanDoWhat.pdf
    3. dl.google.com/io/2009/pres/W_1230_MeasureinMilliseconds-PerformanceTipsforGoogleWebToolkit.pdf
    4. turbomanage.wordpress.com/2010/07/12/caching-batching-dispatcher-for-gwt-dispatch
    5. www.zackgrossbart.com/hackito/antiptrn-gwt
    6. www.zackgrossbart.com/hackito/antiptrn-gwt2
    7. www.zackgrossbart.com/hackito/gwt-rest
    8. habrahabr.ru/blogs/gwt/99614

    Also popular now: