如何构建万字长文,全面分享前端性能优化知识体系?

2026-04-02 02:381阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2430个文字,预计阅读时间需要10分钟。

如何构建万字长文,全面分享前端性能优化知识体系?

为什么要做性能优化?性能优化有多重要?网站的性能优化对用户的留存率和转化率有极大影响,对前端开发来说,性能优化能力也是重要的考察点。性能优化的点非常关键。

为什么要做性能优化?性能优化到底有多重要?网站的性能优化对于用户的留存率、转化率有很大的影响,所以对于前端开发来说性能优化能力也是重要的考察点。

性能优化的点非常的多,有的小伙伴觉得记起来非常的麻烦,所以这里主要梳理出一条线来帮助记忆。

可以将性能优化分为两个大的分类:

  • 加载时优化
  • 运行时优化


加载时性能

顾名思义加载时优化主要解决的就是让一个网站加载过程更快,比如压缩文件大小、使用CDN加速等方式可以优化加载性能。检查加载性能的指标一般看:白屏时间和首屏时间:

  • 白屏时间:指的是从输入网址, 到页面开始显示内容的时间。
  • 首屏时间:指从输入网址, 到首屏页面内容渲染完毕的时间。

白屏时间计算

将代码脚本放在​​</head>​​前面就能获取白屏时间:

<script>
new Date().getTime() - performance.timing.navigationStart
</script>

首屏时间计算

在​​window.onload​​事件中执行以下代码,可以获取首屏时间:

new Date().getTime() - performance.timing.navigationStart

运行时性能

运行时性能是指页面运行时的性能表现,而不是页面加载时的性能。可以通过chrome开发者工具中的 Performance 面板来分析页面的运行时性能。关于chrome开发者工具具体如何操作以及如何查看性能,可以看这篇文章性能优化篇——运行时性能分析

接下来就从加载时性能和运行时性能两个方面来讨论网站优化具体应该怎么做。

加载时性能优化

我们知道浏览器如果输入的是一个网址,首先要​​交给DNS域名解析 -> 找到对应的IP地址 -> 然后进行TCP连接 -> 浏览器发送HTTP请求 -> 服务器接收请求 -> 服务器处理请求并返回HTTP报文 -> 以及浏览器接收并解析渲染页面​​。从这一过程中,其实就可以挖出优化点,缩短请求的时间,从而去加快网站的访问速度,提升性能。

这个过程中可以提升性能的优化的点:

  1. DNS解析优化,浏览器访问DNS的时间就可以缩短
  2. 使用HTTP2
  3. 减少HTTP请求数量
  4. 减少bdimg.share.baidu.com" />

    注意:dns-prefetch需慎用,多页面重复DNS预解析会增加重复DNS查询次数。

    2.使用HTTP2

    HTTP2带来了非常大的加载优化,所以在做优化上首先就想到了用HTTP2代替HTTP1。

    HTTP2相对于HTTP1有这些优点:

    解析速度快

    服务器解析 HTTP1.1 的请求时,必须不断地读入字节,直到遇到分隔符 CRLF 为止。而解析 HTTP2 的请求就不用这么麻烦,因为 HTTP2 是基于帧的协议,每个帧都有表示帧长度的字段。

    多路复用

    在 HTTP2 上,多个请求可以共用一个 TCP 连接,这称为多路复用。

    当然HTTP1.1有一个可选的​​Pipelining​​​技术,说的意思是当一个HTTP连接在等待接收响应时可以通过这个连接发送其他请求。听起来很棒,其实这里有一个坑,处理响应是按照顺序的,也就是后发的请求有可能被先发的阻塞住,也正因此很多浏览器默认是不开启​​Pipelining​​的。

    HTTP1 的​​Pipelining​​技术会有阻塞的问题,HTTP/2的多路复用可以粗略的理解为非阻塞版的Pipelining。即可以同时通过一个HTTP连接发送多个请求,谁先响应就先处理谁,这样就充分的压榨了TCP这个全双工管道的性能。加载性能会是HTTP1的几倍,需要加载的资源越多越明显。当然多路复用是建立在加载的资源在同一域名下,不同域名神仙也复用不了。

    首部压缩

    HTTP2 提供了首部压缩功能。(这部分了解一下就行)

    HTTP 1.1请求的大小变得越来越大,有时甚至会大于TCP窗口的初始大小,因为它们需要等待带着ACK的响应回来以后才能继续被发送。HTTP/2对消息头采用HPACK(专为mp.weixin.qq.com/s/HVkV7F1U77GvXbEI9MWA6g

    5. 使用 Web Workers

    前面提到了大量数据的渲染环节我们可以采用虚拟列表的方式实现,但是大量数据的计算环节依然会产生浏览器假死或者卡顿的情况.

    通常情况下我们CPU密集型的任务都是交给后端计算的,但是有些时候我们需要处理一些离线场景或者解放后端压力,这个时候此方法就不奏效了.

    还有一种方法是计算切片,使用 setTimeout 拆分密集型任务,但是有些计算无法利用此方法拆解,同时还可能产生副作用,这个方法需要视具体场景而动.

    最后一种方法也是目前比较奏效的方法就是利用Web Worker 进行多线程编程.

    Web Worker 是一个独立的线程(独立的执行环境),这就意味着它可以完全和 UI 线程(主线程)并行的执行 js 代码,从而不会阻塞 UI,它和主线程是通过 onmessage 和 postMessage 接口进行通信的。

    Web Worker 使得网页中进行多线程编程成为可能。当主线程在处理界面事件时,worker 可以在后台运行,帮你处理大量的数据计算,当计算完成,将计算结果返回给主线程,由主线程更新 DOM 元素。

    6. 写代码时的优化点

    提升性能,有时候在我们写代码时注意一些细节也是有效果的。

    6.1 使用事件委托

    看一下下面这段代码:

    <ul>
    <li>字节跳动</li>
    <li>阿里</li>
    <li>腾讯</li>
    <li>京东</li>
    </ul>

    // good
    document.querySelector('ul').onclick = (event) => {
    const target = event.target
    if (target.nodeName === 'LI') {
    console.log(target.innerHTML)
    }
    }

    // bad
    document.querySelectorAll('li').forEach((e) => {
    e.onclick = function() {
    console.log(this.innerHTML)
    }
    })

    绑定的事件越多, 浏览器内存占有就越多,从而影响性能,利用事件代理的方式就可节省一些内存。

    6.2 if-else 对比 switch

    当判定条件越来越多时, 越倾向于使用switch,而不是if-else:

    if (state ==0) {
    console.log("待开通")
    } else if (state == 1) {
    console.log("学习中")
    } else if (state == 2) {
    console.log("休学中")
    } else if (state == 3) {
    console.log("已过期")
    } esle if (state ==4){
    console.log("未购买")
    }

    switch (state) {
    case 0:

    break
    case 1:

    break
    case 2:

    break
    case 3:

    break
    case 4:

    break
    }

    向上面这种情况使用​​switch​​​更好, 假设​​state​​​为4,那么​​if-else​​​语句就要进行4次判定,​​switch​​只要进行一次即可。

    但是有的情况下​​switch​​​也做不到​​if-else​​​的事情, 例如有多个判断条件的情况下,无法使用​​switch​

    6.3 布局上使用flexbox

    在早期的 CSS 布局方式中我们能对元素实行绝对定位、相对定位或浮动定位。而现在,我们有了新的布局方式 flexbox,它比起早期的布局方式来说有个优势,那就是性能比较好。

    关于前端性能优化就写到这里了,相信还有很多在代码细节上注意就能进行性能优化的点。

    如何构建万字长文,全面分享前端性能优化知识体系?

    参考文章:


    ​​learnku.com/docs/f2e-performance-rules/reduce-the-number-of-http-requests/6369​​


本文共计2430个文字,预计阅读时间需要10分钟。

如何构建万字长文,全面分享前端性能优化知识体系?

为什么要做性能优化?性能优化有多重要?网站的性能优化对用户的留存率和转化率有极大影响,对前端开发来说,性能优化能力也是重要的考察点。性能优化的点非常关键。

为什么要做性能优化?性能优化到底有多重要?网站的性能优化对于用户的留存率、转化率有很大的影响,所以对于前端开发来说性能优化能力也是重要的考察点。

性能优化的点非常的多,有的小伙伴觉得记起来非常的麻烦,所以这里主要梳理出一条线来帮助记忆。

可以将性能优化分为两个大的分类:

  • 加载时优化
  • 运行时优化


加载时性能

顾名思义加载时优化主要解决的就是让一个网站加载过程更快,比如压缩文件大小、使用CDN加速等方式可以优化加载性能。检查加载性能的指标一般看:白屏时间和首屏时间:

  • 白屏时间:指的是从输入网址, 到页面开始显示内容的时间。
  • 首屏时间:指从输入网址, 到首屏页面内容渲染完毕的时间。

白屏时间计算

将代码脚本放在​​</head>​​前面就能获取白屏时间:

<script>
new Date().getTime() - performance.timing.navigationStart
</script>

首屏时间计算

在​​window.onload​​事件中执行以下代码,可以获取首屏时间:

new Date().getTime() - performance.timing.navigationStart

运行时性能

运行时性能是指页面运行时的性能表现,而不是页面加载时的性能。可以通过chrome开发者工具中的 Performance 面板来分析页面的运行时性能。关于chrome开发者工具具体如何操作以及如何查看性能,可以看这篇文章性能优化篇——运行时性能分析

接下来就从加载时性能和运行时性能两个方面来讨论网站优化具体应该怎么做。

加载时性能优化

我们知道浏览器如果输入的是一个网址,首先要​​交给DNS域名解析 -> 找到对应的IP地址 -> 然后进行TCP连接 -> 浏览器发送HTTP请求 -> 服务器接收请求 -> 服务器处理请求并返回HTTP报文 -> 以及浏览器接收并解析渲染页面​​。从这一过程中,其实就可以挖出优化点,缩短请求的时间,从而去加快网站的访问速度,提升性能。

这个过程中可以提升性能的优化的点:

  1. DNS解析优化,浏览器访问DNS的时间就可以缩短
  2. 使用HTTP2
  3. 减少HTTP请求数量
  4. 减少bdimg.share.baidu.com" />

    注意:dns-prefetch需慎用,多页面重复DNS预解析会增加重复DNS查询次数。

    2.使用HTTP2

    HTTP2带来了非常大的加载优化,所以在做优化上首先就想到了用HTTP2代替HTTP1。

    HTTP2相对于HTTP1有这些优点:

    解析速度快

    服务器解析 HTTP1.1 的请求时,必须不断地读入字节,直到遇到分隔符 CRLF 为止。而解析 HTTP2 的请求就不用这么麻烦,因为 HTTP2 是基于帧的协议,每个帧都有表示帧长度的字段。

    多路复用

    在 HTTP2 上,多个请求可以共用一个 TCP 连接,这称为多路复用。

    当然HTTP1.1有一个可选的​​Pipelining​​​技术,说的意思是当一个HTTP连接在等待接收响应时可以通过这个连接发送其他请求。听起来很棒,其实这里有一个坑,处理响应是按照顺序的,也就是后发的请求有可能被先发的阻塞住,也正因此很多浏览器默认是不开启​​Pipelining​​的。

    HTTP1 的​​Pipelining​​技术会有阻塞的问题,HTTP/2的多路复用可以粗略的理解为非阻塞版的Pipelining。即可以同时通过一个HTTP连接发送多个请求,谁先响应就先处理谁,这样就充分的压榨了TCP这个全双工管道的性能。加载性能会是HTTP1的几倍,需要加载的资源越多越明显。当然多路复用是建立在加载的资源在同一域名下,不同域名神仙也复用不了。

    首部压缩

    HTTP2 提供了首部压缩功能。(这部分了解一下就行)

    HTTP 1.1请求的大小变得越来越大,有时甚至会大于TCP窗口的初始大小,因为它们需要等待带着ACK的响应回来以后才能继续被发送。HTTP/2对消息头采用HPACK(专为mp.weixin.qq.com/s/HVkV7F1U77GvXbEI9MWA6g

    5. 使用 Web Workers

    前面提到了大量数据的渲染环节我们可以采用虚拟列表的方式实现,但是大量数据的计算环节依然会产生浏览器假死或者卡顿的情况.

    通常情况下我们CPU密集型的任务都是交给后端计算的,但是有些时候我们需要处理一些离线场景或者解放后端压力,这个时候此方法就不奏效了.

    还有一种方法是计算切片,使用 setTimeout 拆分密集型任务,但是有些计算无法利用此方法拆解,同时还可能产生副作用,这个方法需要视具体场景而动.

    最后一种方法也是目前比较奏效的方法就是利用Web Worker 进行多线程编程.

    Web Worker 是一个独立的线程(独立的执行环境),这就意味着它可以完全和 UI 线程(主线程)并行的执行 js 代码,从而不会阻塞 UI,它和主线程是通过 onmessage 和 postMessage 接口进行通信的。

    Web Worker 使得网页中进行多线程编程成为可能。当主线程在处理界面事件时,worker 可以在后台运行,帮你处理大量的数据计算,当计算完成,将计算结果返回给主线程,由主线程更新 DOM 元素。

    6. 写代码时的优化点

    提升性能,有时候在我们写代码时注意一些细节也是有效果的。

    6.1 使用事件委托

    看一下下面这段代码:

    <ul>
    <li>字节跳动</li>
    <li>阿里</li>
    <li>腾讯</li>
    <li>京东</li>
    </ul>

    // good
    document.querySelector('ul').onclick = (event) => {
    const target = event.target
    if (target.nodeName === 'LI') {
    console.log(target.innerHTML)
    }
    }

    // bad
    document.querySelectorAll('li').forEach((e) => {
    e.onclick = function() {
    console.log(this.innerHTML)
    }
    })

    绑定的事件越多, 浏览器内存占有就越多,从而影响性能,利用事件代理的方式就可节省一些内存。

    6.2 if-else 对比 switch

    当判定条件越来越多时, 越倾向于使用switch,而不是if-else:

    if (state ==0) {
    console.log("待开通")
    } else if (state == 1) {
    console.log("学习中")
    } else if (state == 2) {
    console.log("休学中")
    } else if (state == 3) {
    console.log("已过期")
    } esle if (state ==4){
    console.log("未购买")
    }

    switch (state) {
    case 0:

    break
    case 1:

    break
    case 2:

    break
    case 3:

    break
    case 4:

    break
    }

    向上面这种情况使用​​switch​​​更好, 假设​​state​​​为4,那么​​if-else​​​语句就要进行4次判定,​​switch​​只要进行一次即可。

    但是有的情况下​​switch​​​也做不到​​if-else​​​的事情, 例如有多个判断条件的情况下,无法使用​​switch​

    6.3 布局上使用flexbox

    在早期的 CSS 布局方式中我们能对元素实行绝对定位、相对定位或浮动定位。而现在,我们有了新的布局方式 flexbox,它比起早期的布局方式来说有个优势,那就是性能比较好。

    关于前端性能优化就写到这里了,相信还有很多在代码细节上注意就能进行性能优化的点。

    如何构建万字长文,全面分享前端性能优化知识体系?

    参考文章:


    ​​learnku.com/docs/f2e-performance-rules/reduce-the-number-of-http-requests/6369​​