zoukankan      html  css  js  c++  java
  • 高性能JavaScript 笔记之 第1章 加载和执行

    《高性能JavaScript》,一本不可多得的好书,打算这个月把它看完。每章做个笔记,免得以后忘了~

    阻塞特性:

    JS 有个很无语的阻塞特性,就是当浏览器在执行JS 代码时,不能同时做其他任何事情,无论其代码是内嵌的还是外部的。

    脚本位置:

    浏览器在碰到一个引入外部JS 文件的<script>标签时会停下所有工作来下载并解析执行它,在这个过程中,页面渲染和用户交互完全被阻塞了,为了避免页面加载时的停顿甚至空白页的出现,JS 脚本应尽量放置在页面底部,这点很重要:

    <html>
    <head>
    <title>无标题文档</title>
    <link rel="stylesheet" type="text/css" href="styles.css" />
    </head>
    <body>

    <p>页面的内容。。。</p>

    <!-- 推荐的位置,页面底部: -->
    <script type="text/javascript" src="file1.js"></script>
    <script type="text/javascript" src="file2.js"></script>
    <script type="text/javascript" src="file3.js"></script>
    </body>
    </html>

    组织脚本:

    为了改善上面的阻塞情况,应尽可能的减少页面中<script>标签的出现次数,这同时也是考虑到HTTP 请求会带来额外的性能开销,也就是说应减少页面中外链脚本的数量。

    你可以手动合并你的多个JS 文件,也可采用类似Yahoo! combo handler 这样的实时在线服务来实现,例如下面的这个<script>标签实际上便载入了3个JS 文件:

    <html>
    <head>
    <title>无标题文档</title>
    <link rel="stylesheet" type="text/css" href="styles.css" />
    </head>
    <body>

    <p>页面的内容。。。</p>

    <!-- 推荐的位置,页面底部: -->
    <script type="text/javascript" src="http://yui.yahooapis.com/combo?file1.js&file2.js&file3.js"></script>
    </body>
    </html>

    无阻塞的脚本:

    为了阻塞状况,这里提供了几个实现并行下载JS 脚本的方案。

    i. 延迟的脚本

    HTML4 为<script>标签定义了一个defer 属性,它能使这段代码延迟执行,然而该属性只有IE4+ 和Firefox 3.5+ 支持。声明了defer 属性的<script>会在DOM加载完成,window.onload 事件触发前被解析执行:

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

    ii. 动态脚本元素

    这是最通用的解决方案,通过DOM 动态地创建<script>元素并插入到文档中,文件在该元素被添加到页面时开始下载,这样 无论在何时启动下载,文件的下载和执行过程不会阻塞页面其他进程。

    不过要注意使用这种方式加载的代码会立刻执行,这样需清楚的了解各文件的作用以及合理的执行顺序,此时跟踪并确保脚本下载完成并准备就绪是很有必要的,非IE浏览器会在<script>元素接收完成时触发一个load 事件,而IE 下则会触发一个readystatechange 事件并通过readyState 属性加以判断便可。以下是兼容地动态加载一个JS 脚本的函数:

    function load_script(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;
    callback();
    }
    }
    }
    else { //others
    script.onload = function() {
    callback();
    }
    }
    script.src
    = url;
    document.getElementsByTagName(
    'head')[0].appendChild(script);
    }

    你可以将这个函数保存至一个load_script.js 文件,然后用该函数来加载其他的脚本,当要加载多个脚本时,为了确保正确的加载顺序,可以将load_script() 的执行串联起来,最后如前面说到的放至页面的底部,这便是比较完美的解决方案了:

    <script type="text/javascript" src="load_script.js"></script>
    <script type="text/javascript">
    load_script(
    'file1.js', function() {
    load_script(
    'file2.js', function() {
    load_script(
    'file3.js', function() {
    //全部载入后的操作...
    } );
    } );
    } );
    </script>

    iii. XMLHttpRequest 脚本注入

    即通过AJAX 方式加载,不过这种方式无法实现跨域加载,不适用于大型网站。

    推荐的无阻塞模式

    我们上面做的这些工作当然也已经被那些牛人们完成了,并写成了一些优秀的JS 类库以便我们使用,它们均能很好地解决JS 脚本的阻塞问题,实现并行下载,例如: YUI3、LazyLoad、LABjs 等。http://www.cnblogs.com/eric6/archive/2011/02/23/1961816.html

  • 相关阅读:
    73. Set Matrix Zeroes
    289. Game of Live
    212. Word Search II
    79. Word Search
    142. Linked List Cycle II
    141. Linked List Cycle
    287. Find the Duplicate Number
    260. Single Number III
    137. Single Number II
    Oracle EBS中有关Form的触发器的执行顺序
  • 原文地址:https://www.cnblogs.com/aaa6818162/p/1962159.html
Copyright © 2011-2022 走看看