当前位置: 首页 > 科技观察

我对JS延迟异步脚本的思考

时间:2023-03-21 14:28:57 科技观察

关于延迟脚本的思考相信大家都听说过带有async和defer属性的脚本,但是它们真正的执行细节是怎样的呢?很少有文章认真研究它,可能有些人不注意细节,但实际上真正的技术工作和项目对性能要求极高,所以细节非常重要。它需要最近几个月不断的试验和自我尝试。一直在研究一些技术,比如linux、操作系统、算法等,希望能一直学到今年年底。小红书第四版出来后,我也花了很多时间看。对于延时脚本,我也做了实验,写了这篇总结。什么是延迟脚本?通过document.createElement('script')创建且不指定script.async=false的script标签,带有async和defer等属性,默认为异步defer脚本(必须是非内联脚本),如下:<!DOCTYPEhtml>文档以上7个脚本文件,其中common开头的是非异步延时脚本,其余指定延迟脚本的模式。它分为两种类型:async和defer。document.createElement创建的标签插入默认以异步方式启动实验。我一共写了2个async和2个defer标签,其余都是普通标签。async1.js有4000行代码,其他的只是一个console.log。第一个实验结果:再次刷新页面(注意我禁用了浏览服务器缓存),结果是:再次刷新发现async执行的时机和顺序不定。原因是:async告诉浏览器你不用等它下载解析完再加载页面,不用等它执行完再执行其他脚本,俗称异步执行脚本,看下载执行时序和打印结果对比。打印结果:对应的下载执行时序由上可知,下载时序async和normal模式一样是并行下载,只是最后下载defer(http1.1有并发量限制,但这里不是并发限制。当我删除了commonreference,发现defer总是最后下载)async和defer两种模式,区别是:async告诉浏览器不会操作dom,不用等到下载解析完在加载页面之前,您不必等待它执行后再执行其他脚本。它通常被称为异步执行脚本。多个异步不能保证它们的执行顺序。比如async1和async2不能按顺序执行defer。解析到标签结束后才会执行,俗称延迟脚本执行,多个defer可以按顺序执行,比如defer1和defer2可以按顺序执行(其实顺序不一样)guaranteed)解析到script标签后,async直接下载解析到script标签,defer和上次下载是一样的:多个async或defer标签其实不能保证顺序执行不会阻塞解析和页面呈现其他脚本标签的内容。它们都会在浏览器加载Execute事件之前执行,但不保证是在DomContentLoad事件之前还是之后执行。defer不一定在async之后执行。从我的实验结果和书中对它们的分析可以看出,多个异步脚本的执行顺序受脚本文件大小网络传输因素的特殊情况,当所有脚本文件都很小时,结果将是大概率使用稳定。异步延迟脚本的执行顺序是不稳定的,所以在使用异步延迟脚本的时候尽量只有一个,应该考虑在什么场景下使用,而不是滥用