导语
在架构一个大型app的时候,混合应用(hybridAPP)是一个十分成熟并且流行的技术方案。Webview容器具有绝大多数系统浏览器具有的标准,并且可以通过jsBridge和Native交互,在功能和性能方面也有很大的提升空间。
在这样的前提下,业务方可以开发一套H5代码,同时展现在浏览器、APP、微信中,可以跨APP分享、交互,十分方便快捷。在功能方面,爱奇艺视频提供了JSSDK供第三方使用,那么在H5性能方面如何提升,就是我们现在正在谈论的问题。
❖
本文将深入研讨如何通过离线化技术加快H5页面初始加载速度、在弱网环境下提升用户体验、极大地降低资源请求数量,减小服务器压力的方法。
离线缓存
爱奇艺离线缓存系统最初的设计包含了如下几个主要特性:
-
可控的资源更新(对每个被缓存的页面和资源文件可追踪、可操控);
-
选择性的资源缓存(可选择希望缓存的资源类型,可以精确到每个文件);
-
内容压缩(可选择性对html、css、js等文件做代码压缩,最终再对整个资源包进行zip压缩);
-
合并重复资源(同资源不同url会去重)
以上也是离线缓存系统对比浏览器缓存的优势所在。浏览器缓存依赖HTTP请求的响应头,一旦有文件需要更新,必须在客户端清除缓存,或者用版本号来免缓存,这样一来,增加了业务方对文件缓存管理的难度,而且无法清除指定某个资源的缓存。
同时,我们提供了一套基于配置的CLI的方式以及GUI的方式方便业务方管理他们得缓存。对此我们设计了一套离线化管理后台。
架构+实现原理
下图简单描绘了整个系统的设计,而实际的项目开发过程中,涉及到很多复杂的细节内容,这里不一一描述:
整个离线缓存由环环相扣的3部分组成,我们将在下文中对每个部分进行详细的解释:
打包系统
打包是整个流程的第一步。业务方只有一个可访问的H5链接。在这个前提下,怎样可以事先获取到希望缓存的资源?让业务方自行整理一个文件夹或者列表?在这个问题中,我们需要考虑以下几点:
是否高效?
考虑到业务隔离性,和整个离线缓存机制的复杂性,难道业务方需要对每个页面整理一个资源列表吗?当然他们可以把本地开发环境的资源文件夹上传,但是有些情况显然并不适用:
-
页面引用了外部资源
-
页面是自动生成的(没有本地开发环境)
是否容易出错?
如果让业务方整理一个资源清单,实际操作中很容易出错,并且歌是很难处理。
是否容易管理?
如果页面或自愿发生更改,如何快速更新缓存?如何方便查看被缓存的资源?
因此,带着这些问题,我们需要一个自动化的打包程序、一个一键式的工具、一个友好的可视化平台来解决。
自动化
我们利用PhantomJS来实现一个网络爬虫,输入页面URL之后,跟踪所有的301重定向,在最终的页面上抓取所有资源请求。
之后,从配置文件中获取资源的filter配置,包含规则、排除规则、最大压缩后体积、最小文件体积,等等,最终获取一份业务方想要的离线zip包。离线zip包会带上本次打包的版本信息,同步到CDN上,提供给用户客户端下载使用。
可视化
我们提供了图形界面给业务方进行方便快捷的打包和管理,流程化的打包操作,模块化的配置管理和历史记录,一目了然。
可视化的管理后台具有清晰的步骤、友好的界面、醒目的说明。使用者可以在基本模式和专业模式之间轻松选择,快速打包。
在基本模式中,我们提供了一套默认的打包配置,业务方只需提供极少的信息,就可以实现快速打包;
而专业模式则包括完整的配置选项,可以充分自定义自己想要缓存的文件和规则。
为了方便用户查看和管理以前的打包操作,我们提供了一个打包历史的模块,记录了每一次的操作和结果:
从中可以看到在不同的环境、平台,每次的操作分别新增、更新、删除了哪些资源。
对于管理员来说,不光可以查看每次的操作记录,还可以对离线包内的每个资源进行删除等操作,可以下载对应平台和环境的离线包进行查看,也可以手动上传离线包,简单易用。
系统更新
资源一旦成功打包,并且发布到CDN,用户就可以用了。这个过程,是由爱奇艺APP来完成。对离线资源的更新和下载,都在app启动时完成。APP会比对离线包的版本,自动在后台下载更新的离线包,并解压到本地。如果后面出现网络状况不佳的情况,也不用担心加载离线资源的时候会卡住。
拦截系统
这才是用户能感知到的部分。用户在APP内打开一个内嵌的H5时,Webview容器会对容器内的请求进行拦截,并在解压后的离线包内搜索匹配。一旦找到匹配项,就直接加载本地的资源文件,而不会发起网络请求。这样以来就真正实现了资源的离线化:
写在最后
离线缓存系统给爱奇艺APP内嵌H5提供了一个性能大规模提升的方式,也为业务方控制自己页面的缓存提供了很大的便利。尤其是在3G、4G,以及信号较差的网络情况,甚至无网的情况下,用户体验能得到很大的提升,再也不会出现进度条一直缓冲加载,白屏时间很久的情况(针对大部分活动类页面)。
当然,目前该系统对不同业务的优化程度不同。对于服务端渲染的动态页面,还无法进行全部的离线化缓存。针对这类同构渲染的业务场景,后续我们将推出离线缓存的动态化升级,在必要的服务端请求的前提下尽可能多的进行本地化缓存,自动加载离线化模板,来同样达到弱网、无网环境秒开的效果。
此外,我们也将优化缓存的更新机制,让业务方有更多更灵活的缓存选择。同时我们正在研究一套更智能的离线资源版本管理系统,以期降低离线包更新所带来的用户下载流量。
我们的工作旨在提升爱奇艺APP内H5的用户体验,用方便易用的技术来最大化地帮助业务方提升开发效率和业务转化率。