浏览器系列 -- 优化 Web 网页加载

377 阅读3分钟

启动加载性能层面

一、缓存

1. 利用浏览器缓存

具体方案见 浏览器系列 -- 浏览器缓存

2. 使用 CDN 缓存

具体方案见 浏览器系列 -- CDN 缓存

二、使用预解析 DNS

具体方案见 浏览器系列 -- DNS 解析及预解析

三、解决阻塞渲染问题(2+2)

阻塞渲染问题参考 浏览器系列 -- 阻塞渲染

  • CSS 阻塞问题
  • JS 阻塞问题

四、减少重绘回流(2+4+1)

2 + 4 + 1 详见 重绘和回流

CSS方面

  1. 避免设置多层内联样式,将样式【合并】在一个外部类
  2. 将需要多次回流的元素position属性设为absolute或fixed(比如动画效果)

JS方面

  1. 避免多次读取 DOM 节点【可以用变量将结果存起来】
  2. 需要多次操作同一 DOM 节点时可以先将该节点的元素设置display:none,操作完再显示。(因为隐藏元素不在render树内,因此修改隐藏元素不会触发回流重绘)
  3. 操作多个 DOM 节点时将所有的 DOM 操作集中在一起
  4. 形变和位移用【transfrom】代替 DOM 节点操作

图片方面

所有图片必须指定高宽属性

否则只有当图片完全下载才能确定图片的高宽,势必造成浏览器的重新渲染

五、资源预加载技术

资源预加载是一个性能优化技术,我们可以使用该技术来预先告知浏览器某些资源可能在将来会被使用到

DNS 预解析 rel="dns-prefetch"

例如,我们将来可能加载名为 image.png 这种图片,那么可以在文档顶部的 <head>标签中加入以下内容: <link rel="dns-prefetch" href="image.png"> 通过简单的一行代码就可以告知那些兼容的浏览器进行 DNS 预解析,这意味着当浏览器真正请求该域中的某个资源时,DNS 的解析就已经完成了

预获取 rel="prefetch"

与 DNS 预解析不同,预获取真正请求并下载了资源,并储存在缓存

在文档顶部的 <head>标签中加入以下内容:<link rel="prefetch" href="image.png">

预渲染 rel="prerender"

对一个用户将来一定会打开的 tab 页:将【下载所有资源、创建 DOM 结构、完成页面布局、应用 CSS 样式和执行 JavaScript 脚本】等。当用户真正访问该链接时,隐藏的页面就切换为可见,使页面看起来就是瞬间加载完成一样

前提是:用户在将来一定会打开该tab页,否则会造成不必要的资源浪费

六、优化网页图片加载

具体方案见 浏览器系列 -- 优化网页图片加载

七、如果有用到 Canvas

Canvas具体内容及优化方案见 HTML系列 -- Canvas

  1. 可以创建【多个重叠的Canvas】绘制不同的层,而不是【在同一个Canvas】中绘制非常复杂的图
<canvas id="canvas-1"></canvas>
<canvas id="canvas-2"></canvas>
  1. 创建一个【不可见的Canvas】来绘图,然后将最终绘制【结果复制】到页面的可见Canvas中
var imgData = ctx.getImageData(0, 0, 60, 60);
ctx.putImageData(imgData, 60, 60);
  1. 背景图片如果不变的话可以直接用 <img> 标签并放到最底层
  2. 尽量使用整数坐标而不是浮点数 【整数坐标计算更加简便】

重渲染性能

一、多次切换显示、隐藏元素

使用 visibility:hidden 代替 display:none去实现重复切换显示隐藏元素功能,因为这样会减少对 DOM 节点的操作

二、多次读取和操作 DOM 节点

  1. 避免多次读取 DOM 节点【可以用变量将结果存起来】
  2. 需要多次操作同一 DOM 节点时可以先将该节点的元素设置 display:none,操作完再显示。(因为隐藏元素不在 render 树内,因此修改隐藏元素不会触发回流重绘)
  3. 操作多个 DOM 节点时将所有的 DOM 操作集中在一起