前言随着移动互联网的发展,用户对产品体验的要求越来越高。H5作为重要的业务载体,在移动端应用广泛,因此H5页面性能是一个非常核心的用户体验指标。本文结合【饿了么首屏优化实践】介绍页面性能优化的思路。首屏性能指标性能优化的首要依据是数据和指标。没有正确的数据和指标指引,优化思路和方向可能会出现偏差。UC在首屏性能指标统计上支持内核指标和标准W3C标准指标。Kernelindicatorstart:blink内核开始创建请求的时间点,可以理解为“0”点T0:blink收到httphead的时间T1:第一屏显示内容的时间T2:首屏全部显示的时间PerformanceW3Cindicators首屏时间是指页面首屏所有资源全部显示的时间。这对于用户来说是一个非常直接的体验指标,但是对于前端来说却是一个非常难以统计衡量的指标。通常的做法是,domContentLoadedEventEnd-fetchStart,甚至使用loadEventStart-fetchStart,此时页面DOM树已经解析完毕,内容显示出来。下面给出一种页面性能指标的统计方法。性能监控在线监控对于数据分析和问题发现具有重要意义。一般我们在测试阶段只能做基础分析,很难在不同环境下得到真实准确的数据。那我们如何知道上线后是否出现了性能问题,或者如何尽快消除问题的苗头呢?实时在线监控是最好的选择。悦影全景监控平台可以对SDK采集上报的数据进行实时分析,可以直观方便的查看应用的性能指标。并通过设置告警规则,当性能指标达到阈值时,及时通知,第一时间发现问题,及时处理。实时行情通过实时行情,初步了解业绩波动。查看性能趋势查看页面性能,通过firstbyte、DOMReady、页面满载等核心指标分析首屏性能和页面加载性能。(如果接入了UC内核,可以通过T2直观了解首屏性能)分析定位具体页面进一步分析,了解TOP访问页面的性能。通过多维度聚合分析,进一步定位问题范围,分析性能优化思路,通过在线数据分析透彻后,可以继续深入分析优化。1优化方向前端:前端围绕优化首屏、汇聚域名、js资源管理、js耗时管理、图片管理、界面管理等方向展开。客户端:客户端围绕提高容器启动速度,优化拦截逻辑,为前端提供预加载等各种能力,提供类原生体验。【干货预警】下面是我们在饿了么H5优化项目中的整体优化思路。H5资源和数据都依赖于网络,因此优化的一个主要策略是预加载。我们先来了解一下H5场景中常见的缓存有哪些。HttpCache:通过一定的规则,将网络返回的资源缓存到本地,下次使用时可以直接从本地读取。stale-while-revalidate可以让资源在过期后继续使用一段时间,同时发起异步请求,让资源先使用后验证。LocalStorage:前端可以使用LocalStorage在本地存储资源,类似的还有IndexedDB。LocalStorage也有一些限制。比如一个域名只能存储5M的数据,不能跨域读取。MemoryCache:内存缓存。Chrome中的MemoryCache主要由GC管理。当一个资源进入MemoryCache时,会关联一个弱引用,当主文档关闭时会被清除。离线包(ZCache):当用户访问一个页面时,内核会通过shouldInterceptRequest向shell询问是否有可用资源。如果有可用资源,shell将返回资源,而无需去网络请求资源。【ZCache会去shell拦截逻辑,效率比HttpCache低。一般资源到达Blink核心需要100ms,主文档需要300ms]NetCache:DNS分析结果,长期连接复用。V8BytecodeCache:V8字节码缓存。【JS已经执行过一次,第二次执行可以明显减少时间】。ImageDecodeCache:图像解码缓存。PageCache:页面级缓存,UC上角的WebViewCache,点击UC浏览器上的前进后退按钮,会生成WebViewCache。对于这些缓存,我们通常使用预加载的方法。提前加载全屏文档:主要用于信息流,提前加载前几个Item的文档,用户点击秒访问。首屏提前加载图片:主要用在信息流中。当您点击访问文档时,同时发送图片请求。当文档解析需要图片时,首屏的图片已经提前加载到本地。链接预加载:在资源响应头或主文档头中标记需要预加载的资源,内核会按照一定的规则和优先级提前预加载这些资源。Modulepreload:类似于Linkpreload,但是是模块级预加载,除了预加载模块的依赖资源外,还可以提前编译解析模块JS。链接预取:域名提前寻址。提前加载界面数据:空闲时导航预加载&算法预加载。关于界面预加载,我们在js插件中进行。当然也可以在网络库中间件中拦截处理。HTTP接口预加载的两种实现:shouldInterceptRequest拦截:拦截这里是否有Response缓存,返回return。缺点是不能做接口同步。MtopWVPlugin(ANetBridge)拦截:我们和MtopWVPlugin一样重新实现了一个JSPlugin扩展,在扩展层做拦截。2性能分析工具和平台鲁班尺:UC鲁班尺基于Lighthouse,会在内核中分析页面的实际渲染情况,并给出优化建议。SeagullLabs:UCSeagullLabs是一个性能分析平台,可以提供全面的首屏、内存、启动、帧率分析数据。Lighthouse:检测页面性能瓶颈。Timeline:记录页面运行过程的具体细节,用于分析页面出现问题的具体位置。Profile:分析页面内存使用情况和JS/CSS执行时间。一般可以使用TImeline定位到大概位置,然后使用JavaScriptCPUprofiler详细分析各个JS函数的耗时情况。ChromeTrace:记录页面在浏览器内核中执行的完整过程。粒度和每个功能方法一样细,可以准确定位具体问题。优化实践下面我们就来看看如何分析一个H5页面的性能优化点。1可以使用UC鲁班尺平台获取性能分析数据。它将生成性能报告。鲁班池以灯塔为蓝本。Lighthouse在本地运行时,除了生成性能报告外,还可以生成ChromeTrace文件供我们分析。当然,您也可以在本地捕获Timeline和ChromeTrace日志。拿到性能报告后,我们可以大致看出哪些地方耗时,资源加载,S耗时等,然后根据Trace日志进行分析。2获取T2日志并分析T2时间线。如果连接了UC内核,就可以分析T2日志了。分析的时候注意几个数据:frameCount:最后一个T2的frameCount,说明T2的计算是在这一帧完成的。我们在Trace界面搜索T2Paint_Event,找到这个frameCount,按m键,标记T2线。tStart:表示T0开始计算的时间,搜索TStart_Point即可定位到该点。确定了T2线之后,就可以分析T2线之前的页面渲染情况,以及影响页面渲染的因素。3整体性能分析分析T2之前渲染的整体效果,比如JS执行时间长的部分,加载时间长的部分。4、加载性能分析主要是指Doc、界面、各种资源的加载性能。一般来说,如果加载时间超过300ms,就被认为很慢。主要看资源是否被离线缓存。5排版性能分析主要分析排版内容是否合理,排版时机是否合理,是否有大量重排和刷新样式。6JS性能分析JS性能主要包括三个方面:JS解析编译耗时JS对应业务逻辑JS具体函数执行耗时一般来说,v8.compile需要100ms以上,比较耗时。另外需要注意两次v8.run的执行间隔。一般来说,有间隔的时候,就是在等待一个接口或者资源。这方面可以优化,比如界面预加载,资源下线等。然后用timeline分析具体功能的耗时,找出耗时较多的js功能,进行相应的优化。7观察图片解码对T2时间的影响一般来说,影响T2计算的因素有两个:图片解码和渲染。首屏内容发生变化。(滑动、图片懒加载、动态节点)图片,尤其是小图标,在某些页面上会明显影响T2时间。比如饿了么的红包页面,经过分析,红包列表中的小图标大大延长了T2时间,实现后改为iconfont。优化T2耗时1400多ms,性能提升45%以上。所以我们可以用IconFont或者css替换这些小图片(svg矢量图无法计算图片的宽高,所以不计入计算)。如果有些图片需要忽略T2计算,也可以使用uc-perf-stat-ignore(新版本内核支持3.22)flag。对比UC的T2Paint_Event和W3C的loadEventStart的时间差,观察图片解码对T2计算的影响。搜索DecodeImage观察图片的解码
