提高 JavaScript 性能【从URL解析到DOM点操作】

前公司创业公司创业还没成功,新制度倒是层出不穷,纷纷扰扰。心里不快,干脆裸辞跑回广州。面试了两天就确定了新公司,从小程序又转战Vue。

许久没碰Vue,手生得很啊!很感谢新公司CTO杰哥给我机会让我快速了解公司业务,上手项目。虽然刚进公司不到一个月,但是得到机会见识了架构好的代码,一个月内多次刷新对前端的认知。难得本月业务写完大半,遂抽空开始学JavaScript性能相关,于是有此文。

本文是我学习Web性能所整理的文章。主要读物:《高性能JavaScript》、《你不知道的JS》、MDN网站以及网络上一些解读文章。

页面加载与运行过程

1、DNS解析:将URL解析为IP地址

2、TCP连接:三次握手与四次分手

3、各种HTTP请求:接口请求、JavaScript加载等

4、服务端的响应:服务端响应请求并返回数据

5、浏览器解析:浏览器对数据进行解析

6、页面渲染:解析的数据通过DOM树、CSS树与JavaScript生命周期渲染过程生成最终的页面

7、定时任务与后置JavaScript加载:JavaScript会在特定生命周期/业务期间被调用,影响页面

通过上面的过程我们了解了 从发送URL请求到页面渲染完成/事件触发 期间发生的事情,而 1-4 是涉及服务端和客户端双方合作部分,我们先关注 5-7 ,也就是我们前端工程师能独立优化性能的部分

首先,我们在加载页面到渲染页面之前,页面呈现出来的是一片空白。我们要做的第一件事,就是尽可能压缩这段空白页面出现的时间。而我们知道浏览器读取页面代码是自顶向下按顺序执行的。那么我们就得先搞清楚一件事。

浏览器在什么时候开始渲染页面?

浏览器是在读取 body 节点后才开始渲染页面。也就是说,执行 head 标签内语句的整个过程,页面都是一片空白,所以我们尽可能的将 JavaScript 与 CSS 渲染代码放在 body 底部。

那么我们是不是要将全部的 JavaScript 与 CSS 代码置于 body 呢?

不是的,我们需要将页面渲染所相关的 JavaScript 与 CSS 代码放在 head 标签内,而耗时操作与业务代码、定时任务等都放在 body 底部加载即可。另一方面,随着项目不断扩充业务场景,载入的 JavaScript 与 CSS 越来越多,我们就需要考虑多两个问题。

JavaScript 如何按期待的顺序载入与执行?JavaScript 拆分载入好还是合并载入好?

第一个问题有许多种解法,包括定时器、异步回调等,我个人觉得最好的方式是使用 Promise 进行链式调用,清晰明了。但是这样链式调用了就会产生一个新的问题,我们为什么不将代码合并成同一段 JavaScript 代码载入,而是要分成多链式载入呢?我们都知道,每次载入 JavaScript 和载入完成后的编译都是一项耗时操作,我们如果将多段 JavaScript 合并成一段后载入,不就可以更快地获取想要的页面效果吗?

答案是肯定的。多段 JavaScript 合并后,载入速度将大大提高。因为我们将略去绝大部分 JavaScript 执行时间,那为什么基本没有团队这么做呢?答案很简单,因为在 JavaScript 加载过程中,页面是处于“卡顿”状态,这将非常严重影响用户体验。那我们又希望提高性能,又无法整合 JavaScript,这可咋整啊?

耗时代码拆分单独运行,同业务代码片段尽量整合,涉及 DOM 操作的代码预加载

耗时操作的代码,例如发送请求、Canvas 绘图等,只能单独加载,有时候甚至还得做多一步操作,例如加个 Loading、进度条等;同业务代码,例如获取接口数据后进行的后续操作,(修改DOM节点等)尽量合并,此时代码加载将无法分隔开来,如果中途停止 JavaScript 加载,而是让用户进行操作,用户会觉得他之前进行的操作毫无反馈,从而影响了用户体验;涉及 DOM 操作的代码,例如放大图片功能,popup 层展示功能等,如果等到需要的时候才加载 JavaScript 代码将造成明显卡顿,我们可以通过代码预加载来避免这种状况。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章