我在《javascript高性能》 这本书里面读到这个文章,所以做一下学习笔记,供大家一块学习:

  1. 无阻塞脚本的概念什么?
  2. 为什么要用无阻塞脚本?
  3. 如何实现无阻塞脚本,和每个实现方式应该注意什么问题?

我来围绕以上4个问题来展开阐述:

1.无阻塞脚本的概念是什么?

无阻塞脚本也就是在下载js的时候,不影响网页中其他内容(html,css,image)的下载

2.为什么要用到无阻塞脚本?

网页中的内容无非包括的有(html,css,js,image)等这些内容,但是浏览器在下载这些文件的时候是单线程进行的,所以说:在下载东西的时
候,是一个下载完成之后才能下载另一个文件,在这些内容之中,html+css+image
可能就可以让用户眼前显示出来页面的大体内容,而js是一些动画效果,验证之类的东西,可以在这些东西加载完毕之后来加载js,或者也可以是异步加载
js,这样就可以不影响其他内容的影响,所以这样,就会用到无阻塞脚本技术.
       
如果js的大小不是很大的时候,可能没有什么影响,如果js的大小灰常或者不是小的情况下,可以考虑采用无阻塞脚本,如果不采用可能用导致用户打开页面是
一片空白,因为这个时候可能是在加载js的原因引起的.
那有的人说css也可以延迟加载,因为他也是有大小的,这个css是渲染页面(告诉浏览器dom树如何显示),所以这个必须是在js前面加载,还有比如在
js里面算某个节点的位置之类的,这个必须得到css渲染页面完成之后,才能得到准确的位置.

3.如何实现无阻塞脚本?

书里面提供了三种方式来实现无阻塞脚本:

  • 延迟脚本属性: defer属性
    也就是在脚本的标签里面添加defer属性来实现,最后加载这段javascript

    1. <script type="text/javascript" defer>
    2. //添加defer属性,first会在second弹出之后执行
    3. alert("first");
    4. </script>
    5. <script type="text/javascript">
    6. //没有添加defer属性,second会在first弹出之前执行
    7. alert("second");
    8. </script>

    缺点: 只有 Internet Explorer4+和firefox 3.5+ 支持 defer 属性,如果要适应其他的浏览器,只能选择下面的几个方案了

  • 动态脚本语言
          也就是通过Dom的方法, createElement方法来创建动态的script标签,检测标签加载完成是script的onload方法来检测加载成功,而ie里面不支持这个方法,则是onreadystatechange方法来检测.详细看以下代码:

    1. function addScript(src,callBack)
    2. {
    3. var head=document.documentElement.getElementsByTagName("head")[0];
    4. var scri=document.createElement("script");
    5. scri.type="text/javascript";
    6. /*ie browser*/
    7. if(document.all)
    8. {
    9. scri.onreadystatechange=function()
    10. {
    11. if(scri.readyState=="loaded"||scri.readyState=="complete")
    12. {
    13. alert(src+" ie brower 加载完毕!");
    14. callBack&&callBack();
    15. }
    16. }
    17. }
    18. /*other browser*/
    19. else
    20. {
    21. scri.onload=function()
    22. {
    23. alert(src+" not ie brower 加载完毕!");
    24. callBack&&callBack();
    25. }
    26. }
    27. <pre name="code" class="javascript"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"> scri.src=src;</blockquote>        //一般在设置src之后再append到dom树里面,
    28. //详情 http://www.iefans.net/ie-script-element-readystate/
    29. head.appendChild(scri);</pre>}addScript("js.js",function(){addScript("js2.js")});
    30. <pre></pre>

    31. 这段代码里面我异步加载了两个js(js.js和js2.js), 在加载第一个js之后又调用了加载第二个js. 应该注意的是ie里面的
      onreadystatechange方法里面,判断加载状态(scri.readyState) 的状态有:<br>
    32. <br>
    33. • uninitialized – 原始状态<br>
    34. • loading – 下载数据中..<br>
    35. • loaded  – 下载完成<br>
    36. • interactive  – 还未执行完毕.<br>
    37. • complete  – 脚本执行完毕<br>
    38. <br>
    39. 因为在ie各个版本里面无法确定哪个是加载成功,所以判断了两个状态,下载完成和执行完成两种状态,有关详细的ie中script加载状态请参考: http://www.iefans.net/ie-script-element-readystate/<br>
    40. <br>
    41. 优点:  1. 兼容各个主流浏览器<br>
    42. 2.可以解决js跨域问题.<br>
  • XMLHttpRequest脚本注入(XHR)
    原理:用XMLHTTP取得要脚本的内容,再创建 script 对象。
    注意:服务器端js 必须用UTF8编码保存,因为服务器与XML使用UTF8编码传送数据。
    代码如下:

    1. <script language="JavaScript">
    2. function GetHttpRequest()
    3. {
    4. if ( window.XMLHttpRequest ) // Gecko
    5. return new XMLHttpRequest();
    6. else if ( window.ActiveXObject ) // IE
    7. return new ActiveXObject("MsXml2.XmlHttp");
    8. }
    9. function AjaxPage(sId, url){
    10. var oXmlHttp = GetHttpRequest();
    11. oXmlHttp.OnReadyStateChange = function()
    12. {
    13. if ( oXmlHttp.readyState == 4 )
    14. {
    15. if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
    16. {
    17. IncludeJS( sId, url, oXmlHttp.responseText );
    18. }
    19. else
    20. {
    21. alert( 'XML request error: ' + oXmlHttp.statusText + ' ('+oXmlHttp.status+')') ;
    22. }
    23. }
    24. }
    25. oXmlHttp.open('GET', url, true);
    26. oXmlHttp.send(null);
    27. }
    28. function IncludeJS(sId, fileUrl, source)
    29. {
    30. if ((source!=null)&&(!document.getElementById(sId))){
    31. var oHead = document.getElementsByTagName('HEAD').item(0);
    32. var oScript = document.createElement( "script" );
    33. oScript.language = "javascript";
    34. oScript.type = "text/javascript";
    35. oScript.id = sId;
    36. oScript.defer = true;
    37. oScript.text = source;
    38. oHead.appendChild( oScript );
    39. }
    40. }
    41. AjaxPage( "script1", "b.js" );
    42. </script>

    部分源码来自: http://mario-design.iteye.com/blog/147810
    优点:
              1.兼容各个主流浏览器
    缺点:
              1.存在js跨域问题, 也就是 www.baidu.com  页面无法下载  www.google.com?aa.js 这个问题

以上是我对无阻塞脚本的总结,博文有什么问题可以直接留言给我或者发送邮件nishiwode923@qq.com. 中间有部分内容来自其他博文,已将链接公布在博文内部,希望原博文lz可以谅解.

javascript高性能的更多相关文章

  1. JavaScript高性能开发的十条建议

    JavaScript高性能开发的十条建议 文/开发部 Dimmacro 编者按:javascript开发大部分程序员都做过,写出来的代码质量也千差万别,现在浏览器内嵌的解释器虽然效率已经很高了,但在客 ...

  2. "Javascript高性能动画与页面渲染"笔记

    前言:好久没翻阅我的gmail邮箱了,午休时就打开看了一下,看到InfoQ推荐的一篇名为“Javascript高性能动画与页面渲染”文章,粗略的看了一下,很赞!讲的很详细,对好些细节讲的都很好,很通俗 ...

  3. javascript高性能编程-算法和流程控制

          代码整体结构是执行速度的决定因素之一. 代码量少不一定运行速度快, 代码量多也不一定运行速度慢. 性能损失与代码组织方式和具体问题解决办法直接相关.       倒序循环可以提高性能,如: ...

  4. Javascript高性能编程-提高数据访问速度

         hasOwnProperty()仅检索实例不检索原型,in即检索实例,又检索原型      成员嵌套越深,访问速度越慢,只在必要的情况下使用对象成员.      如果在同一个函数中你要多次读 ...

  5. Javascript高性能编程-提高javascript加载速度

        1.将所有<script>标签放在尽可能接近<body>标签底部的位置,以保证页面在脚本运行之前完成解析尽量减少对整个页面下载的影响     2.限制页面的<sc ...

  6. JavaScript 高性能笔记

    浏览器解析 JavaScript .CSS .DOM 时,一般都是单线程解析,所以,引用外部文件时的位置不同,UE体验也不同. 下面是 Yahoo 大牛 Nicholas C. Zakas 的 < ...

  7. Javascript高性能动画与页面渲染

    转自:http://www.infoq.com/cn/articles/javascript-high-performance-animation-and-page-rendering No setT ...

  8. javascript高性能写法

    看到一篇不错的博文,如果想写出比较高性能的代码,可参看这个链接http://developer.51cto.com/art/200906/131335.htm

  9. JavaScript 高性能数组去重

    中午和同事吃饭,席间讨论到数组去重这一问题 我立刻就分享了我常用的一个去重方法,随即被老大指出这个方法效率不高 回家后我自己测试了一下,发现那个方法确实很慢 于是就有了这一次的高性能数组去重研究 一. ...

随机推荐

  1. JAVA篇之环境安装(Windows)

    一.JAVA 安装两个重要概念 1.JRE::英文Java Development Kit ,记住英文,深入理解就去看相关文章. 2.JDK:英文 Java Runtime Environment,记 ...

  2. asp.net mvc+webuploader大文件分片上传

    首先是前端: var GUID = WebUploader.Base.guid();//一个GUID uploadereditsVideo = WebUploader.create({ // swf文 ...

  3. 基于 ZKEACMS 的云建站 / 自助建站解决方案

    基于ZKEACMS的云建站 / 自助建站解决方案,一站式托管,解决企业建站需求,功能强大,高度自定义.用户只需在界面上输入一些基本信息,选择相应的主题 / 网站模板,然后就可以快速创建一个独一无二的网 ...

  4. python: list转字符串

    命令: ' '.join(list) 其中,引号中是字符之间的分割符,如“,”,“;”,“\t”等等 如: list = [1, 2, 3, 4, 5] ''.join(list) 结果即为:1234 ...

  5. Ionic2使用百度地图API(JS)出现白屏解决方案

    最近自学ionic2,写了一个内嵌百度地图JS的demo,实际跑起来之后出现了大家常见的白屏问题.. 最初的实现是这样的: 首先主页内嵌了一个百度地图插件 <div id="Bmap& ...

  6. 基本bash shell命令

    以下列举一些常用的bash shell命令,在使用时方便查找. 访问Linux系统上的手册:man 命令.例:man ps      手册是由分页程序来显示的,可以通过点击 空格,回车,向上和向下箭头 ...

  7. weex 初始化

    文档教程 一. 已有项目集成weex, 有时候会报错, 因为sdk中用到了socket pod 'WeexSDK' pod 'SocketRocket' 二. 在app启动方法 -didFinish ...

  8. 数组其他部分及java常见排序

    数据结构的基本概述: 数据结构是讲什么,其实大概就分为两点: 1.数据与数据之间的逻辑关系:集合.一对一.一对多.多对多 2.数据的存储结构: 一对一的:线性表:顺序表(比如:数组).链表.栈(先进后 ...

  9. SQL语句之用户管理

    SQL语句系列 1.SQL语句之行操作 2.SQL语句之表操作 3.SQL语句之数据库操作 4.SQL语句之用户管理 占坑,待写……

  10. js 面向对象 定时器 046

    获取DOM对象补充 document.getElementsByTagName('div'); //获取的多个DOM对象 这种对象叫伪数组 如果想遍历此对象 通过for(var i=0; i < ...