Home >Web Front-end >JS Tutorial >How to implement JS synchronization, asynchronousness, and lazy loading

How to implement JS synchronization, asynchronousness, and lazy loading

php中世界最好的语言
php中世界最好的语言Original
2018-05-23 14:35:052343browse

This time I will bring you how to implement JS synchronization, asynchronous, and delayed loading, and what are the precautions for implementing JS synchronization, asynchronous, and delayed loading. The following is a practical case, let's take a look.

1: Synchronous loading

The most commonly used method.

Synchronous mode, also known as blocking mode , will prevent the browser from subsequent processing and stop subsequent parsing. Only when the current loading is completed, the next step can be performed. Therefore, synchronous execution is safe by default. But if there are behaviors such as outputting document content, modifying DOM, redirection, etc. in js, it will cause page congestion. Therefore, it is generally recommended to place the <script> tag at the end of <body> to reduce page blocking as much as possible. <p style="text-align: left;"></p> <p style="text-align: left;">2: Asynchronous loading<strong></strong></p>Asynchronous loading is also called non-blocking loading. While the browser is downloading and executing js, it will continue to process subsequent pages. There are three main ways. <p style="text-align: left;"></p> <p style="text-align: left;">Method 1: Also called Script DOM Element<span style="color: #800000"></span></p> <pre class="brush:php;toolbar:false">(function(){  var scriptEle = document.createElement(&quot;script&quot;);  scriptEle.type = &quot;text/javasctipt&quot;;  scriptEle.async = true;  scriptEle.src = &quot;http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js&quot;;  var x = document.getElementsByTagName(&quot;head&quot;)[0];  x.insertBefore(scriptEle, x.firstChild);   })();</pre><async> attribute is a new asynchronous support in HTML5. This method is called the Script DOM Element method. Both Google Analytics and Google Badge use this asynchronous loading code. <p style="text-align: left;"></p> <pre class="brush:php;toolbar:false">(function(){;  var ga = document.createElement('script');   ga.type = 'text/javascript';   ga.async = true;   ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';   var s = document.getElementsByTagName('script')[0];   s.parentNode.insertBefore(ga, s);  })();</pre>However, this loading method will prevent the onload event from being triggered before the execution is completed. Now, the code of many pages also performs additional rendering work during onload, so it will still block the initialization processing of some pages. <p style="text-align: left;"></p> <p style="text-align: left;">Method 2: Asynchronous loading during onload<span style="color: #800000"></span></p> <pre class="brush:php;toolbar:false">(function(){  if(window.attachEvent){  window.attachEvent(&quot;load&quot;, asyncLoad);  }else{  window.addEventListener(&quot;load&quot;, asyncLoad);  }  var asyncLoad = function(){  var ga = document.createElement('script');   ga.type = 'text/javascript';   ga.async = true;   ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';   var s = document.getElementsByTagName('script')[0];   s.parentNode.insertBefore(ga, s);  } )();</pre>This method just puts the method of inserting script in a function, and then puts it in the onload method of the window Execution, thus solving the problem of blocking the onload event triggering. <p style="text-align: left;"></p> <p style="text-align: left;">Note: The difference between DOMContentLoaded and load. The former is after the document has been parsed and the DOM elements in the page are available, but the pictures, videos, audio and other resources in the page have not been loaded. The function is the same as the ready event in jQuery; the difference in the latter is that all resources on the page have been loaded. <span style="color: #ff0000"></span></p> <p style="text-align: left;">Method 3: Other methods<span style="color: #800000"></span></p>Due to the dynamic nature of JavaScript, there are many asynchronous loading methods: XHR Injection, XHR Eval, Script In Iframe, Script defer attribute, document.write(script tag). <p style="text-align: left;"></p>XHR Injection (XHR injection): Get javascript through XMLHttpRequest, and then create a script element to insert into the DOM structure. After the ajax request is successful, set script.text to the responseText returned after the request is successful. <p style="text-align: left;"></p> <pre class="brush:php;toolbar:false"> //获取XMLHttpRequest对象,考虑兼容性。  var getXmlHttp = function(){  var obj;  if (window.XMLHttpRequest)   obj = new XMLHttpRequest();  else   obj = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);  return obj;  };   //采用Http请求get方式;open()方法的第三个参数表示采用异步(true)还是同步(false)处理  var xmlHttp = getXmlHttp();  xmlHttp.open(&quot;GET&quot;, &quot;http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js&quot;, true);  xmlHttp.send();   xmlHttp.onreadystatechange = function(){  if (xmlHttp.readyState == 4 &amp;&amp; xmlHttp.status == 200){   var script = document.createElement(&quot;script&quot;);   script.text = xmlHttp.responseText;   document.getElementsByTagName(&quot;head&quot;)[0].appendChild(script);  }  }</pre>XHR Eval: Different from the way XHR Injection executes responseText, responseText is directly executed in the eval() function. <p style="text-align: left;"></p> <pre class="brush:php;toolbar:false">//获取XMLHttpRequest对象,考虑兼容性。  var getXmlHttp = function(){  var obj;  if (window.XMLHttpRequest)   obj = new XMLHttpRequest();  else   obj = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);  return obj;  };   //采用Http请求get方式;open()方法的第三个参数表示采用异步(true)还是同步(false)处理  var xmlHttp = getXmlHttp();  xmlHttp.open(&quot;GET&quot;, &quot;http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js&quot;, true);  xmlHttp.send();   xmlHttp.onreadystatechange = function(){  if (xmlHttp.readyState == 4 &amp;&amp; xmlHttp.status == 200){   eval(xmlHttp.responseText);   //alert($);//可以弹出$,表明JS已经加载进来。click事件放在其它出会出问题,应该是还没加载进来   $(&quot;#btn1&quot;).click(function(){   alert($(this).text());   });  }  }</pre>Script In Irame: Insert an iframe element in the parent window, and then perform the operation of loading JS in the iframe. <p style="text-align: left;"></p> <pre class="brush:php;toolbar:false"> var insertJS = function(){alert(2)};  var iframe = document.createElement(&quot;iframe&quot;);  document.body.appendChild(iframe);  var doc = iframe.contentWindow.document;//获取iframe中的window要用contentWindow属性。  doc.open();  doc.write(&quot;&lt;script&gt;var insertJS = function(){};&lt;\/script&gt;&lt;body onload=&amp;#39;insertJS()&amp;#39;&gt;&lt;/body&gt;&quot;);  doc.close();</pre>GMail Mobile: The JS content in the industry is commented, so it will not be executed. When needed, get the text content in the script, remove the comments, and call eval() to execute. <p style="text-align: left;"></p> <pre class="brush:php;toolbar:false"> &lt;script type=&quot;text/javascript&quot;&gt;   /*   var ...   */   &lt;/script&gt;</pre>HTML5 new attributes: async and defer attributes<p style="text-align: left;">defer attribute: It appears in IE4.0. There will be no document.write and dom modifications in the defer attribute declaration script. The browser will download other scripts with defer attributes in parallel. without blocking subsequent processing of the page. Note: All defer scripts must be executed in order. <br></p> <p style="text-align: left;"> <script type="text/javascript" defer></script>

async attribute: HTML5 new attribute. The script will be executed as soon as possible after downloading. The function is the same as defer, but there is no guarantee that the script will be executed in order. They will complete before the onload event.

Firefox 3.6, Opera 10.5, IE 9 and the latest Chrome and Safari are Supports async attributes. You can use async and defer at the same time, so that all IE after IE 4 support asynchronous loading.

Without the async attribute, the script will be obtained (downloaded) and executed immediately, blocking the browser's subsequent processing. If there is an async attribute, the script will be downloaded and executed asynchronously, while the browser continues subsequent processing.

总结: 对于支持HTML5的浏览器,实现JS的异步加载只需要在script元素中加上async属性,为了兼容老版本的IE还需加上defer属性;对于不支持HTML5的浏览器(IE可以用defer实现),可以采用以上几种方法实现。原理基本上都是向DOM中写入script或者通过eval函数执行JS代码,你可以把它放在匿名函数中执行,也可以在onload中执行,也可以通过XHR注入实现,也可以创建一个iframe元素,然后在iframe中执行插入JS代码。

三:延迟加载

有些JS代码在某些情况在需要使用,并不是页面初始化的时候就要用到。延迟加载就是为了解决这个问题。将JS切分成许多模块,页面初始化时只加载需要立即执行的JS,然后其它JS的加载延迟到第一次需要用到的时候再加载。类似图片的延迟加载。

JS的加载分为两个部分:下载和执行。异步加载只是解决了下载的问题,但是代码在下载完成后就会立即执行,在执行过程中浏览器处于阻塞状态,响应不了任何需求。

解决思路:为了解决JS延迟加载的问题,可以利用异步加载缓存起来,但不立即执行,需要的时候在执行。如何进行缓存呢?将JS内容作为Image或者Object对象加载缓存起来,所以不会立即执行,然后在第一次需要的时候在执行。

1:模拟较长的下载时间:

利用thread让其sleep一段时间在执行下载操作。

2:模拟较长的JS代码执行时间

var start = Number(new Date());
while(start + 5000 > Number(new Date())){//执行JS}

这段代码将使JS执行5秒才完成!

JS延迟加载机制(LazyLoad):简单来说,就是在浏览器滚动到某个位置在触发相关的函数,实现页面元素的加载或者某些动作的执行。如何实现浏览器滚动位置的检测呢?可以通过一个定时器来实现,通过比较某一时刻页面目标节点位置和浏览器滚动条高度来判断是否需要执行函数。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

vue自动化表单有哪几种方式

vue-element怎么做出音乐播放器

The above is the detailed content of How to implement JS synchronization, asynchronousness, and lazy loading. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn