本文介绍了GWT如何减少RPC调用的代码序列化程序的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现在我的应用程序中由GWT生成的超过60%的javaScript代码用于RPC序列化器。
另外我发现序列化程序不在服务接口之间共享,我的意思是如果我有例如在2个rpc服务接口上引用的AccountDTO类型,我将得到2个序列化程序类而不是1个相同类型。
为了减少编译代码的大小,我在想,也许我可以使用延迟绑定来替换我为一个大界面所用的所有服务接口。如果可能的话,那么GWTCompiler可能只会生成一个AccountDTO序列化器,而不是2个。



我不确定这是个好主意还是更好解决方案为我的问题。



我试图实现的是这样的:

  code>,你会将 TypeSerializers 的数目限制为一个。



RemoteServiceProxy 子类型是无状态的,所以确保只创建一个实例可以使构建一致性更容易,但不会节省运行时内存或时间,因为它们几乎可以编译为静态方法。然而, * _ TypeSerializer 类具有状态,但每个类只有一个实例,因此将所有 RemoteService s可能会节省很少的工作记忆。


I found that the more than 60% of the javaScript code generated by GWT on my application is for RPC serializers. Also I found that serializers are not shared between service interfaces, I mean if I have for example AccountDTO type referenced on 2 rpc service interfaces, I will get 2 serializer classes instead of 1 for the same type. In Order to reduce the size of the compiled code I was thinking that maybe I could use Deferred Binding in order to do a replacement of all the services interfaces I have for one big interface. If that could be possible, maybe then GWTCompiler will produce only one AccountDTO serializer instead of 2.

I'm not sure this is a good idea or if there is a better solution for my problem.

What I was trying to implement was something like this:

// Define new interface that extends all service interfaces
public interface GenericService extends RemoteService,
                    AccountingService,
                    FinancialService,..., { }

public interface GenericServiceAsync extends AccountingServiceAsync,
                         FinancialServiceAsync, ..., { }

// At Application.gwt.xml do:

<module>
...
...
    <replace-with class="com.arballon.gwt.core.client.GenericService">
        <when-this-is class="com.arballon.gwt.core.client.AccountingService>
    </replace-with>
    <replace-with class="com.arballon.gwt.core.client.GenericService">
        <when-this-is class="com.arballon.gwt.core.client.FinancialService>
    </replace-with>
    ...
    ...

But at the moment I was receiving the error:

[ERROR] Errors in 'file:/C:/Users/Daniel/EclipseWorkspace/ADK/src/com/arballon/gwt/core/client/FinancialService.java' [ERROR] Line 31: Rebind result 'com.arballon.gwt.core.client.GenericService' could not be found

Any thoughts about the issue will be appreciated.Regards

Daniel

解决方案

GWT's RPC generation code builds several classes to do its work as you've noted: a *_FieldSerializer for each type that goes over the wire, and a *_Proxy class for the RemoteService async type. That proxy type requires a *_TypeSerializer, which is the root of your problem - for some reason, GWT wires up all of the serialization/deserialization methods in a string->js function map, probably to facilitate fast lookups - but this setup code comes at the cost of lines of code that need to be in the final build. A more optimized approach could have each FieldSerializer have a registration method where it adds its methods to the static map owned by the Proxy - this is plagued, however, but GWT's optimization of attempting to not reference instantiate(), deserialize() and serialize() methods if it doesnt appear they will be called.

Your issue stems from having many types that can be serialized, and from your having attempted to build out RemoteService types that each describe specific units of functionality, but re-use many model types. Admirable goal, especially as it will probably make your server-side code look nicer, but apparently GWT bites you for it.

The solution I attempted to offer you on freenode (as niloc132) was to build a single large RemoteService type, which you named GeneralService, and a matching GeneralServiceAsync, each extending all of the existing rpc service types. My first thought was to use a <replace-with> to tell the generator system that when you want each RemoteService type to replace it with GeneralService, but as Tahir points out, this doesn't make sense - GWT doesn't pass rebind results back into itself to keep doing lookups. Instead, I would suggest that when you want a service async type, do the following:

AccountingServiceAsync service = (AccountingServiceAsync) GWT.create(GeneralService.class)

The rebind result from GeneralService will implement GeneralServiceAsync, which is itself assignable to AccountingServiceAsync. If memory serves, you said that you have static methods/fields that provide these services - change those sites to always create a GeneralServiceAsync instance. As long as you do not invoke GWT.create on any RemoteService subtype but GeneralService, you will limit the number of TypeSerializers to one.

As a side note, the RemoteServiceProxy subtypes are stateless, so ensuring that you create only one instance might make it easier to build consistently, but saves no runtime memory or time, as they are almost certainly compiled out to static methods. The *_TypeSerializer classes do have state however, but there is only one instance of each, so combining all of your RemoteServices might save a very small amount of working memory.

这篇关于GWT如何减少RPC调用的代码序列化程序的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 09:07