2015-12-23 3 views
2

Я использую разделение кода в GWT, чтобы уменьшить размер исходного JavaScript. Пока мое приложение инициализируется, я хочу предварительно выбрать другую (большую) часть моего кода, как описано в документах (www.gwtproject.org/doc/latest/DevGuideCodeSplitting.html).Кодирование синхронного запроса кода GWT

private void doSth(final boolean prefetch) { 
    GWT.runAsync(new RunAsyncCallback() { 
     public void onFailure(Throwable caught) { 
      Log.error("Loading the code failed!"); 
     } 

     public void onSuccess() { 
      if(prefetch) 
       return; //do nothing. just a prefetch 
      //here is the loaded code 
     } 
    }); 
} 

Но я не могу признать улучшение производительности. Когда я проанализировал журналы браузера, я понял, что запрос на загрузку JavaScript не помечен как XHR. Загружает ли GWT код точки разделения синхронно?

ответ

4

Улучшение производительности в исходном загруженном коде, предполагая, что ничего другого не ссылается на этот код. Если что-то еще делает работу //here is the loaded code, тогда будет либо очень мало, либо вообще нет кода, чтобы разрастись в отдельно загруженный JS-файл.

Эта функция может быть отключена несколькими способами, в том числе с помощью режима dev или установки флага компилятора, чтобы пропустить этот процесс. В этом случае да, точка разделения работает синхронно, так как нет смысла ждать. Кроме того, после того, как файл был загружен один раз, его не нужно загружать при следующем вызове кода при одной и той же загрузке страницы.

Если ваш сервер настроен на кеш-память правильно, то после первого посещения сбережения еще меньше, так как загрузка не выполняется - вы сохраняете только время, затрачиваемое на разбор этого кода в JS-машине браузера.

Но помимо этого нам потребуется дополнительная информация.


Вот краткий демо, показывающий, как точка разделения может быть записана с немного больше мяса к нему, и позволяя вам использовать ваш браузер, чтобы заметить, как код точки разделения был введен отдельно.

public class SampleEntryPoint implements EntryPoint { 
    public void onModuleLoad() { 
    Label label = new Label("Hello, World!"); 
    label.addClickHandler(new ClickHandler() { 
     @Override 
     public void onClick(ClickEvent event) { 
     GWT.runAsync(new RunAsyncCallback() { 
      public void onFailure(Throwable var1) {/*ignore*/} 
      public void onSuccess() { 
      Window.alert("Clicked, and loaded in split point!"); 
      } 
     }); 
     } 
    }); 
    RootPanel.get().add(label); 
    } 
} 

код и образец: https://viola.colinalworth.com/proj/755e224e7f48a047703d44eb6903d926/project/client/SampleEntryPoint.java

Standalone образец: https://viola.colinalworth.com:444/compiled/755e224e7f48a047703d44eb6903f76c/

При загрузке этой страницы, то nocache загружает файл, как это делает начальную загрузку (как видно через вкладку Сеть инспектора в Chrome): initial download after page load

Затем, когда вы нажимаете виджет «Ярлык», е OnClick пожаров, которые запускают runAsync и загружают дополнительные точки разделения (плюс «остатки» фрагмент): additional downloads after split point

После этих двух новых записей, которые были добавлены к вкладке Сети, вы увидите предупреждающее сообщение появляется. Последующие клики не приводят к этой небольшой задержке, и они не заставляют этот дополнительный JS загружаться снова.

Также обратите внимание, что они не загружаются как вызовы AJAX/XHR, а как тег скрипта, который будет добавлен на страницу. При нажатии на данные в столбце Инициатор (не изображен) приводит к этому (отформатирован для удобства чтения):

function fb(a) { 
    var b, c, d; 
    d = (bb(), window); 
    b = d.document; 
    c = b.createElement('script'); 
    (!!a.a || a.b) && cb(c, a.a, a.b); 
    eb(c, a.c); 
    (b.head || b.getElementsByTagName('head')[0]).appendChild(c); 
    return c 
} 

Получение через запутанный код, мы видим, что <script> тег создается и добавляется к <head> из стр.


Копаем глубже, мы можем обнаружить, что интерфейс AsyncFragmentLoader.LoadingStrategy описывает, как пойти получить этот фрагмент, и что com/google/gwt/core/AsyncFragmentLoader.gwt.xml проводах это по умолчанию для XhrLoadingStrategy. Однако оба линкера и xsiframe меняют это значение на CrossSiteLoadingStrategy и ScriptTagLoadingStrategy соответственно. А по последним версиям GWT (вы не указали, поэтому я предполагаю, что вы используете последнюю версию), компоновщик xsiframe по умолчанию. От Core.gwt.xml:

<add-linker name="xsiframe" /> 

Мы можем настроить это за счет перехода к старому линкера, или просто заменить стратегию. Обратите внимание, что переключение стратегии XHR предотвратит правильную работу междоменной загрузки (например, SuperDevMode), поэтому будьте осторожны с этим.

Многое, как AsyncFragmentLoader.gwt.xml проводной интерфейс для XhrLoadingStrategy и CrossSiteIframeLinker.gwt.xml изменил его ScriptTagLoadingStrategy, мы можем изменить его обратно. Мы создадим правило, заменяющий LoadingStrategy с XhrLoadingStrategy, и перечислить его после того, как наш GWT наследует заявления в нашем .gwt.xml файле:

<replace-with class="com.google.gwt.core.client.impl.XhrLoadingStrategy"> 
    <when-type-is class="com.google.gwt.core.client.impl.AsyncFragmentLoader.LoadingStrategy" /> 
</replace-with> 

Это то, что старое значение по умолчанию используется, чтобы полагаться на как часть std линкера (com.google.gwt.core.linker.IFrameLinker), хотя это уже не рекомендуется и может быть удалено в более позднем выпуске.

+0

Благодарим вас за этот отличный ответ. Именно то, что мне нужно. Можно ли определить XhrLoadingStrategy (и перезаписать настройки по умолчанию) в gwt.xml? –

+0

Да, я поясню в ответе, но почему вы надеетесь использовать XHR? Это разрушит междоменную загрузку (если сервер, на котором размещена точка разделения, поддерживает CORS), что предотвратит работу SDM как ожидалось. –

+0

Код приложения огромен. Код точки разделения составляет 2 МБ! Чтобы повысить производительность запуска, я хочу асинхронно загружать код точки разделения, в то время как клиент запрашивает некоторые другие параметры с сервера. –