Saturday, November 19, 2011

Ускоряем GWT-компиляцию

При разработке GWT-приложений сталкиваешься с тем, что они довольно долго компилируются. Для примера, соберём это небольшое приложение с помощью команды "mvn clean install":

[INFO] Scanning for projects...
...                                                                       
[INFO] ------------------------------------------------------------------------
[INFO] Building hellogwt 1.0
[INFO] ------------------------------------------------------------------------
...
[INFO] --- gwt-maven-plugin:2.4.0:compile (default) @ hellogwt ---
[INFO] auto discovered modules [com.hellogwt.HelloGWT]
[INFO] Compiling module com.hellogwt.HelloGWT
[INFO]    Compiling 6 permutations
[INFO]       Compiling permutation 0...
[INFO]       Process output
[INFO]          Compiling
[INFO]             Compiling permutation 1...
[INFO]       Compiling permutation 2...
[INFO]       Compiling permutation 3...
[INFO]          Compiling
[INFO]             Compiling permutation 4...
[INFO]       Compiling permutation 5...
[INFO]    Compile of permutations succeeded
[INFO] Linking into D:\Work\hellogwt\target\hellogwt-1.0\hellogwt
[INFO]    Link succeeded
[INFO]    Compilation succeeded -- 30.684s
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 36.295s
[INFO] Finished at: Sat Nov 19 01:40:03 EET 2011
[INFO] Final Memory: 17M/309M
[INFO] ------------------------------------------------------------------------

30.684 секунды. А ведь приложение содержит всего несколько сервисов и один основной класс HelloGWT.

Попробуем уменьшить время компиляции:

1) Лучше использовать конкретные типы (ArrayList) вместо интерфейсов (List) в аргументах и возвращаемых значениях GWT RPC сервисов. Иначе будет производится избыточная компиляция для всех классов, реализующих интерфейс (List). Класс HelloGWT содержит метод refreshGreetingTable(), который использует интерфейс List:
...
private void refreshGreetingsTable() {
        greetingService.getGreetings(new AsyncCallback<List<Greeting>>() {
            public void onFailure(Throwable throwable) {
                Window.alert("ERROR: Cannot load greetings!");
            }

            public void onSuccess(List<Greeting> greetings) {
                fillGreetingsTable(greetings);
            }
        });
    }
...

Заменим List на его конкретную реализацию - ArrayList:
...
private void refreshGreetingsTable() {
        greetingService.getGreetings(new AsyncCallback<ArrayList<Greeting>>() {
            public void onFailure(Throwable throwable) {
                Window.alert("ERROR: Cannot load greetings!");
            }

            public void onSuccess(ArrayList<Greeting> greetings) {
                fillGreetingsTable(greetings);
            }
        });
    }
...

Конечно, из-за новой сигнатуры метода нужно не забыть изменить интерфейсы и классы, содержащие refreshGreetingTable().

2) Можно отключить оптимизацию кода при компиляции приложения с помощью параметра "draftCompile".

Выполним команду "mvn clean install -Dgwt.draftCompile=true":
[INFO] Scanning for projects...
...
[INFO] ------------------------------------------------------------------------
[INFO] Building hellogwt 1.0
[INFO] ------------------------------------------------------------------------
...
[INFO] --- gwt-maven-plugin:2.4.0:compile (default) @ hellogwt ---
[INFO] auto discovered modules [com.hellogwt.HelloGWT]
[INFO] Compiling module com.hellogwt.HelloGWT
[INFO]    Compiling 6 permutations
[INFO]       Compiling permutation 0...
[INFO]       Process output
[INFO]          Compiling
[INFO]             Compiling permutation 1...
[INFO]       Compiling permutation 2...
[INFO]          Compiling
[INFO]             Compiling permutation 3...
[INFO]       Compiling permutation 4...
[INFO]       Compiling permutation 5...
[INFO]    Compile of permutations succeeded
[INFO] Linking into D:\Work\hellogwt\target\hellogwt-1.0\hellogwt
[INFO]    Link succeeded
[INFO]    Compilation succeeded -- 25.326s
... 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 31.143s
[INFO] Finished at: Sat Nov 19 01:48:38 EET 2011
[INFO] Final Memory: 16M/309M
[INFO] ------------------------------------------------------------------------

25.326 секунды. Уже вполне неплохо.

3) По умолчанию приложение компилируется для всех поддерживаемых типов браузеров. Установим, чтобы оно компилировалось только для одного. Это настраивается с помощью свойства "user.agent" в файле HelloGWT.gwt.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6.2//EN"
        "http://google-web-toolkit.googlecode.com/svn/tags/1.6.2/distro-source/core/src/gwt-module.dtd">
<module rename-to='hellogwt'>
    <!-- Inherit the core Web Toolkit stuff.                        -->
    <inherits name='com.google.gwt.user.User'/>

    <!-- Inherit the default GWT style sheet.  You can change       -->
    <!-- the theme of your GWT application by uncommenting          -->
    <!-- any one of the following lines.                            -->
    <inherits name='com.google.gwt.user.theme.standard.Standard'/>
    <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
    <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>     -->

    <!-- Other module inherits                                      -->

    <!-- Specify the app entry point class.                         -->
    <entry-point class='com.hellogwt.client.HelloGWT'/>

    <set-property name="user.agent" value="safari"/>

    <source path='client'/>
    <source path='shared'/>
</module>

Все возможные значения свойства "user.agent" можно посмотреть здесь.

Выполним команду "mvn clean install -Dgwt.draftCompile=true":
[INFO] Scanning for projects...
...                                                                     
[INFO] ------------------------------------------------------------------------
[INFO] Building hellogwt 1.0
[INFO] ------------------------------------------------------------------------
...
[INFO] --- gwt-maven-plugin:2.4.0:compile (default) @ hellogwt ---
[INFO] auto discovered modules [com.hellogwt.HelloGWT]
[INFO] Compiling module com.hellogwt.HelloGWT
[INFO]    Compiling 1 permutation
[INFO]       Compiling permutation 0...
[INFO]    Compile of permutations succeeded
[INFO] Linking into D:\Work\hellogwt\target\hellogwt-1.0\hellogwt
[INFO]    Link succeeded
[INFO]    Compilation succeeded -- 19.606s
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 25.433s
[INFO] Finished at: Sat Nov 19 01:42:30 EET 2011
[INFO] Final Memory: 16M/330M
[INFO] ------------------------------------------------------------------------

19.606 секунды. Это на 36% меньше, чем изначальное время компиляции - 30.684 секунды. Ощутимая разница!

Еще про эффективную разработку GWT-приложений можно посмотреть здесь и здесь.


Рекомендуемые посты:

4 comments:

  1. Так а на сколько увеличилась ско
    рость после замены листа на его реализацию? И еще можно дать больше памяти при старте, что тоже однозначно даст прирост в скорости потому что по умолчанию там дается мало :) приду домой могу дать параметры которые мы используем у нас в проекте. Кстати еще есть такой приятный параметры skipTest если есть тесты в проекте.

    ReplyDelete
    Replies
    1. После замены List на ArrayList заметить ускорения компиляции не удалось из-за того, что проект небольшой. Это - рекомендация ребят из Google, думаю им можно верить :) Меня заинтересовали параметры памяти, которые вы используете в проекте. Буду рад узнать о них больше!

      Delete
  2. Вспомнил про параметры :)
    Вот какие у нас в проекте -
    -Xmx1024m -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:PermSize=256M -XX:MaxPermSize=512M

    ReplyDelete