前端性能的监控和优化

385 阅读5分钟

[TOC]

目标

  • 理解性能监控和优化的一般方法
  • 移动端的性能
  • 运用工具来监控和优化

性能优化的重要性

1. 性能和PV直接相关
2. 性能与收入有关
3. 前端容易产生性能的瓶颈
4. 无线设备性能问题更明显

反面案例: 百科某次上线,性能下降20% ====> PV流失近15%====> 收入下降10%

移动端更严重 DOM ready时间: wifi 2.3s, 3G/4G 4.2s, 2G 首字节5-6s, 8s+

一、何为前端性能

打开一个网站,需要经过多少步

性能优化的一般思路

  1. 减少请求次数
  2. 减少请求体积
  3. 加快请求速度
  4. 缩短渲染时间

二、指标的确定、采集和分析

基于用户角度的关键指标选取

  1. 页面打不开 -- 白屏时间(DNS查询,TCP连接,发送请求,等待响应)
  2. 页面显示不出来 -- 首屏时间(html传输,静态资源下载)
  3. 按钮点击不了 -- 用户可操作(解析文档,执行JS/CSS规则,计算布局)
  4. 图片显示慢 -- 页面总下载(渲染完成)

怎么采集展示

页面打开的时间起点到页面渲染完成的时间各阶段时间分布,总占比

数据波动

波动即意味着性能发生变化,需要注意

占比更重要

总下载的时间,各阶段的用户下载占比(很快0-2,较快2-4,可接受4-8,很慢8+)

数据采集-首屏时间
图片是制约首屏的主要因素

获取首屏图片的加载耗时即可获取大概首屏时间
首屏统计流程
  1. 首屏大概位置执行统计JS
  2. 绑定所有图片加载事件
  3. 页面onload之后找到最慢一张图片加载时间
数据采集- 可操作时间
DomReady或核心JS加载完毕
数据采集-总下载时间
onload or 异步渲染完成

浏览器性能API

Performance Timing

Resource Timing

三、常用的优化方法

  1. 雅虎性能优化军规
  2. 可优化的点
    1. DNS查询
      1. DNS缓存(浏览器、操作系统)
      2. 减少DNS数(一个页面不超过4个, DNS预查询dns-prefetch)
    2. 建立连接
      1. 使用CDN 提速10%-20%(缩短距离,降低连接时间)
    3. 发送请求
      1. 减少HTTP请求(打包JS,CSS文件,图片合并)
      2. Keep alive 减少TCP请求连接数
    4. 内容传输
      1. 文件压缩(js, css, html),代码混淆 60%+
      2. 代码精简 减少无用代码,提高质量
      3. gzip
    5. 缓存
      1. Expires、Cache-Control
      2. Last-Modified
      3. Etag
    6. 充分利用缓存--强缓存(文件名md5后缀)
  3. 前端工程化与性能优化--静态资源管理 自动将样式表放在头部,脚本放在底部,并按需加载
  4. 代码的性能--css
    • 书写高效的CSS selectors
    • 删除没用的CSS代码
    • 避免使用CSS expressions(实践中比较难~~~)
    • 把CSS放到页面顶部
    • 不要缩放图片--很大的图片缩到很小展示,耗性能
  5. 代码的性能--JavaScript
    • 数据结构和算法优化
    • 避免with, eval
    • 减少跨上下文查找: 全部变量、属性
    • 避免arguments、debugger
    • 缓存计算结果
  6. DOM才是性能大头
    • 避免DOM重绘(避免访问childNode数组,读写分离),不在for循环重绘DOM
    • 收回、重复利用DOM
    • 缓存数据而不是DOM
  7. MVVM 框架的DOM 只在需要时才更新DOM 性能:JS Engine > Render Engine
  8. React的性能优化
    1. shouldComponentUpdate / PureComponent

    2. 全局数据store管理(redux) + immutable

    3. 在shouldComponentUpdate里全部return false,在componentWillReceiveProps里判断是否需要更新

          export class Line extends React.Component {
              shouldComponentUpdate(nextProps) {
                  return false;
              }
      
              componentWillReceiveProps(nextProps) {
                  // 只有某些数据发生改变时进行绘图
                  if (this.props.data !== nextProps.data) {
                      this.refresh();
                  }
              }
              ...
          }
      
    4. Debounce防抖延迟更新 compositionstart, compositionend 解决中文输入时的频繁更新

      export default class DebounceText extends Component {
      
          componentWillMount() {
              this.props_onChange = debounce(this.props.onchange, 300);
          }
          onChange = val => {
              this.setState({
                  value: val
              });
              this.props_onChange(val);
          }
          render() {
              let props = Object.assign({}, this.props, {value: this.state.value});
              delete props.onChange;
              return <Input value={this.state.value} onChange={this.onChange} />
          }
      }
      
    5. React 性能优化

      • redux --> mobx, mobx-state-tree 对redux性能优化,主动用observer观察数据的变化...
      • 避免过度的动画效果

四、极致的性能优化

  1. 懒加载(lazy render), 逐屏加载,优化首屏时间
  2. bigRender 减少DOM数,提升首屏(DOM树转为注释,页面滚动到指定位置才加载)
  3. bigpipe 一次请求,分chunk方式获取所有内容,后端并发 Request-header (http 1.1)
    • transfer-encoding: chunked
    • content-length 先给前端吐一个结构,在HTML结束后,输出一些js代码渲染内容上去 性能提升 贴吧首页白屏提升40% FRS页贴吧列表区展示时间提升20% 弊端 代码复杂度 后端成本

五、移动端的性能

  1. 显性加载- loading页

  2. 首屏优先

    • 单页应用首屏后端渲染
    • 逐屏加载
    • 滚动加载(用户无感知,提速30%)
  3. 减少首屏图片数量,减少请求

    • 使用其他方式代替图片: css3,svg,iconfont
    • 合适的图片类型: webP > jpg, png8>gif
    • 避免使用dataURL
    • 响应式图片 分辨率、Retina srcset, picture
  4. 加载过程的优化

    • 预加载: 提前加载下一页
    • 避免302重定向
    • 异步加载广告等第三方资源
    • 减少cookie:静态资源域名不适用cookie
    • 长缓存
  5. 执行过程的优化

    • 合理使用CSS 3D加速
    • 避免批量绑定数量,使用事件代理
    • 严格控制DOM数,缓存数据而不是DOM(不超20层)
    • 用touchstart, touchend代替click
  6. 利用Native的能力

    将一些不频繁更新的一些东西本地化

    • Hybird的加速方式
      • 模板资源本地化,极大提速首屏
      • 模板资源的增量下发
      • 图片缓存:imageCache
      • 利用NA(native)的Request、socket长连接
      • 利用NA获取用户信息、位置等

    手百使用Hybird的性能收益

    • 相比H5方案,首屏时间降低60%+
    • 模板增量下发,体积减小90%

总结

前端性能十分关键,影响PV 和收入 找到关键指标,用统计到的数据说话 性能优化贯穿页面的整个响应过程 无线端更需要优化 监控-分析-优化,利用现有的工具方案