ihtml5 / blog

个人博客 源码阅读*前端实践 My Blog
MIT License
6 stars 0 forks source link

无阻塞加载js #44

Open ihtml5 opened 7 years ago

ihtml5 commented 7 years ago

背景

如果把脚本写死在页面中,当页面加载脚本时,会直接下载并解析脚本内容,页面停止渲染。这种情况对于大型网站来说,其对性能影响很大。而动态脚本加载可以无阻塞加载js,不影响网站性能。

无阻塞加载js三种方法

  1. 设置defer属性
    <script charset=‘utf-8’ src='a.js'></script>
    • 浏览器兼容性: ie4+,opera浏览器不支持
    • 加载时机 立即加载
    • 执行时机:: 在dom加载完成之前即DOMContentLoaded事件触发之前执行,按照他们出现在文档中顺序加载,但是在ie浏览器不一定
  2. 设置async属性
    <script charset=‘utf-8’ src='a.js'></script>
    • 浏览器兼容性: ie9+,opera浏览器不支持
    • 加载时机 立即加载
    • 执行时机:: 在脚本load事件即将发生之前执行
  3. 动态脚本
    
    (function(d,s,id) {
    var js = document.createElement(s);
    var tjs = document.getElementsByTag(s)[0];
    js.id = id;
    js.src = "//connect.facebook.net/en_US/all.js#xfbml=1"
    if (document.getElementById(id)) {
     return;  
    }
    tjs.parentNode.insertBefore(js,tjs);

})(document,'script','ihtml5')

```javascript
/*
loadScript
*/
function loadScript(src,func) {
   var dscript = document.createElement('script');
   if (dscript.onreadystatechange) { 
      if (dscript.readyState === 'loaded' || dscript.readyState === 'complete') {
          dscript.onreadystatechange = null;
          func();
      }
  } else {
      dscript.onload = func;
  }
  dscript.src = src;
  document.body.appendChild(dscript);
}

注意:

  1. 下载并未开始,直到脚本加载完成,这和动态加载图片不同(动态加载图片,只要设置src属性就会立即加载)
  2. 无论动态加载的脚本添加到head还是body标签里都不会阻塞页面渲染

    相关资源

  3. IE’s Premature Execution Problem
  4. The art and craft of the async snippet
  5. Deep dive into the murky waters of script loading
  6. Loading JavaScript without blocking
  7. non-blocking-scripts
  8. The truth about non-blocking JavaScript