您的位置:首页 > Web前端 > JavaScript

高性能javascript读书笔记(一 加载和运行)

2015-07-30 17:29 441 查看
第一章 加载和运行

<script>标签的出现使整个页面因脚本解析,运行而出现等待。不论实际的javascript代码是内联的还是包含在一个不相关的外部文件中,页面下载和解析必须停下,等待脚本完成这些处理,然后才能继续,因为脚本可能在运行过程中修改页面内容。document.write();

<script>标签可以放在<head>里面,但是如果我们放了很多文件在head里,每个<script>都会阻塞页面的解析,直到他完整的下载并运行了外部的javascript文件。并且浏览器在遇到<body>标签之前是不会渲染页面的任何部分,所以这样导致了一个可以察觉的延迟。每个js文件都有一个下载和运行的时间。

IE8,FF3.5, Safari4 和chrome2允许并行下载js文件,一个<script>标签下载外部资源,不会阻塞其他<script>标签。但是,javascript的下载仍然要阻塞其他资源的下载过程,例如图片。即使脚本之间的下载过程互补阻塞,页面仍要等待所有javascript代码下载并执行完成后才能继续。

推荐:将所有<script>代码放在尽可能接近<body>标签底部的位置,尽量减少对整个页面下载的影响。

限制页面的<script>的总数也可以改善性能。

减少引用外部脚本文件的数量,每个http请求都会产生额外的性能负担,下载一个100KB的文件比下载四个25KB的文件要快,可以打包将这些文件整合成一个文件

Yahoo!创建了"联合句柄"。任何一个网站可以使用联合句柄url指出包含哪些文件。

src="http://yui.yahooapis.com/combo/hahoo.min.js&2.70/build/event-min.js"

此代码只有一个script标签,在页面底部,加载多个javascript,这是在html页面中包含多个外部javascript的最佳方法。

非阻塞脚本:等页面加载之后,再加载javascript代码,意味着在window的load事件发出之后开始下载代码,

Deferred script脚本

<script type=”text/javascript” src=”file1.js” defer>

带有Defer属性的script标签可放在文档的任何位置,对应的javascript文件将在<script>解析时启动下载,但代码不会被执行,直到DOM加载完成(在onload事件句柄被调用之前)

当一个defer的javascript 文件被下载时,他不会阻塞浏览器的其他处理程序,所以文件可与页面的其他资源一起并行下载。(IE和FF3.5支持)

<script defer> alert("deffer"); </script>

<script> alert("next"); </script>

<script defer> window.onload=function(){alert(“widow”)}</script>


顺序是 next deffer window

注意:标记问defer的不是第二个运行的,是在onload事件句柄处理之前被调用的。

Dynamic script elements 动态脚本元素

新的script元素加载.js原文件,此文件当元素添加到页面之后立刻开始下载。无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程。<script>事件有一个readyState属性,有五种取值:

uninitialized 默认状态

loading 下载开始

loaded 下载完成

interactive下载完成尚不可用

complete 所以数据已准备好

在script元素的生命周期,readyState的这些取值并不一定都会被用到,对感兴趣loaded complete,

IE对readyState值所表示的最终状态并不一致,在readyState事件中,检查两种状态,当其中一种出现时,删除readystatechange事件句柄。

封装的函数实现javascript文件的动态加载:

function loadscript(url, callback){
  var script=document.createElement("script");
  script.type="text/javascript";
  if(script.readyState){//IE
   script.onreadyStatechange=function(){
    if(script.readyState="loaded"||script.readyState="complete"){
      script.onreadyStatechange=null;//删除readystatechange事件句柄,保证事件不会被处理两次
       callback();
        }
      }
   }else{//others
    script.onload=function(){
    callback();
  }
}
script.src=url;
document.getElementsByTagName("head")[0].appendChild(script);
}


  

在页面中动态加载很多javascript文件,浏览器不能保证文件加载的顺序

所以主流浏览器之中,只有FF 和Opera会保证脚本按照指定的顺序执行,其他浏览器将按照服务器返回他们的次序下载并运行不同的代码文件。

串联起来:

loadScript(“file.js”, function (){
(“file1.js”, function(){
(“file2.js”,function(){
Alert(“fd”); });});})


缺点:file可用之后,执行file1,之后再执行file2, 方法可行,但是如果要下载和执行的文件比较多,还是比较麻烦。

如果是多个文件次序十分重要,更好的办法是将这些文件按照正确的次序连接成一个文件,独立文件可以一次性下载所以代码,由于这是异步的,所以没有什么损失。

(动态脚本加载是非阻塞javascript下载中最常见的,因为可以跨浏览器,简单易用。)

XMLHttpRequest Script Injection XHR脚本注入

首先创建XHR对象,然后下载javascript文件,接着用动态<script>元素将javascript代码注入页面。

var xhr = new XMLHttpRequest();

xhr.open("get", "file1.js", true);

xhr.onreadyStatechange=function(){

  if(xhr.readyState==4){

    if(xhr.status>=200&&xhr.status<300||xhr.status==304){

      var script=document.createElement("script");

      script.type="text/javascript";

      script.text=xhr.responseText;

      document.body.appendChild(script);

    }

  }

}

xhr.send(null);


向服务器发送一个获取file.js文件的GET请求,onreadystatechange事件处理函数检查readyState是不是4,然后检查HTTP状态码是不是有效(2XX表示有效的回应,304代表响应),如果收到了一个有效响应,就创建script标签,将他的文本属性设置为从服务器收到的responseText字符串,实际会创建一个带有内联代码的script 一旦新script元素被添加到文档,代码被执行,并准备使用。

优点:可以下载不立即执行的javascript代码,由于代码返回在script标签之外,它下载后不会自动执行,你可以推迟执行,直到一切都准备好。

所有浏览器中都不会异常

缺点:javascript文件都必须与页面放置一个域内。

推荐的向页面加载大量的Javascript的方法:

1,先包含动态加载javascript所需的代码,然后加载页面初始化所需要的除javascript以外的部分。这部分代码尽量小,可能只包含一个loadScript()函数,它下载和运行非常迅速,不会对页面造成很大干扰,当初始代码准备好了,再用它加载其他的javascript代码。

<script type="text/javascript" src="load.js></script>
<script type="text/javascript">
loadScript("the-rest.js", function(){
Application.init();
};
</script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: