zoukankan      html  css  js  c++  java
  • Javascript性能优化(一)

    一、加载

    1. 依据HTML 4规范,script标签可以放置在head和body标签中的任意位置

    2. 下载js脚本会阻塞其他页面文件下载,所以应尽可能将script标签放置在body底部

    3. HTML 4为script标签增加了一个defer属性,表明延迟执行,但这并不是标准做法

    4. 将多个script合并后压缩,放置在body标签底部,是引入多个外链javascript文件的最佳实践

    5. 通过动态创建标签,可以异步引入js文件,代码如下:

     1 function loadScript(url, callback) {
     2     
     3     var script = document.createElement('script')
     4     script.type = 'text/javascript'
     5 
     6     // IE
     7     if (script.readyState) {    
     8         script.onreadystatechange = function() {
     9             if (script.readyState == 'loaded' || script.readyState == 'complete') {
    10                 script.onreadystatechange = null
    11                 callback()
    12             }
    13         }
    14 
    15     // other browser
    16     } else {
    17         script.onload = function() {
    18             callback()
    19         }
    20     }
    21 
    22     script.src = url
    23     document.getElementByTagName('head')[0].appendChild(script)
    24 }

    6.使用xhr对象,同样可以异步引入js。与上面不同的是,你可以获得准确的加载进度,并且,脚本并不是一下载好就执行(取决于script标签添加到页面中的时间)

     1 var xhr = new XMLHttpRequest()
     2 
     3 xhr.open('get', 'file.js', true)
     4 xhr.onreadystatechange = function() {
     5 
     6     if (xhr.readyState == 4) {
     7         if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
     8 
     9             var script = document.createElement('script')
    10 
    11             script.type = 'text/javascript'
    12             script.text = xhr.responseText
    13 
    14             document.body.appendChild(script)
    15         }
    16     }
    17 }

    二、数据

    1. javascript数据类型:直接量、变量、数组、对象

    2. 直接量和局部变量的访问速度优于数组项和对象成员,变量访问性能与作用域嵌套有直接关系

    3. 闭包比非闭包函数需要更多内存开销(变量的生命周期延长,并且最后不一定能释放)

    4. 使用hasOwnProperty只对实例进行查找,而使用for in遍历对象成员可以访问prototype

    5. 每次使用 "." 操作符时,会导致javascript引擎搜索所有对象成员,对象成员嵌套越深,速度越慢。尤其是当访问的属性(方法)在原型链中时

    6. 使用 "." 操作符,在safari下会比[key]更快,但[key]的写法更通用(属性为保留字)

    7. 命名空间是导致频繁访问嵌套属性的起因之一,对命名空间进行缓存,可以有效减少对象访问次数

      

    1 // 对命名空间进行缓存
    2 var load = ME.core.load
    3 
    4 // 对resource.length进行缓存,避免每次遍历都访问resource
    5 for (var i = 0, length = resource.length; i < length; i++) {
    6 
    7     load.LoadResource(resource[i].url)
    8 }

    三、DOM

    1. 文档对象模型(DOM)是一个语言无关的,用于操作XML和HTML文档的应用程序接口

    2. DOM和ECMAScript是两个独立的功能,当他们通过接口相互访问,就会产生消耗。访问DOM元素要被收取“过桥费”,修改元素则更为昂贵,因为它会导致浏览器重新计算页面的几何变化

    3. 使用dom方式生成html(body.appendChild)与使用innerHTML效率大致相同,在旧版本浏览器上innerHTML更胜一筹

    4. 在大多数浏览器上,克隆节点(cloneNode)比生成节点(createElement)更有效率

    5. HTML集合一直与文档保持着链接,每次访问时,都会重复执行查询的过程,哪怕只是获取集合里的元素个数。以下方法和属性会造成这种低效率情况

    1 document.getElementsByName()
    2 document.getElementsByClassName()
    3 document.getElementsByTagName()
    4 
    5 document.images
    6 document.forms
    7 document.links
    8 document.forms[0].elements

    6. 遍历元素子节点,ie下使用nextSibling比childNodes更快

     1 // nextSibling
     2 function testNextSibling() {
     3     var el = document.getElementById('father'),
     4         ch = el.firstChild,
     5         name = ''
     6 
     7     do {
     8         name = ch.nodeName
     9 
    10     } while(ch = ch.nextSibling)
    11 
    12     return name
    13 }
    14 
    15 // childNodes
    16 function testChildNodes() {
    17     var el = document.getElementById('father'),
    18         ch = el.childNodes,
    19         len = ch.length,
    20         name = ''
    21 
    22     for (var i = 0; i < len; i++) {
    23         name = ch[i].nodeName
    24     }
    25 
    26     return name
    27 }

    7. 使用原生的querySelector和querySelectorAll将比遍历获得更好的效率(ie8+)

    8. 当DOM的变化影响了几何属性(盒模型),其他元素的几何属性和位置也会因此受到影响(normal flow)。浏览器会使渲染树种受到影响的部分失效,并重新构造渲染树。这个过程称为“重排”。完成重排后,浏览器会重新绘制受到影响的部分到屏幕中,这个过程称为“重绘”。以下情况会发生重排:

    • 添加或删除可见的DOM元素
    • 元素位置改变
    • 元素盒模型改变(padding、margin、width、height、border)
    • 内容改变,如文字或图片路径
    • 页面渲染器初始化
    • 浏览器窗口尺寸改变

      有些改动会触发整个页面的重排,例如,当滚动条出现时

    9. 重排会产生计算消耗,多数浏览器会通过队列化修改并批量执行来优化重排过程。获取布局信息的操作会导致列队刷新,比如以下方法:

    • offsetTop,offsetLeft,offsetWidth,offsetHeight
    • scrollTop,scrollLeft,scrollWidth,scrollHeight
    • clientTop,clientLeft,clientWidth,clientHeight
    • getComputedStyle()

      在修改样式的过程中最好避免使用上述属性

    10. 将多次改动合并为一次,可以大幅提高效率。另一种一次性修改样式的方式是修改class属性,这种方法更利于维护和复用,虽然可能带来轻微性能影响(改变类时需要检查级联样式)

    11. 有三个方法可以使DOM脱离文档流

    • 隐藏元素,应用修改,重新显示
    • 使用文档片段,在当前DOM树外构建一个子树,再拷贝回文档
    • 将原始元素拷贝到一个脱离文档的节点中,修改副本,再替换原始元素

    12. 在IE 7-8上大范围使用hover会降低响应速度

    13. 通过事件委托可以减少事件的绑定数量,从而提升效率。通过子元素冒泡触发父元素的事件,可能更加简单和优雅

    14. 将需要大量修改的DOM节点(动画元素)设置为绝对定位,使其脱离文档流以减少影响

     

  • 相关阅读:
    Docker 国内镜像源
    SeMF安装指南
    CGI environment variables
    OpenResty + ngx_lua_waf使用
    OpenResty源码编译安装
    Ubuntu安装DVWA
    C安全编码实践
    [译]The Complete Application Security Checklist
    HTTP 安全头配置
    AWVS 10.5使用指南
  • 原文地址:https://www.cnblogs.com/sunken/p/4379495.html
Copyright © 2011-2022 走看看