面试高频之js的异步加载

讲这个问题之前, 我们从另一个面试高频问题来切入,

我们的web页面从开始解析到页面渲染完成都经历了什么 ? 

1  ,  创建document对象, 开始解析页面,    此时document.readyState = 'loading'

2 ,     遇到link标签引入的css文件, 创建线程并异步加载css,继续解析文档

3,    遇到script标签引入的外部脚本 ,  如果script标签的属性设置了defer或者async  则  创建线程异步加载js , 否则同步加载js(阻塞了dom的解析)  , 继续解析文档 (async脚本加载完就执行)

4 ,   遇到img等要加载资源的标签, 正常解析dom 标签  ,  异步加载src ,    继续解析文档

5 ,    文档解析完毕 ,  document.readyState = 'interactive' , 所有defer脚本按顺序执行,并且document会触发 DOMContentLoaded事件 , 标志着程序从同步脚本执行阶段转化成事件驱动阶段

6 , 当所有async 脚本 加载并执行 完毕 , img 加载完毕  ,  document.readyState = 'complete' ,  window 触发  load  事件  。

7      从此   以异步响应的方式处理用户输入, 网络事件等 。。。。。。

ok , 光说没用, 我们来看看真相是否只有一个。。。

document.onreadystatechange = () => {
console.log(document.readyState)
};
document.addEventListener('DOMContentLoaded', () => {
console.log('DOMContentLoaded')
});
window.onload = () => {
console.log('load')
};

注意一点, DOMContentLoaded 事件 只能用  addEventListener 来绑定

结果是这样:

按顺序打印出来了 。。。

上文我们提到只有设置了defer /async 的 script 脚本 才能异步加载  ,

注意defer 有些低版本浏览器不兼容,

async是W3C的标准,但只能在引入外部js文件时使用,

当然,我们最常用的是把script标签放在body 后面 ,这样就不会阻塞dom解析

还有一种情况, 动态添加的script脚本也是异步加载的, 基于此 我们来封装一个 异步加载script脚本的函数

function loadScript (url, callback) {  // 传入url , 和要执行的回调函数
const script = document.createElement('script');
script.type = 'text/javascript'; // 创建一个script标签
if (script.readyState) { // 做兼容
script.onreadystatechange = () => { // readyState变化触发
if (script.readyState === 'complete' || script.readyState === 'loaded') { // 兼容
callback(); // 加载完执行回调
}
}
} else {
script.onload = () => {
callback(); // 加载完执行回调
}
}
script.src = url;
document.head.appendChild(script); // 插入head中
}

以上就是 js 异步加载 的 全部内容了, 欢迎小伙伴们补充

    

js的异步加载你真的懂吗的更多相关文章

  1. Vue中结合Flask与Node.JS的异步加载功能实现文章的分页效果

    你好!欢迎阅读我的博文,你可以跳转到我的个人博客网站,会有更好的排版效果和功能. 此外,本篇博文为本人Pushy原创,如需转载请注明出处:http://blog.pushy.site/posts/15 ...

  2. js滚动异步加载数据的思路

    <body> <div style="width:200px; height:1000px; border:1px solid red;" id="to ...

  3. JS异步加载的三种方案

    js加载的缺点:加载工具方法没必要阻塞文档,个别js加载会影响页面效率,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作. 有些工具方法需要按需加载,用到再加载,不用不加载. 一.def ...

  4. 异步加载的JS如何在chrome浏览器断点调试?

    我们常常利用chrome强大的控制台Sources下面进行代码断点调试,但是通过$.getScript等异步加载JS的方式在Sources里面就是找不到,那如何进行debug断点调试呢? 方案一: 在 ...

  5. 不得不说的JavaScript异步加载

    同步加载的问题 默认的js是同步加载的,这里的“加载”可以理解成是解析.执行,而不是“下载”,在最新版本的浏览器中,浏览器对于代码请求的资源都是瀑布式的加载,而不是阻塞式的,但是js的执行总是阻塞的. ...

  6. javascript 同步加载与异步加载

    HTML 4.01 的script属性 charset: 可选.指定src引入代码的字符集,大多数浏览器忽略该值. defer: boolean, 可选.延迟脚本执行,相当于将script标签放入页面 ...

  7. Highcharts 异步加载数据曲线图表

    导入 data.js 文件 异步加载数据需要引入以下js 文件: <script src="http://code.highcharts.com/modules/data.js&quo ...

  8. Javascript 文件的同步加载与异步加载

    HTML 4.01 的script属性 charset: 可选.指定src引入代码的字符集,大多数浏览器忽略该值.defer: boolean, 可选.延迟脚本执行,相当于将script标签放入页面b ...

  9. Highcharts 基本曲线图;Highcharts 带有数据标签曲线图表;Highcharts 异步加载数据曲线图表

    Highcharts 基本曲线图 实例 文件名:highcharts_line_basic.htm <html> <head> <meta charset="U ...

随机推荐

  1. javamail接收邮件(zt)

    zt from:http://xiangzhengyan.iteye.com/blog/85961 import <a href="http://lib.csdn.net/base/j ...

  2. 终端字形logo

    网上有很多的项目都有一个自己的字形logo,而我也在开发一个小的项目,也想要生成一个终端字形的logo,于是找到这款小工具,分享给大家:FIGlet “FIGlet is a program for ...

  3. es6(一):es6介绍以及let,const

    es是js的规范,而js是具体实现 将es6转化为es5代码工具:运用的多的是babel 在线转换地址:babel,traceur(属于谷歌)   1.let申明变量:let其实可以完全取代var,并 ...

  4. C#更改操作系统时间

    using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServi ...

  5. PCA算法和python实现

    第十三章 利用PCA来简化数据 一.降维技术 当数据的特征很多的时候,我们把一个特征看做是一维的话,我们数据就有很高的维度.高维数据会带来计算困难等一系列的问题,因此我们需要进行降维.降维的好处有很多 ...

  6. ccf 目录格式转换

    任务背景: 在网络上获取的ccf目录的格式是PDF,但是要进行数据分析时,PDF格式的数据是不符合要求的,因此需要将pdf格式转化为excel格式 任务目的: 将pdf格式的CCF目录转化为excel ...

  7. Spring的断言工具类Assert的基本使用

    org.springframework.util.Assert; Assert工具类,通常用于数据合法性检查. 平时做判断通常都是这样写: if(message == null || message. ...

  8. linux基础-系统安装教程篇(centos6.5)

    一.linux系统简介: Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件.应用程 ...

  9. Unity3D学习(四):小游戏Konster的整体代码重构

    前言 翻了下之前写的代码,画了个图看了下代码结构,感觉太烂了,有很多地方的代码重复啰嗦,耦合也紧,开个随笔记录下重构的过程. 过程 _____2017.10.13_____ 结构图: 目前发现的待改进 ...

  10. hibernate多表查询封装实体

    以前用sql实现联合查询 是非常简单的事,只需要写sql语句就可以,第一次遇到hibernate要实现多表联合查询的时候还楞了一下.最后看了下资料,才恍然大悟,hibernate实现多表联合查询跟SQ ...