zoukankan      html  css  js  c++  java
  • 《高性能JavaScript》读书笔记

    加载和执行

    • 所有的script放在</body>之前
    • 合并脚本,尽量减少script,因为每个script就是一次http请求
    • 内嵌的javascript不能放在加载CSS的link之后
    • 无阻塞脚本,使用scriptdefer属性
    • 动态创建script元素来下载并执行代码,动态创建的建议放在head里

    数据存取

    • 能用局部变量就用局部变量,因为查找作用域链越深越消耗性能
    • 若是多处使用某个全局属性,应该把全局属性赋值给一个局部
    • 对象的属性比字面量消耗性能,再多处使用某对象的属性,应该将其赋值给局部变量,若是方法则不需要,因为可能会改变内部方法的this指向
    • 尽量不要用闭包,闭包应及时释放
    • 不要使用with语句,
    • 嵌套的对象成员会影响性能,尽量少用
    • 访问字面量和局部变量的速度最快,访问数组元素和对象成员相对较慢

    DOM编程

    • 减少DOM操作
    • 计算在js完成,之后再修改DOM

    性能差的

    function innerHTMLLoop(){
        for(let count = 0; count < 15000; count++){
            document.getElementById('here').innerHTML += 'a';
        }
    }
    

    性能较好的

    function innerHTMLLoop(){
        let content = '';
        for(let count = 0; count < 15000; count++){
            content += 'a';
        }
        document.getElementById('here').innerHTML += content;
    }
    
    • 大多数情况下,节点克隆效率比创建元素高

    • HTML集合是类数组,拥有length和Index,但没有push

    • HTML集合是实时更新的,所以在遍历时,添加元素后,长度会自动发生变化

    这是一个死循环

    let alldivs = document.getElementsByTagName('div');
    for(let i = 0; i < alldivs.length; i++){
        document.body.appendChild(document.createElement('div'));
    }
    
    • HTML集合的性能是昂贵的,可以将length属性缓存,或将集合转化为真数组,不同场合考虑不同用法

    • 需要多次访问DOM属性或方法时,将其赋值给局部变量

    • 在IE中,查找DOM节点时,使用nextSibling()

    • 使用children会比childNodes效率高

    • 选择器API使用querySelectorAllquerySelector,比document.getElementById()这些更有效率,而且返回的是NodeList,这是一个类数组,而且不会实时对应文档结构

    • 较少重绘和重排

    重排和重绘

    重排是浏览器重新渲染,重绘只绘制一部分DOM元素

    触发重排的条件

    • 添加或删除可见DOM
    • 元素位置改变
    • 元素尺寸改变(包括:外边距、内边距、边框厚度、高度、宽度等属性改变)
    • 内容改变,例如文本改变或图片被另一个不同尺寸的图片改变
    • 页面渲染器初始化
    • 浏览器窗口尺寸改变

    触发重绘的条件

    例如,背景色发生变化,颜色发生变化

    在元素脱离文档流时,改变元素大小不会触发重排

    • 较少重复修改CSS样式

    性能差的

    const el = document.getElementById('mydiv');
    el.style.borderLeft = '1px';
    el.style.borderRight = '2px';
    el.style.padding = '5px';
    //发生了三次重排
    

    性能较好的

    const el = document.getElementById('mydiv');
    el.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;';
    //只会修改DOM一次
    

    使用cssText会覆盖已存在的样式信息,如果不想覆盖可以这样做

    el.style.cssText += '; border-left: 1px;';
    

    批量修改DOM

    当需要对DOM元素进行一系列操作时,可以利用以下方法,减少重绘和重排

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

    第一种方法

    给元素设置display: none,修改元素的一系列操作,元素显示display: block

    第二种方法

    const fragment = document.createDocumentFragment();
    appendDataToElement(fragment, data); // 一系列元素操作
    document.getElementById('mylist').appendChild(fragment)
    

    第三种

    const old = document.getElementById('mylist');
    const clone = old.cloneNode(true);
    appendDataToElemnet(clone, data);
    old.parentNode.replaceChild(clone, old);
    

    推荐使用第二种,因为发生的重排最少

    • 较少使用会使队列刷新的方法
    offsetTop | offsetLeft | offsetWidth | offsetHeight
    scrollTop | scrollLeft | scrollWidth | scrollHeight
    clientTop | clientLeft | clientWidth | clientHeight
    getComputedStyle() (computedStyle in IE)
    
    • 需要动画的DOM,使其脱离文档流

    使用绝对位置定位页面的动画元素,使其脱离文档流

    元素执行动画

    执行完毕,恢复位置

    • 在很长的列表或表格时,避免使用:hover

    • 能使用事件委托的就使用事件委托

    算法和流程控制

    • 较少的条件分支,使用if,较多时使用switch
    • 在遍历时,知道长度的使用for循环,不要使用for...in,不知道长度时才使用for...in
    • 循环之前,把元素长度赋值给局部变量,避免每次循环查找长度
    • 倒循环的性能比正循环要好
    • 函数迭代(forEach)性能比for循环差

    快速响应的用户界面

    用于执行js和更新用户界面的线程,称为浏览器UI线程,该线程要么执行js代码,要么执行UI更新,因此当js执行过长时,会影响UI的更新,比如点击按钮,Js执行过长时,无法看到按钮被按下的样式

    • js执行时间不要超过100毫秒,否则用户会觉得与界面失联了
    • 定时器的时间最少是25毫秒,再少由于各个浏览器的实现机制的问题,会引发其他不可预测的问题
    • 当不需要操作DOM的时候,而且是复杂的计算时,如编码/解码大字符串,复杂数学运算(包括图像或视频处理),大数组排序等,使用Worker。任何操作100毫秒的处理过程,都应该考虑Worker

    其他

    创建数组或对象时,使用字面量

    const o = {
        name: 'zhangsan'
    }
    const arr = [1, 2]
    

    运算时使用位运算,会使性能提高很多

    使用原生方法,原生方法是效率最高的方法

  • 相关阅读:
    HDU 2196 Computer (树形DP)
    HDU 4756 Install Air Conditioning (MST+树形DP)
    HDU 4126 Genghis Khan the Conqueror (树形DP+MST)
    HDU 4714 Tree2cycle (树形DP)
    HDU 1159 Common Subsequence (LCS)
    HDU 2159 FATE (二维背包)
    HDU 2602 Bone Collector (01背包DP)
    HDU 5918 Sequence I (KMP)
    关于一些逗逼函数//atoi,itoa,strtok,strupr,
    二叉树—-1(No.9HN省赛小题)
  • 原文地址:https://www.cnblogs.com/tourey-fatty/p/12828388.html
Copyright © 2011-2022 走看看