`
wangemperor
  • 浏览: 39976 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

javascript同步与异步的标题问题

 
阅读更多
一、同步加载与异步加载的形式
1. 同步加载
咱们平时最常运用的就是这类同步加载形式:
<script src="yourdomaincm/script.js"></script> 
同步形式,又称壅塞形式,会阻止涉猎器的后续处置,停止了后续的分析,于是住手了后续的文件加载(如图像)、渲染、代码执行。
js 之所以要同步实验,是由于 js 中或许有输出 document 内容、批改dom、重定向等举动,所以默认同步执行才是平安的。
此前的一般倡导是把<script>放在页面匹面</body>之前,何等尽笼统削减这类壅闭举止,而先让页面展示进去。
简单说:加载的Internet timeline 是瀑布模型,而异步加载的 timeline 是并发模型。

2. 思空见贯异步加载(Script DOM Element)

(function() {
     var s = document.createElement('script');
     s.type = 'text/javascript';
     s.async = true;
     s.src = 'ht/script.js';
     var x = document.getElementsByTagName('script')[0];
     x.parentNode.insertBefore(s, x);
 })();

异步加载又叫非壅塞,阅读器不才载实验 js 同时,还会继续进行后续页面的处置惩罚。
这种方式是在页面中<script>标签内,用 js 成立一个 script 元素并插入到 document 中。何等就做到了非阻塞的下载 js 代码。
async属性是HTML5中新增的异步赞成,见后文评释,加之好(不加也不影响)。
此办法被称为 Script DOM Element 法,不申请 js 同源。
将js代码包裹在匿名函数中并即时试验的方式是为了爱护变量名透露到内部可见,这是很常见的方式,尤为是在 js 库中被遍及应用。
例如 Google Analytics 和 Google+ Badge 都使用了这种异步加载代码:
(function() {
     var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
     ga.src = ('https:' == document.location.protocol ? 'https/ssl' : ww') + '.google-analytics.com/ga.js';
     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
 })();
 
(function()
    {var po = document.createElement("script");
    po.type = "text/javascript"; po.async = true;po.src = ".com/js/plusone.js";
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(po, s);
 })();
 
然而,这类加载方式在加载试验完之前会禁止 onload 事变的触发,而目下当今许多页面的代码都在 onload 时还要实行分外的衬着任务等,以是还是会壅闭有部分页面的初始化处置惩罚。
 
3. onload 时的异步加载
(function() {
     function async_load(){
         var s = document.createElement('script');
         s.type = 'text/javascript';
         s.async = true;
         s.src = .co/script.js';
         var x = document.getElementsByTagName('script')[0];
         x.parentNode.insertBefore(s, x);
     }
     if (window.attachEvent)
         window.attachEvent('onload', async_load);
     else
         window.addEventListener('load', async_load, false);
 })();
 
这与前面的方式差不久不多,但关头是它不是当即开始异步加载 js ,而是在 onload 时才开始异步加载。多么就解决了梗阻 onload 事故触发的标题问题。
增补:DOMContentLoaded 与 OnLoad 事项
DOMContentLoaded : 页面(document)曾经解析完成,页面中的dom元素也曾可用。然则页面中援用的图片、subframe笼统尚无加载完。
OnLoad:页面的所有资源都加载结束(涵概图片)。浏览器的载入进度在这时候才住手。
这两个年华点将页面加载的timeline分成了三个阶段。

4.异步加载的其它方法

由于Javascript的新闻特点,尚有不少异步加载办法:
  • XHR Eval
  • XHR Injection
  • Script in Iframe
  • Script Defer
  • document.write Script Tag
  • 尚有一种法子是用 setTimeout 迟误0秒 与 其它方法组合。
XHR Eval :经过 ajax 获取js的内容,往后 eval 实验。
var xhrObj = getXHRObject(); 
 xhrObj.onreadystatechange =  
   function() {  
     if ( xhrObj.readyState != 4 ) return; 
     eval(xhrObj.responseText); 
   }; 
 xhrObj.open('GET', 'A.js', true); 
 xhrObj.send('');
 
Script in Iframe:创立并插入一个iframe元素,让其异步试验 js 。
var iframe = document.createElement('iframe'); 
 document.body.appendChild(iframe); 
 var doc = iframe.contentWindow.document; 
 doc.open().write('<body onload="insertJS()">'); 
 doc.close();
 
GMail Mobile:页内 js 的内容被注释,所以不会执行,往后在需要的时分,获取script元素中 text 内容,去掉注释后 eval 履行。
<script type="text/javascript"> 
 /* 
 var ...  
 */ 
 </script>
 
详见参照资估中2010年的Velocity 大会 Steve Souders 和淘宝的那两个教材。
二、async 与 defer 属性
1. defer 属性
<script src="file.js" defer></script> 
defer属性声名这个脚本中将不会有 document.write 或 dom 修正。
涉猎器将会并行下载 file.js 与其它有 defer 属性的script,而不会壅塞页面后续处置。
defer属性在IE 4.0中就实现了,逾越13年了!Firefox 从 3.5 开始赞成defer属性 。
注:所有的defer 剧本包管是按顺序按序试验的。
2. async 属性
<script src="file.js" async></script> 
async属性是HTML5新增的。感化和defer相通,可是它将鄙人载后尽快试验,不能保障剧本会按步骤实验。它们将在onload 事变之前完成。
Firefox 3.6、Opera 10.5、IE 9 与 最新的Chrome 和 Safari 都赞成 async 属性。可以同时使用 async 与 defer,如许IE 4以后的所有 IE 都赞成异步加载。
3. 具体讲明
<script> 标签在 HTML 4.01 与 HTML5 的鉴识:
  • type 属性在HTML 4中是必须的,在HTML5中是可选的。
  • async 属性是HTML5中新增的。
  • 个别属性(xml:space)在HTML5中不支持。
说明:
  1. 不有 async 属性,script 将即时获得(下载)并履行,接下来才持续后面的处置,这期间梗阻了浏览器的后续处置惩罚。
  2. 如果有 async 属性,那么 script 将被异步下载并实行,同时浏览器持续后续的处理。
  3. HTML4中就也有defer属性,它揭示涉猎器这个 script 不会发生任何文档元素(没有document.write),于是阅读器会继续后续处置惩罚和衬着。
  4. 假设没有 async 属性 可是有 defer 属性,那末script 将在页面parse之后履行。
  5. 假设同时设置了两者,那么 defer 属性首要是为了让不支持 async 属性的老涉猎器遵照原本的 defer 方式措置,而不是同步方式。
另拜会民间说明:script async
小我私家补充:
既然 HTML5 中也曾赞成异步加载,为何还要运用前面保举的那种贫穷(动态确立 script 元素)的方式?
答:为了兼容尚不支持 async 老涉猎器。如果将来所有浏览器都支持了,那么直接在script中加之async 属性是最简单的方式。
三、延宕加载(lazy loading)
前面解决了异步加载(async loading)题目,再谈谈什么是稽延加载。
稽延加载:有些 js 代码的确不是页面初始化的时分就立刻需要的,而稍后的某些情况才重要的。迟误加载等于开头实际上不加载这些历久毋庸的js,而是在紧要的时辰或稍后再经过js 的控制来异步加载。
也就是将 js 切分红许多模块,页面初始化时只加载必要当即实验的 js ,今后其它 js 的加载延早退第一次紧要用到的时候再加载。
特别是页面有少量分歧的模块组成,很多兴许长期无须或根基就没用到。
就像图片的延误加载,在图片呈那会可视周边内时(在转折条下拉)才加载展现图片。
四、script 的两阶段加载 与 稽迟执行(lazy execution)
JS的加载真实是由两阶段造成:下载内容(download bytes)和执行(parse and execute)。
浏览器鄙人载完 js 的内容后就会当即对其综合和执行,岂论是同步加载还是异步加载。
前面说的异步加载,解决的只不过下载阶段的标题,但代码在下载后会立即执行。
而阅读器在赏析实验 JS 阶段是壅塞任何垄断的,这时候的浏览器处于无相应形状。
我 们都晓得经过Internet下载 script  须要显着的年华,但容易忽略了第二阶段,阐发与试验也是紧要年光的。script的阐发与履行所花的时日比我们设想的要多,尤为是script  不少很大的时刻。有些是重要立刻履行,而有些则不须要(好比只是在展示某个界面或执行某个把持时才紧要)。
这些script 可以贻误实行,先异步下载缓存起来,但不立即实验,而是在第一次紧要的时辰试验一次。
利用特殊的伎俩可以做到 下载 与 试验的分散 (再次谢谢 javascript 的音讯特性)。譬喻将 JS 的内容作为 Image或 object 对象加载缓存起来,所以就不会当即执行了,而后在第一次重要的时分再执行。
此局部的更多正文 请搜检起源参考资估中 ControlJS 的相关链接。
小技能花样:
1. 模拟较长的下载年华
写个后端脚本,让其 sleep 未必时间。如在 jsp 中 Thread.sleep(5000); ,何等5秒后才能收到内容。
2. 摹拟较长的 js 代码履行岁月(由于这步一般相比快不容易视察到):
var t_start = Number(new Date());
while ( t_start + 5000 > Number(new Date()) ) {}
这个代码将使 js 试验5秒才能完成!
五、script 标签使用的历史
 
1. script 放在 HEAD 中
<head>
  <script src=“…”></script>
  </head>
 
  • 制止了后续的下载;
  • 在IE 6-7 中 script 是法度模范下载的,而不是现在的 “并行下载、步调执行” 的方式;
  • 不才载解析实行阶段禁止衬着(rendering);
2. script 放在页面底部(2007)
... 
 <script src=“…”></script> 
 </body>
 
  • 不禁止其它下载;
  • 在IE 6-7 中 script 是程序下载的;
  • 鄙人载阐发执行阶段制止衬着(rendering);
3. 异步加载script(2009)
var se = document.createElement
 ('script'); 
 se.src = 'http://anydomain.com/A.js'; 
 document.getElementsByTagName('head') 
 [0].appendChild(se);

这便是本文首要说的方式。
  • 不制止其它下载;
  • 在所有浏览器中,script凡是并行下载;
  • 只在剖析履行阶段禁止衬着(rendering);
4. 异步下载 + 按需试验 (2010)
var se = new Image(); 
 se.onload = registerScript(); 
 se.src = 'http://anydomain.com/A.js';
 把下载 js 与 阐发履行 js 会萃进去
  • 不制止其它下载;
  • 在所有阅读器中,script但凡并行下载;
  • 不阻止渲染(rendering)直到真正需要时;
六、异步加载的标题
在异步加载的时候,无法使用 document.write 输出文档内容。
在同步内容下,document.write 是在今朝 script 所在的身分输 出文档的。而在异步模式下,浏览器继续处理后续页面内容,根蒂根基没法肯定 document.write  应该输出到什么位子,以是异步形式下 document.write 不成行。而到了页面也曾 onload  以后,再实行 document.write 将导致今朝页面的内容被清空,因为它会被动触发 document.open 办法。
现实上document.write的名望并不好,最好罕用。
取代方式:
1. 只管异步加载不能用 document.write,但仍是可以onload以后履行行使dom(建树dom或修改dom)的,何等可以完成一些本身的消息输出。譬喻要在页面异步确立一个浮动元素,这与它在页面中的位置就不妨事了,只要构建出该dom元素增长到 document 中便可。
2. 如果需求在静止位子异步天生元素的内容,那末可以在该静止身分设置一个dom元素作为指数,何等就晓得位置了,异步加载之后就能够对这个元素进行修改。
六、JS 模块化方案
异步加载,需要将所有 js 内容按模块化的方式来切分布局,其中就具有委托干系,而异步加载不保障实行步骤。
别的,namespace 若何整治 等相关问题。这部门已横跨本文内容,可参照:
RequireJS 、 Co妹妹onJS 以及 王保平(淘宝)的 SeaJS 及其博客 。
七、JS最好实践:
1. 最小化 js 文件,利用收缩器材将其最小化,同时开启http gzip缩短。工具:
2. 只管即便不要放在 <head> 中,只管即便放在页面底部,最好是</body>之前的位子
3. 防御使用 document.write 法子
4. 异步加载 js ,使用非梗阻方式,便是此文内容。
5. 尽可能不直接在页面元素上应用 Inline Javascript,如onClick 。晦气于对抗护卫弛缓存处理。
分享到:
评论

相关推荐

    以同步方式编写异步代码_WriteAsynchronousCodeAsIf it'sSynchronous_javascript

    标题“以同步方式编写异步代码_WriteAsynchronousCodeAsIf it'sSynchronous_javascript”所指的就是使用`async/await`来实现这一目标。这个话题的核心在于理解如何使用这些新特性,并将异步操作封装成易于理解和执行...

    Node.js连接OpenGauss异步转同步封装

    标题"Node.js连接OpenGauss异步转同步封装"指的是开发者将原本基于异步回调的`pg`模块进行了改造,使其可以像同步操作一样被调用。在Node.js中,异步编程是常态,但有时为了代码的简洁和易读性,开发者可能希望将...

    ajax-get用JS非同步

    综上所述,"ajax-get用JS非同步"主要涉及如何使用JavaScript异步发送GET请求,获取服务器数据,并处理返回的结果。这个主题对于想要提升网页交互性和性能的开发者来说非常重要。下载提供的压缩包文件"ajax-get",你...

    jquery ajax同步异步的执行最终解决方案

    标题中的知识点包括“jquery ajax 同步异步执行”的解决方案,即通过设置`async`属性的不同值来控制AJAX请求是同步执行还是异步执行。描述部分讲述了同步执行的一个关键点,即在AJAX请求完成前,程序会等待,不会...

    用于解构异步值的低级JS模块

    "用于解构异步值的低级JS模块"这个标题暗示我们将会探讨一个专门处理异步操作的JavaScript库或工具,它可能提供了对异步数据结构进行解构的能力。解构是一种从数组或对象中提取值的简洁语法,而将其应用于异步值,...

    写给小白看的JavaScript异步

    标题所指知识点:JavaScript异步编程基础 JavaScript是一种高级编程语言,广泛应用于网页开发中,以实现丰富的用户交互效果。异步编程在JavaScript中是一个核心概念,它允许程序在执行耗时操作时不会阻塞主线程,...

    asincronismo_javascript_

    "asincronismo_javascript_"这个标题暗示了我们将会探讨JavaScript中的异步处理技术。 异步编程在JavaScript中主要有以下几种方式: 1. **回调函数**:这是JavaScript中最早的异步处理方式。当一个耗时操作(如...

    extjs ajax同步请求所需js

    标题中提到的"extjs ajax同步请求所需js"是指ExtJS框架中用于执行同步Ajax请求的相关JavaScript代码。在ExtJS中,Ajax请求通常通过`Ext.Ajax`对象来实现。与传统的异步请求不同,同步请求会阻塞浏览器,直到请求完成...

    使用ReactNative安排后台数据同步_Java_JavaScript_下载.zip

    尽管没有具体的标签,我们可以从标题推测其内容可能涉及Java和JavaScript,这通常是ReactNative开发中的两种主要编程语言。 在ReactNative中,后台数据同步是一个关键功能,特别是在构建实时应用时,如社交应用、...

    eventproxy基于任务事件的异步模式实现

    【描述】:“eventproxy”是一个JavaScript库,设计用于解决在处理异步操作时的“回调地狱”问题,它基于任务和事件的模式来管理复杂的异步流程。在JavaScript中,由于其单线程的特性,异步编程是不可或缺的一部分,...

    Javascript异步执行不按顺序解决方案

    在上述标题和描述中提到的问题主要涉及两个案例,都是关于如何解决JavaScript异步执行不按顺序的问题。 案例一: 在懒加载或滚动事件触发的场景中,可能会连续触发多个Ajax请求,并期望将返回的数据按照特定顺序...

    JavaScript启示录PDF完整版

    根据提供的文件信息,“JavaScript启示录PDF完整版”这一标题与描述明确指出了这是一本关于JavaScript编程语言的专业书籍。然而,由于具体内容并未给出详细章节或摘要信息,我们将基于标题、描述以及JavaScript领域...

    AJAX异步调用代码

    本文将深入解析标题为“AJAX异步调用代码”的内容,该段代码展示了如何使用C#与JavaScript结合,通过AJAX进行前后台数据的异步交互。 ### 一、理解AJAX及其工作原理 AJAX的核心在于`XMLHttpRequest`对象,它允许在...

    uniapp 同步方法 实例代码

    标题提到的"uniapp 同步方法 实例代码"是针对这个问题的一个解决方案,即如何将uniapp的onLaunch方法改为同步执行,确保其在页面onLoad之前完成。 `uniapp`是一个基于Vue.js的多端开发框架,可以一次编写,应用于...

    javascript 经典代码

    在标题"javascript 经典代码"中,我们可以推测这里涉及的是JavaScript语言中的关键代码示例,可能是解决常见问题的高效方案,或者是优化性能的技巧。这些经典代码可能是关于变量声明、函数定义、对象操作、数组处理...

    javascript前端知识汇总

    6. **Promise和async/await**:为了解决异步编程的回调地狱问题,Promise和async/await提供了更优雅的解决方案,使得异步代码可以像同步代码一样编写。 7. **jQuery库**:虽然现代JavaScript有许多原生API可以替代...

    JavaScript宝典.pdf 高清下载

    尽管给定的部分内容似乎重复且不包含实际的IT或JavaScript知识,我们仍可以从标题和描述“JavaScript宝典.pdf 高清下载”出发,探讨与JavaScript相关的深入知识点,以满足对IT专业知识的需求。 ### JavaScript宝典...

    javascript高级编程(第2版)pdf.part2

    根据提供的标题、描述、标签及部分内容,我们可以推测这本书——《JavaScript高级编程(第2版)》第二部分的主要内容涉及到了JavaScript的高级应用和技术细节。尽管给出的部分内容并未包含实际的文字内容,但从书名...

    Mastering Reactive JavaScript

    在本文中,我们看到了标题《Mastering Reactive JavaScript》和描述“运用javascript进行响应式编程,带书签目录,pdf格式高清文件”,这表明文档是一本关于如何精通响应式JavaScript的书籍,并且以PDF格式提供。...

Global site tag (gtag.js) - Google Analytics