浏览器加载 js 的原理
- 浏览器一边下载 HTML 网页,一边解析
- 在解析的过程中,如果遇到
<script>
标签,就暂停解析,把网页渲染的控制权交给 JavaScript 引擎 - 如果
<script>
元素引用了外部脚本,就先下载该脚本 - JavaScript 引擎执行完毕,控制权交换给渲染引擎,恢复解析 HTML 网页
可以看出,当需要加载 js 文件时,是会阻塞渲染的
为了解决这个问题,有以下几种方法
(一)将 <script>
标签放到 <body>
底部
把 <script>
标签放到 <body>
底部,既不会阻止浏览器解析 HTML,还可以在脚本中操作 DOM
(二)defer
属性
当浏览器遇到带有 defer
属性的 <script>
标签时,会再开一个线程去下载 js 文件,同时,继续解析 HTML 文档,等到 HTML 全部解析完成,再去执行加载好的 js 文件
当加载多个 js 文件时,执行顺序就是他们在页面中出现的顺序
(三)async
属性
当 <script>
标签应用 async
属性,也是会再开一个线程去加载 js 文件
但是和 defer
不同的是,它会在下载完成之后立即执行,而不是等到 HTML 全部解析完成再执行,所以,有可能还是会造成堵塞
当加载多个 js 文件时,他不像 defer
那样按顺序执行,哪个文件先下载完就先执行哪个
(四)动态创建 <script>
标签
没有定义 defer
和 async
之前,异步加载的方式是,动态创建 script
,通过 window.onload
方法确保页面加载完毕再将 script
标签插入到 DOM 中
function addScriptTag(src) {
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function() {
addScriptTag("js/index.js");
}
网友评论