《高性能javascript》学习笔记一

补充:因《高性能javascript》一书成书较早,书中介绍的许多知识已过期或者有新的标准,我尽量结合自己的理解以及书中的观点进行总结和阐述。如有错误之处还请指出。

一、脚本的加载和执行

1、为什么脚本会阻塞页面

大多数浏览器是单线程(js线程和ui线程共享同一个线程),所以,在执行js代码时,ui层无法做出响应。所以,在下载或者执行js过程中,页面渲染和交互是阻塞的。

2、防止页面阻塞的方法

(1)将script标签置于页面底部。因为js引擎是从上往下解析,先读取css和html,页面出来之后,再读取js文件并执行,就不会造成页面的阻塞。(其实也会,不过下载./执行js代码时用户能看到页面,只要js下载执行不需要很久,用户察觉不到。)

(2)合并js文件。同样大小的js,合并成一个会比分成多个更节约性能。因为每次请求都会额外消耗性能,如果只有一次请求,无疑是最好的。

(3)async和defer属性。给script标签添加async或者defer属性,浏览器将会异步加载这个script标签的资源(即当前浏览器线程闲置时下载执行)。如果有多个script标签有async属性,则先下载完的先执行。多个defer属性的script标签,则按照页面上的顺序从上往下执行。

两者区别:async属性是下载完对应js文件立即执行。defer属性是下载完之后,等到页面的load事件之前执行该js文件。

(4)动态引入js文件。可以在js代码中创建script标签,设置src属性放在页面上。动态script标签在放在页面上时会立刻异步执行,下载完js文件后会自动执行。(异步执行的原因,其实是因为在将script标签放入页面上时,对应的请求任务才会加入到事件队列,所以要等到之前的事件处理完才会下载并执行这个js文件。)

结果是:

在执行完setTimeout之后,然后会立即将console.log(2222)这个事件放入事件队列。。然后下载外部的9-25.js文件,然后输出2222,然后输出外部文件的1111.

如果延迟回调的时间设置为100(比下载9-25.js时间小就行),那么结果是

                                                                                                                       

setTimeout的时间,是将对应的时间放入事件队列的时间,而不是具体执行的时间。所以在下载9-25.js文件完成后,如果时间还没到,那么会先执行外部的js文件(因为这时会把外部的js文件执行放入事件队列),然后执行回调函数的代码。

推荐方式:动态注入或者async

猜你喜欢

转载自blog.csdn.net/weixin_42733155/article/details/82846653