前端优化系列 - 前端优化的思考

  1. 云栖社区>
  2. 博客>
  3. 正文

前端优化系列 - 前端优化的思考

atuanxy 2018-08-04 11:23:00 浏览1674
展开阅读全文

前言

Web强大的生命力,得益于它所推崇的一些革命性的思想,

  • 无中心: 没有中央控制节点,可以自由的在网络发布任意内容。
  • 无歧视:所有网络参与者可以平等的进行交流,不受操作系统,网络运营商,等等的影响。
  • 自下而上设计: 鼓励大家参与和实验,而不是由一小部分专家编写和控制。
  • 普遍性:所有人都可以在网络上发布任何东西,不受硬件,地理位置,信仰文化,等等的影响。
  • 共   识:大家可以自由的参与规范的讨论,但必须遵循已形成标准的规范。

正是这种自由平等开放共享的精神,使得Web面对各种挑战,依然能一次又一次的焕发生机。

而在Web技术的应用过程中,我们往往会忽略这些内在的精神,更加关注一些更加具体的指标,比如性能指标。

在性能指标方面,前端往往缺乏非常精确的衡量手段,但几乎都会得出Web性能不如Native性能的结论。

然而事实真的如此吗,Web在各个方面都比不上Native吗?

从技术的角度来看,Native App可以直接运行在操作系统上,可以直接调用系统API,而Web App (or Page) 只能运行在浏览器,通过浏览器去调用系统API。

通过浏览器去调用系统API,这中间流程的性能损耗处于什么级别呢?很小,C++/Java代码执行的成本非常低,整个调用流程一般在毫秒级别。

那么,我们为什么会得出Web性能不如Native性能的普遍结论呢?

可能有下面几方面的原因:

(1)Web页面需要运行在浏览器上面,而浏览器的执行流程对前端来说是一个黑盒,在不了解这个黑盒的损耗的情况下,只好假定它的损耗是非常大的。

(2)一些前端框架的性能并不理想,特别是一些框架的初始化特别耗时。框架的执行流程对前端来说也是黑盒,框架的性能也会笼统的认为就是浏览器的性能。

(3)Web技术的使用方式灵活多样,不同的使用方式效果差别很大。一些Web技术使用不当,也可能会引入性能问题。

那么,怎样才能更好的使用Web技术呢?我们下面重点讨论一下,在进行前端优化时,我们可以有那些思路。

优化的基础

(1)精确的指标衡量体系

我们在进行Web优化之前,首先要做一些基础的事情,比如,建立能准确体现用户体验的指标衡量体系。

如果衡量指标不精确,优化效果可能会与我们理想的目标背道而驰,甚至会出现指标表现一片大好,而用户却处于水深火热之中的情况。

首屏性能指标体系方面,UC浏览器一直走在行业的前面,主要表现在:

(1)行业内很多公司使用实验室数据作为指标数据时, 我们就早已使用真实用户统计数据作为指标数据。

(2)在内核层面使用自有算法去计算首屏性能,精确度非常高,远高于Chromium的First Meaningful Paint

注:iOS 未开放内核, 所有浏览器只能使用系统内核,所以iOS上还未能实现UC浏览器的首屏性能指标。

出于多端指标统一的考虑,业务方往往会选择 WebViewClient.onPageFinished 或 PerformanceTiming.loadEventEnd 作为页面性能的衡量指标。

虽然这些指标不能很精确的衡量首屏性能,但也能成为多方可接受的折中方案。

目前UC浏览器也在与业务方一起建立一套统一的指标衡量体系,希望大家能在标准统一的情况下进行业务的优化。

(2)明确约束条件

我们在进行Web优化时,需要明确一些约束条件,在满足约束条件下达到指标最优。

比如,我们使用loadEventEnd作为页面性能指标,但这个指标仅仅反映了资源加载的性能,并不能反映首屏渲染的性能,或者用户可交互的性能。

我们不能为了提升loadEventEnd,将所有的资源都优先加载,而阻塞了页面排版渲染。即需要在首屏性能(T2)不变差的前提下去优化loadEventEnd。

再比如,我们都知道,资源预加载到本地,将联网性能转化为本地性能是优化性能的重要手段。但是,预加载一般会存在使用率不高,服务器压力过大等等问题,即我们不能为了提升100ms的性能而让服务端增加100台服务器,而应该在服务器部署成本不提升的情况下去优化性能。

初级优化

我们在进行Web优化时,需要分阶段有步骤的进行。我们先聊聊初级优化。

初级优化,并不代表简单或者不重要,而仅仅代表它是其它优化的基础,有比较成熟的优化实践指导方案。

初级优化一般是指正确使用Web技术和前端架构,包含但不限于:

(1)使用恰当的前端框架。

(2)使用恰当的前端技术架构。

(3)使用恰当的Web技术。

(4)按规范使用Web技术。

(5)正确使用Cache和压缩图片。

我们举了一些例子进行说明,

权威统计机构Http Archive的数据表明,所有页面的平均数据, 图片占页面大小的50%以上,其中压缩率比较高的WebP格式图片仅占1%, JPG+PNG+GIF图片占比96%。

我们业务的例子,2016年奥运会期间,UC信息流一些图片使用了未经处理的PNG图片,甚至有大小超过5M的单张图片。

我们再看看Cache的数据,Cache有效期为0,即不能缓存的资源,占比50%。这个比例是非常惊人的,即平均每个站点有一半的资源是不能缓存的。

这些看似简单基础的事情,大部分页面都没有做或者没有做好,会严重影响页面的性能和用户体验。

我们再聊聊前端框架,在使用前端框架时,需要先了解它的性能,特别是初始化性能。参考:前端框架启动速度对比

举个例子,滴滴出行页面,app.b6a92cf724d79c664f2f.js 执行耗时可超过1.5秒,主要是框架的初始化耗时,

各种前端框架都有它的初始化成本,我们一般需要选择合适自己业务要求,性能又还可接受的框架。

出于各种原因,比如一些历史原因,或者业务原因,我们很可能选择了性能较差的框架,我们也需要了解它的详细性能数据,做到心中有数。

中级优化

中级优化,一般是指结合业务场景,灵活使用数据和工具,定位和解决页面存在的问题。

各种页面在各类业务场景下,存在的问题往往都不一样,需要具体问题具体分析。

但分析问题的方法或手段都是相通的,包含但不限于:

(1)综合分析用户数据,挖掘问题。

(2)灵活使用Chrome Devtools 开发调试工具, 调试页面和定位问题。

(3)灵活使用 Lighthouse,检测页面和解决问题。

用户数据,是真实反映用户实际情况的。用户数据的分析也非常有讲究,各种分析维度都会得出各种结论,要合理的使用恰当的分析维度。

比如,用户手机系统,网络类型,地理位置,等等。

Chrome Devtools 开发调试工具 是前端开发调试神器,里面包含的功能非常强大,几乎能分析所有前端的疑难问题。

我们提取一些特色功能进行介绍,

(1)Timeline

Timeline可以记录页面运行过程的所有细节,能用于分析页面出现问题的具体位置。

举个例子,UC信息流页面,在2016.8.5页面改版之后,页面首屏渲染时间(T2)变长200ms。

改版前的Timeline是这样的:

57c29b279c8c6fc7f51f78ba6a2711cff8572366

改版之后的Timeline是这样的:

e3e1ee5e09b3e7d3caebedeccb2b79af934b866d


原因是一些期望在T2之后执行的JS逻辑,在T2之前就被执行了,从而延后了T2的渲染时机。

出现问题的代码:

_article.main(function() {
          _article.fsTime();
          cb && cb()
        });

修改也很简单,将一些非首屏的渲染逻辑延后一些执行:

_article.main(function() {
          _article.fsTime();
          setTimeout(cb,20);
        });

当然, 上面只是使用Timeline的一个简单例子,与页面执行时序相关的问题,都可使用它协助分析。它的更多优秀功能,需要大家自己去探索发现。

(2)Profile

Profile 也是一款很强大的分析工具,它可以分析页面的内存使用情况和JS/CSS执行时间。

一般地,我们可以使用Timeline定位出现问题的大概位置,再使用 JavaScript CPU profiler 详细分析每个JS函数的执行情况,找到具体的问题点。

58f8a57796fa3b8975274018c56b54e661301b15

image-profile

(3)Chrome Trace

Chrome Trace 数据记录了页面在浏览器内核执行的完整过程,粒度精细到每个函数方法。使用Trace数据可以分析页面在浏览器内核执行的细节。

根据Trace信息,可以很准确的定位具体的问题,前提是前端同学能够理解具体的函数方法在浏览器内核中的含义,所以对前端的要求是非常高的。

正因为Trace分析对前端的要求过高,Chrome又推出了基于Trace的分析工具Lighthouse。Lighthouse能根据特定的模型用例,得出前端易懂的分析结果。

比如,它可以检测页面是否符合PWA的要求,分析页面在关键路径的耗时。

UC浏览器针对Lighthouse进行了扩展,能够更加全面准确的分析前端关注的问题,比如,它能分析页面JS执行的总体耗时,超过50ms的JS执行函数,页面缓存命中情况,LocalStorage使用情况,排版渲染执行情况,等等。

针对业务所在的业务场景,进行一些定制的优化,往往能带来巨大的性能提升。比如,一些客户端的业务特别集中,页面非常稳定,那么,就可以使用提前下发离线压缩资源包的方式,让关键资源都从本地读取,加速页面的加载性能,和减少网络错误。

高级优化

前面讨论的优化,主要参与者是前端,主要受益者是分析者自己的页面。更高级的优化应该是怎样的呢?

高级优化一般是指全链路拉通进行优化,优化前端页面/框架,后端服务器/中间件,内核,图床,等等,并将优化结果集成到工具,形成自动化检测案例。

我们先来看为什么全链路拉通很重要。每个端(前端,后端,中间件,图床,内核,等等)都有自己的视角,很难看清楚整个链路的问题。

而页面性能问题可以发生在链路的任意一个节点,问题的解决方案在各端都有区别,通过全端拉通我们可以选择最优的解决方案。

举一些例子,

(1)在UC信息流优化过程中,我们多端拉通得出了一个首屏图片预加载的方案,改动涉及到页面,服务器端,图床,浏览器内外壳,最终提升整体性能近300ms。

(2)在支付宝H5性能优化过程中,我们与支付宝容器,网络库,多端拉通,最终分析出支付宝容器和托管网络库存在性能问题,修正问题后带来较大提升。

(3)在UC自媒体页面优化过程中,我们与页端,运营端,多端拉通,最终分析出运营一些配置使得页面文档无法缓存,而这个问题是可以避免的。

这样的例子还有很多,都说明了多端拉通在性能优化中具有非常重要的作用。

多端拉通进行优化,我们的视角更加全面,解决问题的思路也更加开阔。选择在最合适的端进行解决问题,解决问题的方法不再局限于修改前端页面。

我们也可以加强浏览器与前端的交流合作,在浏览器内核或前端框架层面,进行更加高效的优化。

前面也提到,一些前端框架的性能并不理想,我们期望与前端合作,一起去优化一些流行的前端框架的性能。

页面优化,通常属于一种补救手段,而不应属于一种常态,我们不期望同一页面的性能需要反复优化。

我们期望一些优化成果能够固化到工具层面,通过工具自动化去监测页面性能,让工具去保障页面能够持续具备优异的性能。

展望未来

前面重点讨论了前端优化的一些思路,我们再回到Web技术发展前景的问题。

Web技术所推崇的自由平等开放共享的互联网精神,得到了全世界的普遍认可。在Web技术发展之初,就由万维网发明人Tim Berners-Lee 带领成立了万维网联盟(W3C理事会)。W3C致力于构建广泛参与的、知识共享的、具有信任的全球规模的Web。目前W3C成员已经有超过400个研究机构或组织,其中包括Apple, Inc.Google, Inc.Microsoft Corporation 等全球顶级科技公司。有成千上万的科学家参与Web标准规范的制定和实现,我们有充分的理由相信Web技术的长远发展是有坚实的技术和人才保障的。

回顾历史,PC年代早期,大家都去下载Windows软件,随着PC电脑的不断进化,网络带宽的不断增强,现在大家很少会下载PC软件,基本以浏览器为主。

移动互联网时代也是一样,目前手机内存3G及以上的占比已超过50%,WIFI+4G网络占比已超过90%,手机处理能力和网络带宽已不是Web技术的瓶颈。

Google Chrome 在2014年推出PWA系列技术,给前端开发者全面开放浏览器的底层能力,包括但不限于,消息推送通知拦截资源请求管理资源缓存添加到主屏幕在合成器线程上同步运行用户代码,等等。

iOS Safari 在2018.2发布的Safari Technology Preview Release 49宣布正式支持Service Workers。主流浏览器都会全面支持PWA相关技术,前端能在Web上面发挥的空间会越来越大。

Web技术的繁荣发展,需要每一个开发者的共同努力,包括前端,浏览器,服务器。特别是前端开发者,前端每一次技术选型,每一个页面取得的效果,都与Web技术发展息息相关。UC浏览器期望与前端开发者紧密联系,共同打造繁荣的Web生态。

参考文档

History of the Web

我们真的需要“小程序”么?

开放、自由的「互联网精神」是好的吗?

网友评论

登录后评论
0/500
评论
atuanxy
+ 关注