性能优化篇

97 阅读5分钟

性能优化篇

从输入URL到页面展示, 中间都经历了什么?

  • 卸载老页面
  • 解析URL是否合法
  • 检查缓存
  • DNS域名解析
  • TCP连接,3次握手
  • resquest http请求
  • response http响应
  • 浏览器进行解析和渲染
  • 页面加载完成

打包构建

css js

公共代码压缩, 压缩合并css, js

第三方插件按需加载

组件按需加载, ui 组件按需加载, 路由组件按需加载

图片base64转码

将小图片转化成base64, 减少服务器资源请求

常用插件库使用CDN加速

比如vue vue-router axios elementUi

iconfont 代替图片

资源请求优化

DNS域名预解析
<link rel="dns-prefetch" href="https://fonts.googleapis.com/"> 
减少HTTP请求

一个完整的 HTTP 请求需要经历 DNS 查找,TCP 握手,浏览器发出 HTTP 请求,服务器接收请求,服务器处理请求并发回响应,浏览器接收响应等过程。 真正下载数据的时间占比为 13.05 / 204.16 = 6.39%,文件越小,这个比例越小,文件越大,比例就越高。这就是为什么要建议将多个小文件合并为一个大文件,从而减少 HTTP 请求次数的

使用服务端渲染

客户端渲染: 获取 HTML 文件,根据需要下载 JavaScript 文件,运行文件,生成 DOM,再渲染。

服务端渲染:服务端返回 HTML 文件,客户端只需解析 HTML。

  • 优点:首屏渲染快,SEO 好。
  • 缺点:配置麻烦,增加了服务器的计算压力。
图片

雪碧图 和 图片懒加载, 预加载

使用http2.0
  • 采用二进制格式传输数据,而非http1.1文本格式(二进制分帧)。
  • 对消息头采用Hpack进行压缩传输,能够节省消息头占用的网络流量(头部压缩)。
  • 多路复用
  • 服务端推送
gzip 资源加载

浏览器渲染

js 异步加载

js的异步加载有两种方法,deffer和async

  1. deffer属性:这个属性表示脚本在执行的时候不会改变页面的结构,在整个页面解析完成以后再执行,,即如果设置了deffer属性,浏览器会立即下载文件,但是执行应该推迟,会在浏览器解析到最后的标签后才会执行
  2. async属性,这个属性表示告诉浏览器立即下载并开始执行,不必等脚本下载和执行完后在加载页面,同样也不必等到异步脚本下载和执行后在加载其他脚本,所以使用async的时候有两个需要注意的点。
 <script async src="./a.js"></script>
 <script async src="./b.js"></script>

在这个例子中,b.js 有可能先于a.js执行

  1. 保证a.js和b.js之间没有依赖关系
  2. 由于不必等脚本下载和执行完后在加载js文件,所以异步脚本不应该在加载期间修改DOM
节流和防抖
将 CSS 放在文件头部,JavaScript 文件放在底部
  • CSS 执行会阻塞渲染,阻止 JS 执行
  • JS 加载和执行会阻塞 HTML 解析,阻止 CSSOM 构建

如果这些 CSS、JS 标签放在 HEAD 标签里,并且需要加载和解析很久的话,那么页面就空白了。所以 JS 文件要放在底部(不阻止 DOM 解析,但会阻塞渲染),等 HTML 解析完了再加载 JS 文件,尽早向用户呈现页面的内容。

那为什么 CSS 文件还要放在头部呢?

因为先加载 HTML 再加载 CSS,会让用户第一时间看到的页面是没有样式的、“丑陋”的,为了避免这种情况发生,就要将 CSS 文件放在头部了。

另外,JS 文件也不是不可以放在头部,只要给 script 标签加上 defer 属性就可以了,异步下载,延迟执行。

减少重绘重排

浏览器渲染过程

  1. 解析HTML生成DOM树。
  2. 解析CSS生成CSSOM规则树。
  3. 解析JS,操作 DOM 树和 CSSOM 规则树。
  4. 将DOM树与CSSOM规则树合并在一起生成渲染树。
  5. 遍历渲染树开始布局,计算每个节点的位置大小信息。
  6. 浏览器将所有图层的数据发送给GPU,GPU将图层合成并显示在屏幕上。

在这里插入图片描述

重排

当改变 DOM 元素位置或大小时,会导致浏览器重新生成渲染树,这个过程叫重排。

重绘

当重新生成渲染树后,就要将渲染树每个节点绘制到屏幕,这个过程叫重绘。不是所有的动作都会导致重排,例如改变字体颜色,只会导致重绘。记住,重排会导致重绘,重绘不会导致重排 。

重排和重绘这两个操作都是非常昂贵的,因为 JavaScript 引擎线程与 GUI 渲染线程是互斥,它们同时只能一个在工作。

什么操作会导致重排?

  • 添加或删除可见的 DOM 元素
  • 元素位置改变
  • 元素尺寸改变
  • 内容改变
  • 浏览器窗口尺寸改变

如何减少重排重绘?

  • 用 JavaScript 修改样式时,最好不要直接写样式,而是替换 class 来改变样式。
  • 如果要对 DOM 元素执行一系列操作,可以将 DOM 元素脱离文档流,修改完成后,再将它带回文档。推荐使用隐藏元素(display:none)或文档碎片(DocumentFragement),都能很好的实现这个方案。
使用事件委托

事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。所有用到按钮的事件(多数鼠标事件和键盘事件)都适合采用事件委托技术, 使用事件委托可以节省内存。