前言
Web业务的性能优化是一个系统工程,既有深度,又有广度。以下所简称性能均特指Web业务性能。
技术的广度上,主要从大背景下考虑到其各个相关方,基于共同的数据指标发掘和评估方案。
技术的深度上是一个渐进和迭代的过程。可以从性能的本质展到目前各端的主要优化方向。
性能的本质
性能的本质是快速传播, 要素是内容(数据)和流程,效果是:完备、快速。完备不是完整,而是接受的信息要一致,没有歧义。流程是内容处理的过程和方法。
流程从广义上看来源于后台服务器,以网络和客户端为媒介,以页面形式到达用户。落到各端,又可以再次细分为不同的内容和流程,层层拆解。
性能优化就是保障快速传播内容,可以概括为四个流程和三类方法。其中四个流程是指:
- 衡量: 设定指标,建立监控。
- 识别: 识别和梳理出整体到局部对各个层级的内容(数据)及流程。
- 实施: 针对性的进行优化。
- 评估和监控: 通过数据评估是否达成预期,并做定期监控。
各端实施前先理解全业务视角下的内容和流程,以及各自内部的内容和流程。以下为目前识别出的各端内容(数据)及流程:
各端 | 内容(数据) | 流程 |
---|---|---|
整体 | 页面资源 | 后台服务 (图片服务) -> 浏览器(客户端) |
后台 | 页面资源 列表内容 页端接口 |
1.架构 (接入/Docker/爬虫/CDN) 2.发布上线流程 3.内容请求及响应流程(可继续细分, 涉及部署) …… |
图片服务 | 图片 | 1.图片请求接口 2.图片上传发布 …… |
页端 | 主文档 静态资源 动态资源 |
1.前端渲染流程 2.模块加载 3.懒加载 4.统计打点 …… |
客户端 | 统计数据 | 业务逻辑 |
Web Engine | 页面资源 后台响应数据 网络性能数据 统计数据 |
1.网络连接 2.加载、解析、排版、渲染 3.JS执行 4.业务功能 (广告过滤、后台省流省电、统计……) …… |
定义出各层各端的内容及流程后,就可以着手进行优化。
选择优化时机
当我们发现一个问题点,如果确定是不是当时下手解决? 这个还需要在经验中总结提炼.目前总结的原则有两条:
- 优先解决关键路径上的问题.
- 如果解决的问题,不在关键路径上,收益的评估可能不准,如果上线了,其实际效果也往往会被低估.如CSSOM优化.
- 对于不确定的问题,可以使用小步快走的方式,进行快速验证.如中转直连策略.
- 避免微优化。微优化往往会掩盖一些更核心的问题。
- 综合从各端和多维度考虑解决方案.
- 如果单从一端或一点考虑优化,容易出现边优化边引入问题的情况.这时可以通过开放讨论和实验室验证的方式减少影响.如页面之前一次主档精简.
性能优化方法
性能的优化方法上可以概括为: 简(化,减法)、分(离)、预(处理)三类。每一种方法都可以分别从内容和流程上展开典型的方法:
方法 | 目标 | 内容侧 | 流程侧 |
---|---|---|---|
简化 | 尽量少(小),直至没有!!! | 1.去除冗余信息 (请求头,内容…) 2.去除无用的CSS/JS等资源 3.压缩或裁剪 4.缓存及Combo可以减少请求 5.图片优化图片出口流量 |
1.去除不必要的处理和计算 2. 使用更好的处理算法 (查表) 3. 动态策略减少中转或直连请求 4. 不必要的业务逻辑 5. 后台优化存储及服务器布署 6. SPA或模板的应用 7.PRPL原则的应用 |
分离 | 区分不同属性,更加有针对性。 |
动态内容与静态内容的分离 2. 首屏内容(资源)的分离 3. 主文档与正文内容的分离 4. 概要内容(包括低质量图片)与精细内容的分离 |
首屏渲染与懒加载 2. 同步请求改为异步请求 3. 前期不阻塞加载,中期不阻塞渲染 4.区分不同网络的优化 |
预处理 | 重要的内容和事,提前准备。 | 1.预加载(主文档及子资源) 2.预下发 |
1.预热 2.预DNS解析 3.预连接 4.连接复用(包括HTTP2) |
技术演进和整合
演进与迭代
从性能优化上,虽然概括了四个过程和三类的手法,但整体却是一个由各端所在技术领域共同推动的迭代过程。
首先各端的技术领域有很大的交集,大致可以体现为:
但是各端所在的技术领域都有不同的技术演进,各自又都有相应的解决方案,其中以前端和浏览器内核的发展最为活跃,且有各有明显的分段:
端 | 技术要点 |
---|---|
后台 | 1.由于操作系统可以定制,一是借助Linux系统协议栈上的优化,包括HTTP2/QUIC,以及在TCP栈上的优化,二是改进TCP栈的性能、HTTPS的性能、通过改进压缩算法提高数据传输性能等。 2.使用更加精细化的架构和系统来承载服务,同样存在通过细化识别出优化点的过程,包括CDN的部署等。 |
页端 | 自Steve Souders以YUI为始,定制了一套相关的基础规则,包括了Head中的JS, CSS的位置,Cache、Cookies等,并且固化到了YSlow这个工具内。参考<<高性能建站指南>>。 后面又基于Web App发展趋势而有了SPA (Single Page Application,也有称为模板页)模式。同时Responsive Web Design的提出,也有了一套相对应的优化策略。因为前端技术的发散和快速演进的特点,对于将工程化的需求更高。 FaceBook目前可以算是前端技术的领导者, 提出不少问题的前端技术方案,如Instant Article, Network Quality Classifier。特别是RN代表的native化方向,为前端技术应用带来了更大的空间。 |
浏览器 | 浏览器的发展前以Firefox和WebKit为马首,现以Chrome为主导。Chrome之前,浏览器侧重于H5/CSS3/JS等技术体系的支持。自Chrome始,除了继续将技术体系演进到Web Platform外,也再进一步将前端开发者的需求考虑到开发方向上来(见BlinkOn5资料),以开发页面的真实需求驱动Web Platform发展,演进了PWA, AMP等技术,也提出RAIL模型,来统一页端和浏览器内核的目标。 在相同问题,Chrome和Facebook往往有不同的方案,比如AMP对应Instant Article, NQE对应Network Quality Classifier。与Facebook的Native化方向相比,Google则是以PWA(Progressive Web App)推动H5达成Native体验。 针对页端的YSlow, Chrome也在DevTools中提供更为强大的Audit (可以理解PageSpeed Insights增强版),以及评价工具Lighthouse。在网络的层面,和服务器不同的是,Chrome提出了HTTP2(SPDY)和QUIC (UDP),解决网络上问题。 |
从整体看浏览器和页端的技术演进,我们可以看到两个清晰的分段:
- 关注于单项(维度)技术的优化。往往可以从一个Check List的方式入手。比如: 优化点挖掘, 性能优化Check List。
- 体系化、多维度的技术创新。PWA和RN都不能算是技术创新,因为他们背后的技术原型都存在很久了,但是他们经过体系化后,被赋予了一个大愿景,再被不断完善充实,解决一个普遍性的问题。
*后台(服务器侧)因为个人能力和经验的限制,没有看到这个分界线。如果有,欢迎补充。
这两个分段基本也对应到目前性能优化的迭代阶段 (也可能各有若干迭代周期):
- 基于现有技术架构进行各点(面)的优化。
- 这是最重要的基础,往往容易因关注新技术,而被忽略。从业务开发的角度,最好是从一开始就能应用工具和Check List不断纠偏。
- 这一阶段的细化,可以参考: 项目总结 - 过程。
- 应用体系化的技术改造,突破技术瓶颈。
技术整合
虽然Facebook和Google Chrome在技术方向有不同的选择,这是他们作为技术领导者的责任。但是从Web业务上看,技术整合才是必然的,包括Facebook和Google。一个代表前端有控制更多的需求,一个代表Web平台,支持更多的控制,两者的目标并不冲突。
从技术整合的角度来看,需要结合业务特点进行全局的技术方案评估和平衡。比如直出和前端渲染的选择,就还需要考虑到业务单位间的协作和运营的需求。
SPA与模板页
下面以SPA作为一个技术整合评估的示例。在实际业务场景,我们遇到了以下几种提法:
- Single Page Application (SPA)
- 本地模板页
- 主文档缓存和#版本
后者基本一致,SPA与他们的差别就在于可能不需要缓存来实现。所以后两者可以理解为SPA的一种收益较大的实现。
它们的收益来源于:
- 主文档缓存或本地模板页减少主文档请求和响应数据。
- 第二次从页面内跳转到新的内容,可以复用当前运行环境,包括已经在运行的JIT Code, 已经解析完成的CSS Rule Set等。
它们也有缺点:
- 主文档缓存:考虑到改版, 需要使用条件请求,也就是仍然需要发送请求,只是响应在大多数情况会小很多。这个内核和页端配合可以解决,页端保证资源的一致性,内核则允许特定主文档后置验证。
- 本地模板页: 同样是改版的问题,只能是由客户端自己管理了。另一个影响是性能数据可能无法正确收集。
两者是不是有绝对的性能优势还取决于页面的逻辑设计:即使主文档本地化了,正文内容还是需要的,它的发送时间和响应的性能就成了关键因素了。
另外,复用运行环境的收益可以再放大。比如以类似预热的思路,提前加载到空的WebView中,当实际需要请求时,通过#版本的方式就可以完成了。
所以收益最大的方案是四端技术整合:
- 页端&后台: 完成动态数据和静态数据分离,提取出模板化的主文档,并设计启用304条件请求。
- 页端: 同时支持?版本和#版本,确保主文档和资源的一致性。
- 内核: 允许特定域名下的主文档走后置验证,而不是前置验证。
- 客户端: 利用预热的机制,建立一个空白WebView加载主文档。当用户需要打开页面时,切到已加载的WebView,并使用注入JS或#版本加载正文内容,也可以通过JSSDK向外壳直接取数据。
性能优化的方向
前面提到了目前可以确定的两个迭代阶段。我们现在还处于第一阶段。借助U4可以将性能优化推进到第二阶段,将各领域中体系化的技术加以评估、运用, 包括各端技术的深挖。
再往前一步,未来的页面型态会不断细分,相关的技术也会各有差异。我们可以先从业务类型区分开始,针对性的演进跨端的体系化方案。
对页面分类,从性能优化角度看,最终以页面在Web Platform(浏览器内核)上效果来体现.所以采用对内容(数据)和流程(行为)细化最为合理:
- 资源数
- 资源大小
- 多媒体资源占比
- 用户所处的网络环境
- 后台服务器部署
- 动态资源大小及占比
- JS执行时间占比
- 渲染开销
- 依赖于特定的技术
- ……
定出类型后,就可能对应运用简分预挖掘优化策略。