速度优化相关调研

主要记录下速度优化相关的调研

速度指标定义与监控方案

速度指标定义

如上文所述,做速度优化,需要给速度进行量化定义

调研了下速度指标的定义方式

  1. 网页类产品:比如搜索,其实相对比较简单只有2个页面:首页、结果页,速度指标都是以首屏时间80分位来定义,这个首屏时间指核心DOM加载时间,比如搜索结果页就是网页中部,不包含右边和最底下推荐的搜索结果主体部分,而不是指占满整个屏幕的时间;但是移动端又不一样,移动端由于屏幕大小的限制以及操作方式,整个屏幕都是正文,这个首屏时间又变成了真正的首屏时间,就是占据屏幕的时间,不过一般打点都会往下打,防止用户快速下滑,这个
  2. 端上产品:端上情况比较复杂
    • 第一种 其实还是网页,比如京东和美团不少页面^1,定义方法类似1
    • 第二种 是个网页但又不仅仅是个网页,这种主要是通过JS来调用APP本身的能力来进行渲染展现,可以理解成是个本地的网页,然后后端主要是输出接口
    • 第三种 完全是Native实现

上面第二种和第三种大体还是类似于网页但是又不太是,还依赖端的一些能力,所以端本身也要消耗一些时间

理想的速度指标应该反映出用户的浏览速度体验,我看到有一个指标很不错,叫做用户可操作时间,最终还是需要结合业务进行制定。

监控方案

网页类的产品监控方式2种

  1. 多地采集点进行页面性能监控,早年这个东西做的最好的是基调网络(主要是采集点多)后来出现不少此类产品,监控宝、各种云(阿里云 百度BCE)里面都自带类似工具;不过这个方案其实只适合做网站可用性监控,页面性能监控基本被淘汰了,毕竟一方面配置的页面不可能太全,覆盖面有限,另外一方面这种东西实现方式不一,很多前端优化在这个上面体现不出来。
  2. 网页自身JS打点,把所有需要的信息带在参数里面去访问一个空图片,然后后端统计日志,计算出来,再做个展示的平台,这个虽然看上去要做的事情比用现成的方案多,但是这个基本是目前的主流,另外百度内部也有现成的做好的平台,直接引用JS再设置下就行,另外JS打点的逻辑也值得说下,见脚注[^2]

[^2]: 要监控的数据: 白屏时间、首屏时间、用户可操作时间、Timing API数据(DNS TCP连接 首字节 传输完成 domComplete loadEventEnd) 白屏时间监控放在head底部(因为浏览器只有加载并解析完头部才会真正开始渲染页面,可以通过这个来监控白屏时间),首屏时间(放在HTML代码渲染时,浏览器上首屏末尾处DOM元素所在的代码位置处,会计算首屏内图片加载的耗时当成首屏时间),用户可操作时间(在domready的地方标记)

APP类的产品监控方式也有2种

  1. 类似上面网页监控方式的1,代表产品是听云、博瑞、oneAPM等,和网页监控的区别就是这个是走的移动网络的监控点,可能是一堆手机在那监控。。。这个事情其实类似上面的问题,做过的基本都是以失败告终,意义实在不大,不是说APM意义不大,APM是另外一个概念,是在APP里面嵌入SDK
  2. 客户端日志回传,自己的东西还是自己清楚,利用客户端本身的能力去记录

速度优化方案

看到的一些常见的速度优化方案,这里聚合罗列下,冒号后面是我的理解和解释

基础网络

  1. 全国多接入点:移动网络下,网络传输时间占据了相当大的一个比例,所以接入点越多离用户越近速度越快,这里要具体分析下自己业务的用户群体以及网络情况
  2. BGP接入:由于跨运营商的问题,对于移动应用,3大运营商接入点必须有,否则会出现各种奇怪的现象(移动会对跨网流量随机丢包)
  3. 动态代理加速?

基础层协议参数

  1. 优化拥塞窗口
  2. TFO TLP
  3. 长连接
  4. Chunked:http 流式异步传输协议;服务端收到请求后分段返回,浏览器立即渲染。

应用层协议

  1. Head压缩:这里指发送请求的头部大小,有实验证明发送请求的头部大小会强烈影响首字节,基本结论是在1000字节以下,请求时间随头部大小增加变化明显,在1000字节之上,呈缓慢的上升趋势,后续详细实验下
  2. HttpDns IP方式访问后端 : 这个腾讯写的一个文章介绍的比较详细,DNSPOD也有现成的产品。百度看资料实际很早之前也有了,然而又是秘而不发。最早可能是为了防止DNS劫持,不过也可以用来提速,把DNS解析时间干掉,实现成端预请求获得所有APP要访问的域名和IP列表,请求都走IP(不过这个可能有限制,可能需要全部改成POST请求,不然依赖域名的接入服务,就没有办法路由请求了)
  3. Spdy Quic:Spdy是HTTPS的多路复用,介绍HTTPS握手时间(考虑到我们已经全部是HTTPS了) QUIC是用UDP承载HTTPS的流量,不过这些都处于调研阶段,需要端上配合,服务端使用也不是太普遍,没看到内部实践例子,可能比较难实践

前端页面优化

  1. 理想页面布局:css前置,js后置尾部,html的js回调
  2. 理想页面内容:gzip 压缩页面size,减少js,减少图片数和size。
  3. DNS预解析:和HttpDns目的类似,干掉DNS解析时间,毕竟移动网络DNS解析要几十ms呢
  4. 资源预测加载:提前加载图片资源,图片预取,资源预取
  5. 页面分块加载:这个我们用不到,指PC网页的,移动网页没有那么多块,顶多是把首屏下面的分块加载
  6. 异步化:这个提醒在搜索引擎上就是instant search,具体可以google 谷歌的实现

服务端优化

服务端前端

  1. 并行渲染:不懂,应该是smarty相关的,我们都是接口不出页面用不到
  2. HHVM:HHVM方案已经比较成熟了,对于CPU和速度都有很显著的提升,这个是在多个产品上有过证明的,当然HHVM本身会代理一些兼容性问题,可能需要修改PHP代码
  3. 调度串行改并行:服务端前端基本是调用一堆后端,PHP程序员的思维基本是串行写逻辑,这个需要改下,把所有请求改成并行的,建议是先并行请求需要的数据,然后根据返回的数据在串行写自己的逻辑,可能会导致代码的可读性变差些,就看怎么实现的优雅点了。
  4. 图片压缩 Base64编码:移动端不需要过大的图,毕竟屏幕大小在那,而且很多图根本不会让用户放大了看,所以适当的压缩下图片大小,可以结合用户的网络制式和屏幕大小来动态调整,至于不是外链的图,自己产生的图可以直接base64返回,不变的图,前端直接放在前端代码里。
  5. 慢速识别,简版展现:这个之前管过,叫做速度适配,基本思路是根据用户的网络情况,展现不一样的网页,慢速的展现简版的网页,快速的展现元素多比较炫的网页,不过我们是服务端是不渲染HTML的,都是前端渲染的,而且这个得跟PM和UE聊聊,不一定同意。

服务端后端

  1. 全局全机房Cache:全机房统一全局Cache可以明显提升命中率,但是也有稳定性风险,异常就没有备份了
  2. 预充Cache:预充预取是移动端提速2大法宝,先模拟用户访问,预充下Cache,真正用户访问时就已经在Cache里面了
  3. 并行计算

预取架构

这个有一套大的架构,并且有很多有趣的策略,不过都是很个性化的,这里不方便说,主要方法是提前把用户可能要访问的东西请求回来,用户真正点的时候直接加载了

这个网页通过JS就可以弄,但是App里面还依赖App本身,感觉我们App的实现不一定能搞预取的事情。