zoukankan      html  css  js  c++  java
  • <高性能JavaScript>笔记 [1~3]

    <高性能JavaScript>这是一本很好的书,主要讨论实际js开发时要注意的性能问题.

    也算是一本JS的进阶读物,如果要看此书,建议先看<JavaScript权威指南>


    一:加载和执行


    主要讲述了如何更高效的载入JavaScript脚本文件,解决浏览器的阻塞问题.

    其中最简单的解决方法就是把导入的js文件的标签写在 </body> 前,而且不需要使用 onload 事件.
    尽量把js文件进行压缩和合并,因为每次加载一个外链js文件都需要发送一次http请求,这样会增加性能的消耗.

    另外,每一个 <script> 标签初始下载时都会堵塞页面渲染,这不仅针对外链脚本,内嵌脚本也有同样的情况,每遇到一个 <script> 标签就会因执行脚本而导致一定的延时,所以减少<script> 标签能改善页面的总体性能.
    当把内嵌脚本放在引用外联样式表的 <link> 标签之后会导致页面堵塞去等待样式表的下载,这样做是为了确保内嵌脚本在执行时能获得最精准的样式信息,因此不建议把内嵌脚本紧跟在<link> 标签之后.

    那什么是无阻塞脚本呢?
    window 对象的 onload 事件触发后才下载脚本,就是所谓的无堵塞脚本.因为这个时候下载脚本不会影响页面的下载和渲染.
    解决方法有:
    + 延迟脚本(Deferred Script) - 使用 <script> defer 属性(仅适用于IE和Firefox3.5+);
    + 动态脚本元素(Dynamic Script Elements) - 使用动态创建的 <script> 元素来下载并执行代码;
    + XMLHttpRequest脚本注入(XMLHttpRequest Script Injection) - 使用 XMLHttpRequest 对象下载js代码并注入页面;

    最后,
    还介绍了YUI3,LazyLoad,LABjs等库来实现无阻塞脚本.



    二:数据访问

    - 访问直接量和局部变量的速度最快,相反,访问数组元素的对象成员相对较慢;

    - 由于局部变量存在于作用域链的起始位置,因此访问局部变量比访问跨作用域变量更快.变量在作用域链中的位置越深,访问所需时间就越长.由于全局变量总处在作用域链的最末端,因此访问速度也是最慢的;

    - 避免使用 with 语句,因为它会改变运行期上下文作用域链.同样, try-catch 语句中的 catch 也有同样的影响,因此也要小心使用;

    - 嵌套的对象成员会明显影响性能,尽量少用. 如: location.href 比 window.location.href 要快;

    - 属性或方法在原型链中的位置越深,访问它的速度也越慢;

    - 通常来说,你可以通过把常用的对象成员,数组元素,跨域变量保存在局部变量中来改善JavaScript的性能,因为局部变量访问速度更快. 如: var div = document.getElementById("div");


    这章用了很多UML图来解释JavaScript的数据访问,很具体形象.



    三:DOM访问与修改

    浏览器中通常会把DOM和JavaScript独立实现,分为两个不同的库.
    因此访问DOM需要巨大的性能开销.
    尽量避免DOM的访问次数,是提高性能的重要环节.
    例如:多次访问的DOM节点可以通过局部变量来存储.

    另外,要小心处理HTML集合.
    以下方法和属性均返回一个HTML集合:
    document.getElementByName()
    document.getElementsByClassName()
    document.getElementsByTagName()
    document.all
    document.images
    document.links
    document.forms
    document.forms[0].elements

    所谓的的HTML集合,是动态返回对应的HTML对象集合.
    每一次调用以上方法和属性,都会重复一次查询元素的过程,开销十分大.
    建议copy到一个数组对象中再进行操作.

    许多现代浏览器均提供一些API来操作元素节点.
     
    属性名
    被替换的属性
    children
    childNodes
    childElementCount
    childNodes.length
    firstElementChild
    firstChild
    lastElementChild
    lastChild
    nextElementSibling
    nextSibling
    previousElementSibling
    previousSibling
     
    以上属性Firefox 3.5+, Safari 4+, Chrome 2+, Opera 9.62+ 均支持.
    但IE6,7,8只支持children属性.

    还可以使用CSS选择器来获取特定元素对象.
    最新的浏览器都提供了一个querySelectorAll()的方法.
    例如: var elements = document.querySelectorAll("#menu a");
    不过该方法返回的对象是一个NodeList的类数组对象,并不是HTML集合.
    所以并不会重复查询元素.
    IE 8+, Firefox 3.5+, Safari 3.1+, Chrome 1+, Opera 10+ 均支持该属性.
    querySelector() 用来获取第一个匹配的节点.


    尽量减少渲染树的强制刷新(关于DOM树和渲染树,请自行Google或查阅该书)
    以下方法会导致渲染树的强制刷新:
    offsetTop, offsetLeft, offsetWidth, offsetHeight
    scrollTop, scrollLeft, scrollWidth, scrollHeight
    clientTop, clientLeft, clientWidth, clientHeight
    getComputedStyle() (currentStyle in IE)
    以上属性和方法需要返回最新的布局信息,因为要强制渲染列队中的渲染树修改项.
    在修改样式的过程中,最好避免使用上面列出的属性.

    对于css样式的多次操作,可以通过cssText进行合并:
    element.style.cssText = "border-left: 1px; padding: 5px;"
    但此方法是直接覆盖已有的style样式,如果要追加样式:
    element.style.cssText += "margin: 5px;"
    当然,也可以通过修改class名称避免多次强制刷新

    需要批量修改DOM时,可以通过通过下面的方法优化,借此减少强制刷新的次数:
    +隐藏元素,应用修改,重新显示;
    +使用文档片断进行构建子树,然后插入文档; (建议使用此方法 createDocumentFragment() )
    +将原始元素拷贝到一个脱离文档的节点,修改副本在进行替换;

    还要避免页面大部分元素的重排,可以让动画元素使用绝对定位脱离文档流.
    善于利用时间委托,也是提高性能的好办法.







  • 相关阅读:
    CURD演示 2
    CURD演示 2
    测试关闭mojo utf-8
    测试关闭mojo utf-8
    mojo 关闭utf8
    mojo 关闭utf8
    标准Web系统的架构分层
    Myeclipse学习总结(6)——MyEclipse断点调试
    RabbitMQ学习总结(7)——Spring整合RabbitMQ实例
    RabbitMQ学习总结(7)——Spring整合RabbitMQ实例
  • 原文地址:https://www.cnblogs.com/maplejan/p/2731951.html
Copyright © 2011-2022 走看看