通过使用具体类而不是接口,编译后的 js 的大小减少了多少

Posted

技术标签:

【中文标题】通过使用具体类而不是接口,编译后的 js 的大小减少了多少【英文标题】:By how much is the compiled js reduced in size by using concrete classes instead of interfaces 【发布时间】:2012-08-20 02:49:48 【问题描述】:

我已经为 GWT 阅读过,指定返回具体实现的方法,例如:

public ArrayList<String> getList();

而不是通常首选的“抽象接口”,例如:

public List<String> getList();

导致 GWT 生成一个较小的已编译 javascript 文件,因为客户端(即 js)代码不必满足接口的所有已知实现(在 List 的示例中,客户端代码必须是能够处理LinkedListArrayListVector等),因此它可以通过不编译未使用的实现来优化js。

与我密切相关的问题是:

这是真的吗? (以下问题假设它正确的) 是针对使用接口的每个类还是针对每个应用程序进行优化?即 我看到重构一个类的好处了吗?或 只有将所有客户端类重构为不使用接口后,我才能看到好处吗?

【问题讨论】:

测试这个很容易。 【参考方案1】:

以下假设您使用该接口作为 GWT RPC 服务签名的一部分。我认为如果您在 GWT RPC 服务的签名中不使用接口,使用类而不是接口的影响应该是最小的(例如 GWT 编译器只会编译使用的实现)

这是真的吗? (以下问题假设为真)

是的,当 GWT 编译器“知道”哪些类可能从服务器发送到客户端时,它的输出会变得更小。

是针对使用接口的每个类还是针对每个应用程序进行优化?即

在 GWT RPC 的情况下,每个应用程序。

我看到重构一个类的好处了吗?

是的,如果接口需要包含许多类的代码,则由一个实现替换的接口可以将生成的代码大小减少几 kb。

但是,除了使用实现而不是接口之外,还可以在模块定义文件中定义类的“黑名单”,以明确规避在生成的代码中包含实现:类似于

<extend-configuration-property name="rpc.blacklist"
    value="-java.util.ArrayList" />  

【讨论】:

【参考方案2】:

我刚刚根据webAppCreator 生成的示例应用进行了测试,但我添加了 3 个简单的服务,它们返回List&lt;String&gt;ArrayList&lt;String&gt;,具体取决于构建。

结果是让所有服务使用ArrayList&lt;String&gt;从编译的 javascript 中节省了大约 5Kb,而不是使用任何返回类型的组合。

这证明节省是真实的并且是针对每个应用程序(而不是针对每个服务)。

它还显示了它节省了多少(在这种情况下)。

【讨论】:

【参考方案3】:

这对于一般的 GWT 编译器来说并不实际。这种方法仅适用于与代码生成一起使用的类。例如,在使用远程过程调用时。有关更多详细信息,请参阅此question。因此,如果您声明一个接口而不是具体类作为返回类型,编译器会在您编译的代码中包含所有可能的实现。这会增加编译时间和生成的代码量。

实际上可以使用没有 RPC 的 GWT 开发应用程序。在这种情况下,编译后的代码在使用接口时不会膨胀。

【讨论】:

以上是关于通过使用具体类而不是接口,编译后的 js 的大小减少了多少的主要内容,如果未能解决你的问题,请参考以下文章

传递实现类而不是接口时的 MissingMethodException

重构以避免在使用抽象类而不是接口时进行多重继承

带有 POJO 类而不是接口的 GWT AutoBean

无法将 osgi 服务 bean 公开为类而不是接口

在页面加载时使用类而不是输入id上的js自动对焦

angular js ng-class 将表达式显示为类而不是处理它