zoukankan      html  css  js  c++  java
  • 性能优化之无阻塞加载脚步方法比较

        秋招结束了~~,好像偷懒了很久,没更博了。总结一下自己近来看书的内容。

    说明一下,内容大部分来自《高性能网站建设进阶指南》。

    乱入内容

    Web应用和传统桌面应用有一个共同的目标:尽可能快地响应用户输入。
    怎样才算是快?Jakob Nielsen是Web可用性领域知名且备受推崇的专家,引用他的观点来说就是:如果JavaScript代码执行时间超过了0.1秒,页面将会给人不够平滑快捷的感觉,如果执行时间超过了1秒,则会感到应用程序缓慢,超过了10秒,那么用户将会非常沮丧。
    性能分析器:Firebug性能分析器
    当延迟变得很严重时:线程处理Web Workers、Gears
    无阻塞加载脚步
         script标签的阻塞行为会对页面性能产生负面影响。大多数浏览器在下载或执行脚本的同时不会下载其他内容。有时候这种阻塞是非必要的。所以,有些情况我们希望以不阻塞其他内容下载的方式来加载JavaScript。可以做到这点使页面加载更快的有:
    1.XHR Eval
    2.XHR注入
    3.Script in Iframe
    4.Script DOM Element
    5.Script Defer
    6.document.write Script Tag
    ①XHR Eval
    比较好理解,就是为了并行加载更多的脚本,把一些脚本拆分,然后通过ajax的方式请求脚本,再通过eval来执行。
    实例代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
       var xhrObj=getXHRObject();
       xhrObj.onreadystatechange=function(){
          if(xhrObj.readyState==4&&200==xhrObj.status){
             eval(xhrObj.responseText);
          }
      };
    xhrObj.open('GET','A.js',true);
    xhrObj.send(' ');
    //获取XHR对象的基本方法
    function getXHRObject (){
       if (typeof XMLHttpRequest != "undefined"){
              return new XMLHttpRequest();
       else if (typeof ActiveXObject != "undefined"){
     if (typeof arguments.callee.activeXString != "string"){
         var versions = [ "MSXML2.XMLHttp.6.0""MSXML2.XMLHttp.3.0",
              "MSXML2.XMLHttp"],
              i, len;
         for (i=0,len=versions.length; i < len; i++){
         try {
            new ActiveXObject(versions[i]);
            arguments.callee.activeXString = versions[i];
            break;
         catch (ex){
           //跳过
         }
        }
      }
       return new ActiveXObject(arguments.callee.activeXString);
      else {
          throw new Error("No XHR object available.");
      }
    }

    缺点:

      通过XMLHttpRequest获取的脚本必须部署在和主页面相同的域中。

    ②XHR注入

        类似于XHR Eval,XHR注入技术也是通过XMLHttpRequest来获取JavaScript的,但与eval不同的是,该机制通过创建一个script的DOM元素,然后把XMLHttpRequest的响应注入script中来执行JavaScript的,某些情况下使用这种机制的性能会优于eval。

    示例代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
       var xhrObj=getXHRObject();
       xhrObj.onreadystatechange=function(){
          if(xhrObj.readyState==4){
             var scriptElem=document.createElement('script');
             document.getElementsByTagName('head')[0].appendChild(scriptElem);
             scriptElem.text=xhrObj.responseText;
          }
      };
    xhrObj.open('GET','A.js',true);
    xhrObj.send(' ');

    ③Script in Iframe

       主页中的iframe和其他组件是并行加载的,与用iframe在一个HTML页面中包含另一个页面的传统做法不同,Script in Iframe技术利用iframe无阻塞加载JavaScript,实现过程完全在HTML中完成。
    示例代码:
    1 <iframe src='A.html' width=0 height=0 frameborder=0 id='frame1'></ifame>

    缺点:

    该技术使用了A.html,而不是A.js,因为iframe认为其返回的是HTML文档。所有我们要做的就是在HTML文档中把外部脚本转换为行内脚本。并且要求iframe和主页面同域。

    附访问iframe的方法:

    1.通过frames数组:window.frames[0]
    2.通过document.getElementById访问。
    ④Script DOM Element
       利用script标签,动态创建脚本,创建script元素,并设置其src值。
    示例代码:
    1
    2
    3
    var scriptElem=document.createElement('script');
    scriptElem,src='http://test.js';
    document.getElementByTagName('head')[0].appendChild(scriptElem);
    ⑤Script Defer
      非常简单,这个属性的用途是表明脚本在执行时不会影响页面的构造。也就是说,脚本会被延迟到整个页面都解析完毕后再运行。因此,在<script>元素中设置defer属性,相当于告诉浏览器立即下载,但延迟执行。

    HTML5规范要求脚本按照它们出现的先后顺序执行,因此第一个延迟脚本会先于第二个延迟脚本执行,而这两个脚本会先于DOMContentLoaded事件执行。在现实当中,延迟脚本并不一定会按照顺序执行,也不一定会在DOMContentLoad时间触发前执行,因此最好只包含一个延迟脚本。

    示例代码:
    1 <script defer src='A.js'></script>
    在这里顺便辨析一下defer属性和async属性

    defer属性:IE4.0就出现。defer属声明脚本中将不会有document.write和dom修改。浏览器会并行下载其他有defer属性的script。而不会阻塞页面后续处理。注:所有的defer脚本必须保证按顺序执行的。

        <script type="text/javascript" defer></script>

    async属性:HTML5新属性。脚本将在下载后尽快执行,作用同defer,但是不能保证脚本按顺序执行。他们将在onload事件之前完成。

        <script type="text/javascript" defer></script>

    Firefox 3.6、Opera 10.5、IE 9和最新的Chrome和Safari都支持async属性。可以同时使用async和defer,这样IE 4之后的所有IE都支持异步加载。

    没有async属性,script将立即获取(下载)并执行,期间阻塞了浏览器的后续处理。如果有async属性,那么script将被异步下载并执行,同时浏览器继续后续的处理。

    更多参考:https://segmentfault.com/a/1190000006778717

    ⑥document.write Script Tag
      使用document.write把HTML标签script写入页面中。

    技术综述

    不同情况下的最佳脚本加载技术的决策树

    决策树中的六种结果详解

  • 相关阅读:
    mysql索引最左匹配的理解(转载于知乎回答)
    mysql深度优化与理解(迄今为止读到最优秀的mysql博客)
    PHP数组函数总结与使用
    进程(process)和线程(thread)
    联合索引使用规则(转载)
    mysql优化大全(转自别人 )
    HTTP隧道解决的问题
    HTTP代理协议 HTTP/1.1的CONNECT方法
    vant弹窗提示
    vue获取验证码倒计时
  • 原文地址:https://www.cnblogs.com/zhaodahai/p/6823768.html
Copyright © 2011-2022 走看看