前端之网站性能篇

| 前端 | 性能 | 1.9k | 3 分钟
  • 性能从用户方面考虑,需要让页面加载得更快、让用户先看到有效的内容、让用户的操作响应变得更及时。
  • 性能从服务器方面考虑,需要合理控制请求的占用带宽、请求的响应速度。

只描述方向,不展示具体实现

CDN加速

CDN全称Content Delivery Network,是一种内容分发网络。通过其的导向策略能够为用户分配就近的、可访问性高的服务器,增加资源的访问效率,并且CND还会通过一些策略缓存资源文件,减少了源服务器的访问压力。CND加速适用一些内容修改频率低的静态资源文件。

代码压缩

代码压缩能够极大的减小请求消耗的带宽、更快的完成资源的加载。可以对js和css等代码文件先进行代码混淆压缩,再对压缩后的文件进行gzip压缩。图片的压缩极其重要,可以根据不同的设备加载不同分辨率的图片,同时再对图片进行无损或者有损压缩,图片压缩能够明显降低带宽的损耗。

请求

避免使用内联样式和js

外链css和js可以降低页面多次访问时的带宽消耗。

合理控制请求的域名

浏览器通常都会有同域名下的最大并行资源加载数量限制,比如谷歌浏览器是6条,因此需要合理将一些请求分散到不同域名以提高浏览器的实际并行资源请求数量。增加资源域名的同时可能会增加相关的DNS寻址的时间,所以需要合理考虑两者的权衡。

最小化请求数

降低请求的数量能够减少io的占用,和避免传送一些重复的head信息等。常见的方案有合并资源文件、图标类图片使用雪碧图等(或者使用字体图标)。

请求缓存

从业务方面可以缓存一些更改频率低的、或者不严格要求时效性的数据进行浏览器本地缓存,比如国家省市区等。从页面的请求加载方面考虑可以设置页面的缓存策略(Expires、Cache-Control)、开启长连接、采用http2协议等。

内容布局

保持页面中重要的内容先渲染,资源上先加载页面初始化时必须的,其他不重要的内容延迟渲染,内容上考虑什么是用户最关注的内容。同时DOM结构需要语义化和DOM数量需要最小化,减小页面的复杂对和渲染时的消耗,比如图片的懒加载,弹窗或者选项卡内容在显示时再创建等。

js加载顺序

js内容被加载完毕后会立即执行,在执行js时会阻塞页面的渲染。因此需要合理控制资源的加载顺序和时机,比如将js文件的引入放在Html的尾部,分离js中的页面相关和逻辑相关,渲染无关的js文件等延迟加载。

运行时性能

使用CSS动画而不是js操作动画

js操作动画会占用主线程的执行,同时可能会引起页面的回流,也无法利用到硬件加速。

在一次逻辑中缓存能够引起强制渲染的dom属性

读取dom的如offsetTop属性会强制使浏览器清空待渲染队列,引起强制渲染,所以对这些属性的读取需要用变量缓存。

避免频繁操作DOM,压缩操作的次数

频繁的操作dom会引起大量的回流,尽量压缩dom的操作次数。比如利用DocumentFragment来聚合需要插入的dom进行一次最终插入

事件委托

利用dom的事件冒泡机制,可以将绑定在诸多子节点上面的事件绑定在父节点上,减少了大量的事件绑定。

避免全局查找

全局变量在作用域链的顶端,读取全局变量需要走遍整个作用域链,因此有时需要局部缓存全局变量,避免每次都进行全局查找

最小化循环的次数

从业务、数据结构、算法方面优化涉及到循环时的性能。

尽量使用原生方法

js引擎对原生的方法都进行过优化,通常都会有用更高的调用性能。

创建数组和对象时使用字面量

字面量创建比new创建更加的高效、简洁。

尽量避免使用闭包

闭包容易造成内存泄漏,作用域链混乱。

性能优先不要追求代码量最少

在代码行数和性能决策时请选择性能优先,比如采用for循环而不用forin。

位运算


// 快速向下取整
const num = 5.3 | 0

// 快速四舍五入
const num = 5.3 + .5 | 0

// 快速向上取整
const num = 5.3 + 1 | 0


// 非数字转数字,官方推荐+
const num = + '5.3'
const num = + {}
const num = + new Date()

// ~-1 等于 0,也就是假,~其他的值都会是真值
const index = 'Hello World'.indexOf('emmm')
if (~index) {
    console.info('存在emmmmm')
}

// 交换
let a = 1
let b = 2
a ^= b // a = a ^ b,这里是顺便测试了一下有没有 ^=
b = a ^ b
a ^= b
// 还有一种交换方案是使用数组结构 [a, b] = [b, a]

// << 有符号左移
// >> 有符号右移
// >>> 无符号右移