JavaScript非阻塞加载以及延迟和异步的详细说明
解锁加载
把js放在头上,浏览器怎么执行,是顺序加载还是并行加载?在旧浏览器下,都是按照顺序加载的,保证了加载的js依赖不会出问题。然而,一些新的浏览器已经开始允许并行加载js,这意味着可以同时下载js文件,但是文件是按顺序执行的。
异步下载没问题,但是每一个javascript都是同步执行的,也就是先出现的脚本标签必须先执行,即使是并行下载,也是最后一次下载,除非用deferre的脚本标签标记。执行任何javascript时,都会中断当前html文档的解析,这自然会阻止页面呈现。
Javascript加载不会影响呈现的页面,但会中断html文档解析。javascript执行后,浏览器将决定当前文档是否需要重新呈现或重新排列。因此,即使javascript放在后面,浏览器也会被挂起,但是之前解析过的dom文档不会受到影响,这对于此时的用户来说是可操作的。
下载后会立即执行Javascript,所有的javascript执行都会阻塞浏览器的其他行为,比如阻塞其他javascript的执行,其他http请求的执行,页面的解析和渲染。(在html文档中下载外部js也会阻塞浏览器的行为,但是通过创建脚本元素下载动态js就不会了。可能是动态js不会改变页面效果,所以允许资源并行下载。)
动态脚本的图形下载
UI线程会根据资源的写入顺序加载资源(资源指的是css文件、图片等。)在页面中。加载资源意味着使用http请求来获取资源。对css外部文件、html文件、图片等资源的http请求的处理意味着资源加载的结束,但是外部javascript文件的加载过程是不同的。它分为两步。第一步,像加载css文件和图片一样,是执行一个http请求来下载一个外部js文件。但是,javascript完成http操作后,并不意味着操作完成,UI线程随后会执行。js脚本的下载和执行必须是一个完整的操作,不可分割。动态js的下载不会被阻止,但是执行肯定会被阻止。
为了提高用户体验,浏览器加快UI线程的执行速度是不可避免的问题,但是将js的下载和执行进行拆分是不可行的。如果浏览器改变方式,可以同时下载多个资源。
常用稳定的静态资源统一放置在静态资源服务器上,由统一的域名提供,不同于主体请求的域名。原则是浏览器只限制通过域名的连接数。如果一个页面中有两个不同的域,并行http请求的数量将会翻倍。度,DNS解析贵,所以两个最好。
所有外部js代码分为UI初始化代码和其他代码。用户界面初始化代码是加载页面时执行的代码。通过onload事件让浏览器繁忙指示结束后,触发不用于页面初始化显示的js代码的加载和执行操作,即让与页面加载无关的js脚本在onload方法中执行
无阻塞加载脚本的核心技术是动态创建脚本的dom节点,可以跨域访问。
var script=document . createelement(' script ');script . type=' text/JavaScript ';script . src=' http : file . js ';document . getelementsbytagname(' head ')[0]。appendChild(脚本);动态脚本元素,也就是脚本标签不是用HTML编写的,而是由现有脚本生成的,因为脚本标签也是DOM元素,JavaScript可以通过DOM API操作DOM。只有当新创建的脚本元素添加到html文档中时,才会下载动态脚本,并在下载后立即执行。
非阻塞脚本的优点是不会阻塞UI的执行,也不会影响其他同步js代码的执行。非阻塞脚本改变了脚本的加载顺序,所以我们在使用非阻塞脚本时一定要多注意脚本之间的依赖关系,以保证脚本在整个页面上的正常执行。
使用非阻塞脚本,代码是放在html文档的头部标签还是底部并不重要。
页面加载的总时间并不是衡量页面加载速度的标准,但是页面同步阻塞加载的时间才是衡量页面加载效率的准确标准。非阻塞脚本加载可能会增加整个页面加载时间,但可以减少页面阻塞加载的时间。
脚本的异步执行会导致前后依赖的问题。脚本加载完成后,非ie浏览器会触发脚本元素的onload事件,ie浏览器下有onreadystatechange事件,所以我们可以把回调放入这个事件中进行处理。
每当浏览器解析脚本标签(无论是嵌入的还是链接的)时,浏览器都会优先下载、解析和执行标签中的javaScript代码,并阻止所有后续页面内容的下载和呈现。(也就是说外部js的下载也会阻塞其他线程。目前,少数浏览器支持js的并行下载)
无阻塞加载脚本技术的核心是动态下载js脚本时,不会阻塞UI线程的执行。为什么动态脚本不阻塞ui线程?可能是因为浏览器认为动态资源不会影响页面呈现。
使脚本延迟和异步的两个属性:延迟和异步
Js脚本会改变文档输入流的内容,所以执行js时页面渲染会暂停。内联脚本没有问题,因为脚本和html文档是同时加载的。但是对于外部引入的脚本,脚本的下载(取决于网速)也会阻碍浏览器文档的解析和渲染,甚至会阻碍部分浏览器下载其他资源(目前部分浏览器已经实现了并行下载)。因此,延迟和异步属性似乎可以优化页面的显示。
延迟(delay)是在html4.0中定义的。此属性使浏览器能够延迟脚本的下载,然后在加载和解析文档后,按照它们在文档中出现的顺序下载和解析文档。也就是说,defer属性的脚本类似于将脚本放在正文底部的效果,将在文档的DOMContentLoaded事件之前执行。
将脚本放在正文的底部比向脚本添加defer属性来延迟脚本的加载要好。
异步(Async)是HTML5的一个新属性。该属性的功能是使浏览器能够并行下载脚本,而不会阻塞浏览器的文档解析和呈现。下载完成后,脚本将立即执行,这可能是无序的,具体取决于下载完成时间。)
如果浏览器同时支持上述两个属性,并且脚本标签同时具有这两个属性,那么异步属性将比延迟更有效。
在不支持异步属性的浏览器中,可以动态创建脚本元素并将其插入到文档中,以实现脚本的异步加载和执行:
用这种方法实现了需求。
版权声明:JavaScript非阻塞加载以及延迟和异步的详细说明是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。