zh-rocco / fe-notes

:memo: 前端笔记

Home Page:https://zh-rocco.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

【性能优化】常见性能优化方法

zh-rocco opened this issue · comments

commented

性能优化

**:性能优化先优化性能瓶颈(短板),具体问题具体分析。

性能优化的最关键点是首屏。

用户交互时也会出现性能瓶颈:大量 dom 更新(react 性能优势在这,vdom 可以减少不必要的 dom 更新),频繁的页面的重排,动画(动画写的不好性能会很差,比如频繁的页面的重排)。

常见的优化方法

客户端优化

  1. 加载优化(网络方面)

    • 减少 HTTP 请求
      • 合并 CSS、JS
      • 使用雪碧图
      • 小图转 base64,可以受益于 gzip
    • 减少资源体积
      • 压缩 CSS、JS
      • 压缩图片
  2. 渲染和 DOM 操作方面

    • 在网页初步加载时,获取到 HTML 文件之后,最初的工作是构建 DOM 和构建 CSSOM 两个树,之后将他们合并形成渲染树,最后对其进行打印
    • 优化网页渲染
      • CSS 放在头部
        • 保证解析 DOM 的同时解析 CSS
        • CSS(外链或内联)会阻塞整个 DOM 渲染,但是不会阻塞 DOM 解析
      • JS 放在 body 结束标签前或者异步
        • JS(外链或内联)会阻塞后续的 DOM 解析,DOM 渲染也会被阻塞
    • 优化 DOM 操作
      • 避免在 document 上直接进行频繁的 DOM 操作(减少回流和重绘)
      • 使用 className 代替大量的内联样式修改(减少回流和重绘)
      • 对于复杂的 UI 元素,设置 position 为 absolute 或 fixed(减少回流和重绘)
      • 避免强制性同步布局(减少回流和重绘)
        • 比如给某个元素添加了一个类,然后再读取布局信息,这个时候为了获得真实的布局信息,浏览器需要强制性对页面进行布局
      • 批量操作 DOM(减少回流和重绘)
      • 尽量使用 CSS 动画
      • 尽量减少 CSS 表达式(expression)
      • 使用 requestAnimationFrame 代替 setInterval 操作
      • 使用事件代理
    • 操作细节注意
      • 避免图片或者 iframe 使用空 src
        • 避免使用空的 src 属性可以缩减浏览器首屏渲染的时间,因为浏览器在渲染过程中会把 src 属性中的空内容进行加载,直至加载失败,影响 DOMContentLoaded 与 Loaded 事件之间的资源准备过程,拉长了首屏渲染所用的时间;但空的 href 属性对首屏渲染的影响比较小
      • 在 CSS 属性为 0 时,去掉单位
      • 禁止图像缩放
      • 正确的 CSS 前缀,autoprefix
      • 移除空的 CSS 规则
      • 对于可继承的属性,尽量使用继承
      • 缩短 CSS 选择器,BEM
    • 移动端优化
      • 长列表滚动优化,-webkit-overflow-scrolling: touch,视口之外 visibility: hidden
      • 函数防抖和函数节流
      • 使用 touchstart、touchend 代替 click,或者 fastclick
      • 开启 GPU 渲染加速,transform3d、transformZ、will-change
  3. 数据方面

    • 图片加载处理
      • 图片预加载
      • 图片懒加载
      • 首屏加载时显示进度条
    • 异步请求的优化
      • 使用正常的 json 数据格式进行交互
      • 缓存常用的不变数据
      • 数据埋点和统计
    • 组件懒加载、预加载
    • 合理控制 cookie 的大小(每次请求都会包含 cookie)

服务端优化

  1. 服务器开启 gzip

  2. 缓存

    • DNS 缓存,将资源分配到恰当数量的主机名;以减少 DNS 查询
    • 避免重定向,减少多余的中间访问
    • CDN 加速
    • HTTP 缓存:设定缓存时间
      • cache-control
        • public:响应被缓存,并且在多用户间共享
        • private:默认值,响应只能够作为私有的缓存(e.g., 在一个浏览器中),不能再用户间共享
        • no-cache:响应不会被缓存,而是实时向服务器端请求资源
        • max-age:数值,单位是秒,从请求时间开始到过期时间之间的秒数。基于请求时间
      • date:生成消息的具体时间和日期
      • expires:指定了在浏览器上缓冲存储的页距过期还有多少时间,等同 Cache-control 中的 max-age 的效果,如果同时存在,则被 Cache-Control 的 max-age 覆盖。若把其值设置为 0,则表示页面立即过期。并且若此属性在页面当中被设置了多次,则取其最小值
      • last-modified / if-modified-since:本地文件在服务器上的最后一次修改时间。缓存过期时把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比,如果时间一致,那么返回 304,客户端就直接使用本地缓存文件
      • etag / if-none-match
        • (EntityTags)是 URL 的 tag,用来标示 URL 对象是否改变,一般为资源实体的哈希值。和 Last-Modified 类似,如果服务器验证资源的 ETag 没有改变(该资源没有更新),将返回一个 304 状态告诉客户端使用本地缓存文件。Etag 的优先级高于 Last-Modified,Etag 主要为了解决 Last-Modified 无法解决的一些问题
        • 文件也许会周期性的更改,但是他的内容并不改变,不希望客户端重新加载
        • If-Modified-Since 能检查到的粒度是 s 级
        • 某些服务器不能精确的得到文件的最后修改时间
  3. 负载均衡

参考