gwt格式
今天,InfoQ出版了Ryan Dewsbury着的《 Google Web Toolkit》一书中的示例章节“与GWT-RPC Servlet集成” 。
性能是Ajax如此受欢迎的主要原因。 我们经常将许多Ajax应用程序中使用的炫彩效果作为对用户的核心吸引力,并且用户也可能将其归因于他们偏爱Ajax应用程序的原因。 这是有道理的,因为如果您查看传统的Web应用程序,它们看起来是静态且无聊的。 但是,如果确实炫目的效果大大改善了用户体验,那么我们将看到动画gif的更广泛使用。 幸运的是,那些日子已经一去不复返了。 Ajax不会像设置gif动画那样前进,因为它添加的值并不都是浮华的。 无论用户是否意识到这一点,改善Ajax用户体验的真正价值在于性能。
在本文中,我不会向您展示为什么Ajax本质上要比传统的Web应用程序更好。 如果不确定,请查看Google地图,并记住较旧的Web地图应用程序,或者将Gmail与Hotmail进行比较。 通过将应用程序基于Ajax架构,可以显着提高应用程序的性能和用户体验。 取而代之的是,在本文中,我将向您展示如何将这种性能改进推向新的高度-使您的Ajax应用程序与众不同。
为什么选择GWT?
Google Web Toolkit(GWT)极大地促进了Ajax开发。 像这样的任何新技术都很难卖,特别是在有很多其他选择的时候。 实际上,没有什么可以为您带来GWT为Ajax应用程序提供的好处。 如果您尚未绑定到框架,则不使用它就没有意义。 通过为您的Ajax应用程序使用GWT,可以免费获得巨大的性能提升。
所谓免费,是指您无需考虑。 您专心于编写应用程序逻辑,GWT可以帮助您解决问题。 您会看到,GWT附带了一个将Java代码编译为JavaScript的编译器。 如果您熟悉编译语言(C,Java等),您将会知道目标是使语言平台独立。 编译器能够对您特定于要编译到的平台的代码进行优化,因此您可以专注于使代码可读性和组织性良好。 GWT编译器执行相同的操作。 它需要您的Java代码,并编译为几个高度优化JavaScript文件,每个文件专门用于特定的浏览器,从而使代码更小且浏览器独立。 优化步骤采用真正的编译器优化行,以删除未调用的方法,并内联代码,这些代码本质上将JavaScript视为Web的汇编代码。 生成的代码小而快速。 当将JavaScript加载到浏览器中时,它仅包含该浏览器所需的代码,而没有框架因未使用的方法而膨胀。 与直接使用JavaScript构建的应用程序相比,使用GWT构建的应用程序更小,更快,现在,通常非常谦虚的GWT团队相信GWT 1.5编译器生成JavaScript比任何人都能手工编写的代码都要快。 这足以说服任何人将GWT用于Ajax应用程序,但是如果没有,那么还有很多其他原因使您应该使用GWT,包括Java软件工程工具的可用性(在Eclipse中调试Ajax应用程序对于用户来说是一个巨大的优势。我)。
你还要吗?
为什么停在那里。 Ajax应用程序的性能要比传统Web应用程序好,而GWT应用程序的性能要比常规Ajax应用程序好。 因此,只需做出一些技术选择,您就可以构建性能非常好并且专注于应用程序功能的应用程序。 您也可以在一半时间内完成工作。 但是,GWT并不能神奇地完成所有事情。 我将介绍您可以自己做的四件事,以进一步提高Ajax应用程序的性能。
1.永久缓存您的应用
当您将GWT应用程序编译为JavaScript时,将为每个具有唯一名称的浏览器版本创建一个文件。 这是您的应用程序代码,只需将其复制到Web服务器即可用于分发。 由于文件名是代码的哈希,因此它具有内置的版本控制功能。 如果更改代码并编译,则会创建一个新文件名。 这意味着浏览器已经加载了该文件的副本,或者根本没有该文件的副本。 它不需要检查修改日期(HTTP的If-Modified-Since标头)来查看是否有更新的版本。 您可以消除这些不必要的浏览器HTTP旅行。 它们可以很小,但随着用户群的增加,它们的总和会很多。 由于浏览器只能向主机发出两个活动请求,因此它们也会减慢您的客户端的速度。 Ajax加载时间的许多优化涉及减少对服务器的请求数量。
要消除浏览器发出的版本请求,您需要告诉Web服务器发送Expires HTTP标头。 此标头告诉浏览器何时不再认为内容是新的。 在到期日期过去之前,浏览器无法安全地检查新版本。 在Apache中进行设置很容易。 您需要将以下内容添加到您的.htaccess文件中:
<Files *.cache.*>
ExpiresDefault "now plus 1 year"
</Files>
这告诉apache从现在开始为每个匹配模式* .cache。*的文件将expires标头添加到一年后。 此模式将与您的GWT应用程序文件匹配。
如果直接使用Tomcat,则可以通过Servlet过滤器添加这样的标头。 添加servlet过滤器非常简单。 您需要像下面这样在WEB_INF / web.xml文件中声明过滤器:
<filter>
<filter-name>CacheFilter</filter-name>
<filter-class>com.rdews.cms.filters.CacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>/gwt/*</url-pattern>
</filter-mapping>
这告诉tomcat在哪里寻找过滤器类,以及要通过过滤器发送哪些文件。 在这种情况下,模式/ gwt / *用于选择名为gwt的目录中的所有文件。 filter类实现doFilter方法以添加Expires标头。 对于GWT,我们希望将标头添加到与* .nocache。*不匹配的每个文件中。 nocache文件不应该被缓存,因为它包含选择当前版本的逻辑。 以下是此过滤器的实现:
public class CacheFilter implements Filter {
private FilterConfig filterConfig;
public void doFilter( ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest)request;
String requestURI = httpRequest.getRequestURI();
if( !requestURI.contains(".nocache.") ){
long today = new Date().getTime();
HttpServletResponse httpResponse = (HttpServletResponse)response;
httpResponse.setDateHeader("Expires", today+31536000000L);
}
filterChain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void destroy() {
this.filterConfig = null;
}
}
2.压缩您的应用程序
GWT编译器在减少代码大小,但减少未使用的方法和混淆代码以使用简短的变量和函数名称方面做得很好,但是结果仍然是未压缩的文本。 购买gzip压缩应用程序以进行部署,可以进一步改善大小。 使用gzip,您可以将应用程序大小减少多达70%,这可以更快地加载应用程序。
幸运的是,使用服务器配置也很容易做到。 要压缩apache上的文件,只需将以下内容添加到您的.htaccess文件中:
SetOutputFilter DEFLATE
Apache将与每个浏览器自动执行内容协商,并根据浏览器支持的内容发送压缩或未压缩的内容。 所有现代浏览器均支持gzip压缩。
如果直接使用Tomcat,则可以利用server.xml文件中Connector元素上的compression属性。 只需添加以下属性即可打开压缩功能:
compression="on"
3.捆绑图像
Ajax应用程序分发利用了浏览器和HTTP的分发功能,但是浏览器和HTTP并未针对分发Ajax应用程序进行优化。 在传统Web应用程序使用共享资源分发模型的部署需求中,Ajax应用程序更接近于桌面应用程序。 传统的Web应用程序依靠浏览器和Web服务器之间的交互来管理呈现页面所需的所有资源。 此管理确保资源在页面之间共享和缓存,以确保加载新页面时需要尽可能少的下载。 对于Ajax应用程序,资源通常不会在文档之间分配,也不需要单独加载。 但是,在加载应用程序资源时,简单地使用传统的Web分发模型很容易,许多应用程序经常这样做。
相反,您可以通过将图像捆绑到一个文件中来减少加载应用程序所需的HTTP请求数量。 通过这样做,您的应用程序将一次请求而不是一次两次加载所有图像。
从GWT 1.4开始,支持ImageBundle接口。 利用此功能,您可以为应用程序中使用的每个图像定义一个带有方法的接口。 编译应用程序时,将读取接口,并且编译器将列出的所有图像组合到一个图像文件中,并以图像内容的哈希作为文件名(以像应用程序代码一样永久地缓存文件)。 您可以将任何数量的图像放入包中,并在单个HTTP请求的开销下在应用程序中使用它们。
作为示例,我将以下图像包用于我帮助构建的几个应用程序中的基本图像:
public interface Images extends ImageBundle {
/**
* @gwt.resource membersm.png
*/
AbstractImagePrototype member();
/**
* @gwt.resource away.png
*/
AbstractImagePrototype away();
/**
* @gwt.resource starsm.gif
*/
AbstractImagePrototype star();
/**
* @gwt.resource turn.png
*/
AbstractImagePrototype turn();
/**
* @gwt.resource user_add.png
*/
AbstractImagePrototype addFavorite();
}
请注意,每个方法都有一个注释批注,用于指定要使用的图像文件,以及一个返回AbstractImagePrototype的方法。 AbstractImagePrototype具有createImage方法,该方法返回可在应用程序界面中使用的Image小部件。 以下代码说明了如何使用此映像包:
Images images = (Images) GWT.create(Images.class);
mainPanel.add( images.turn().createImage() );
它非常简单,但是可以大大提高启动性能。
4.使用StyleInjector
CSS文件和CSS图像作为应用程序资源呢? 在传统的Web分发模型中,这些被视为外部资源,独立加载和缓存。 在Ajax应用程序中使用时,它们会涉及其他HTTP请求并减慢应用程序的加载速度。 目前,GWT没有提供任何解决方法,但是有一个GWT孵化器项目,其中有一些有趣的GWT代码,可以考虑在将来的版本中使用。 特别有趣的是ImmutableResourceBundle
和StyleInjector
。
ImmutableResourceBundle非常类似于ImageBundle,但可用于任何类型的资源,包括CSS和CSS图像。 目的是提供围绕其他资源的抽象,以便以最佳方式对浏览器运行应用程序进行处理。 以下代码是此类的示例,用于加载CSS文件和一些资源:
public interface Resources extends ImmutableResourceBundle {
/**
* @gwt.resource main.css
*/
public TextResource mainCss();
/**
* @gwt.resource back.gif
*/
public DataResource background();
/**
* @gwt.resource titlebar.gif
*/
public DataResource titleBar();
/**
* @gwt.resource dialog-header.png
*/
public DataResource dialogHeader();
}
对于每个资源,都指定了一个文件和方法,就像ImageBundle一样,但是方法的返回值是DataResource或TextResource。 对于TextResource,可以使用其getText方法获取其内容,对于DataResource,可以使用getUrl引用数据(例如,在IMG标签或IFRAME中)。 对于不同的浏览器,如何加载此数据的方式有所不同,您无需担心。 在大多数情况下,数据是使用以下数据的内联URL:URL前缀。 此类的可能性很大,但最直接的用途是将CSS直接与您的应用程序文件捆绑在一起。
注意在界面中,引用了CSS文件和一些图像。 在这种情况下,该接口用于将CSS及其图像与应用程序捆绑在一起,以减少HTTP调用和启动时间。 CSS文本为某些应用程序元素指定了背景图片,但没有提供真实的URL,而是列出了占位符。 这些占位符引用了包中的其他元素,尤其是其他图像。 例如,main.css文件的gwt-DialogBox样式名称具有CSS规则:
.gwt-DialogBox{ background-image:url('%background%') repeat-x; }
要在您的应用程序中使用此CSS文件及其图像,您需要使用GWT孵化器项目中的StyleInjector类。 StyleInjector类获取CSS数据,并将占位符与资源束中的资源匹配,然后将CSS注入浏览器以在您的应用程序中使用。 听起来很复杂,但使用起来很简单,而且可以提高性能。 以下是使用StyleInjector将CSS从资源包中注入到应用程序中的示例:
Resources resources = (Resources)GWT.create(Resources.class);
StyleInjector.injectStylesheet( resources.mainCss().getText(), resources );
重要的是要注意,该技术是孵化器项目的一部分,并且将来很可能会发生变化。
结论
与传统的Web应用程序相比,Ajax应用程序的可用性有了很大的提高,GWT提供了免费提供更好的Ajax性能的工具。 您应该将GWT邮件示例的启动速度与其他示例Ajax应用程序进行比较。 通过关注传统Web应用程序和Ajax应用程序之间的部署差异,我们可以进一步提高应用程序性能。 我很高兴看到下一代Ajax应用程序。
gwt格式