巧用代理设计模式 (Proxy Design Pattern) 改善前端图片加载体验

这篇文章介绍一种使用代理设计模式(Proxy Design Pattern)的方法来改善您的前端应用里图片加载的体验。
假设我们的应用里需要显示一张尺寸很大的图片,位于远端服务器。我们用一些前端框架的 Image 这个控件类去显示图片。如果直接调用控件类的代码
image.setSrc("http://www.bigfile.gif"), 那么在这张具体的图片真正加载到本地之前,UI 上显示一片空白,这个用户体验不好。
我们日常生活中其实已经能感觉到,很多优秀的前端应用,在加载大尺寸图片或者执行其他费时的后台操作时,前台都会有一些动画效果。
今天我们就来动手做一个类似的效果出来。
有一个按钮。点了之后,会触发一张大尺寸图片的加载。

在这张图片的加载过程中,一直显示一张本地的 gif 图片作为加载动画:

加载完毕后,动画消失,实际图片才显示出来(4.1MB 大)。

项目完整代码在我 github 上:
https://github.com/i042416/FioriODataTestTool2014/tree/master/WebContent/buttontutorial/view
看一些关键步骤。
1. Image 控件定义在 XML 视图里,ID 为 jerryImage。我用的 SAP UI5 前端框架。大家只要领会了思路,可以容易地迁移到其他任何前端框架去。
id 为 jerryButton 的 button 控件,点击事件处理函数 onPress:

2. 再看控制器的代码:onPress 执行 loadImageWithProxy。

loadImageWithProxy 调用 injectProxy,传入的输入参数 image 就是 XML 视图里定义的 Image 控件。

在 injectProxy 里,代码第 30 行创建了一个隐藏的 Image 代理对象,然后在第 36 行用真实的 Image 控件去显示本地的 gif 文件,以在 UI 上显示出动画效果,然后第 37 行用隐藏的 Image 代理对象去悄悄地加载大尺寸文件,这件事情终端用户并不知情。等到这个大尺寸图片加载完毕后,Image 代理对象的 onload 回调函数会被浏览器触发,此时再让真实的 Image 控件把加载好的大尺寸文件显示出来。 效果就实现了。
要获取更多 Jerry 的原创技术文章,请关注公众号"汪子熙"。
版权声明: 本文为 InfoQ 作者【Jerry Wang】的原创文章。
原文链接:【http://xie.infoq.cn/article/34e91b80e0fcfcaf2174fb263】。文章转载请联系作者。
评论