美文网首页
《高性能JavaScript》第1-3章

《高性能JavaScript》第1-3章

作者: 前端艾希 | 来源:发表于2021-05-30 19:22 被阅读0次

    一、加载和执行

    1.1 脚本位置

    HTML4规范指出script标签可以被放在文档中的headbody

    尽管如今大部分浏览器允许脚本并行下载,脚本和脚本之间相互不会阻塞,但是脚本仍旧会阻塞其他资源的下载,例如图片或者样式文件等,所以我们应该讲脚本放在body的最后进行加载。

    1.2 脚本的组织

    下载4个25kb脚本的时间要大于下载1个100kb脚本的时间,因为建立http连接是需要开销的,所以我们应当尽量减少引入过多script标签,可以将多个脚本打包到一起。

    1.3 延迟脚本

    HTML4规范为script标签定义了一个扩展属性:defer;在HTML5规范又扩展了async属性。

    • defer,使用defer属性的脚本不会阻塞其他资源的下载,并且会在页面完成后再执行(document.onload之后,window.onload之前)。
    • async,使用async属性的脚本不会阻塞其他资源下载,但是它会在脚本下载后立即执行,脚本执行时也会阻塞页面渲染。

    1.4 动态脚本

    在解析html文档时,我们可以向head标签里插入script标签,这样做的好处是不管什么时候下载该脚本都不会阻塞页面的其他进程。代码如下:

    var script = document.creatElement("script");
    script.type = "text/javascript";
    
    script.onload = function () {
        alert("script loaded")
    }
    script.src = "http://xxx.js";
    document.getElementByTagName("head")[0].appendChild(scirpt);
    

    1.5 Xhr脚本注入

    我们前面讲过script的下载和执行都是同步阻塞的,那如果我们把它变成异步的,不久解决加载时阻塞问题了么。说到异步,我们最熟悉的就是ajax了,我们可以使用ajax异步下载脚本,然后再将脚本写入html文档中;

    二、数据存取

    2.1 作用域链

    函数作用域决定了哪些变量能在函数内被访问到,当一个函数被声明的时候,函数的作用域链[[scope]]就被创建了,链表的头节点是当前函数的作用域,第二个节点是函数外部作用域...以此类推。当函数执行时,会创建一个执行环境的对象,执行环境的作用域链初始化为当前函数的[[scope]]

    2.2 改变作用域链

    evalwithtry,catch会改变作用域链。

    2.3 标识符解析性能

    • 局部变量 > 全局变量,函数内查找变量是基于作用域链查找的,函数局部变量在作用域链的最前方,所以最快。
    • 字面量 > 对象,查找对象属性值时会基于对象的原型链查找,所以会慢与字面量变量,因此如果我们对一个对象上的某个属性有多次访问,那么我们应该讲该属性的值缓存在局部变量中。

    三、DOM编程

    3.1 天生就慢

    在浏览器中,JavaScript引擎和DOM是独立实现的,即JavaScript不能直接访问到DOM对象的内容,必须通过浏览器提供的接口,因为有了这一层中间代理,所以DOM操作自然就慢了。

    3.2 DOM访问与修改

      1. 尽量减少对dom的访问以及操作,重复的访问应当被缓存,dom操作也可以缓存后进行diff之后在操作。
      1. 在老的浏览器中,innerHTML属性比使用dom方法更快,但是新浏览器中相差无几,不过使用innerHTML会让代码更简洁。
      1. element.cloneNodedocument.createElment更高效。
      1. html集合也是实时更新的,代码里每次访问,都会造成重复的查询,比如document.forms,这种操作也是需要缓存的。
      1. 在老版本浏览器中遍历子节点时,nextSiblingchildNodes更高效。
      1. 浏览器会把reflow操作缓存在队列中按计划执行,但是如果我们调用了获取dom样式属性时,会打破浏览器的计划,让reflow立即执行 。
      1. 使用选择器apiquerySelectorAll效率更高。

    3.3 最小化重绘和重排

    改变样式可以使用cssText属性,例如:el.style.cssText += "; width: 100px; height: 100px;"

    3.4 批量修改DOM

    当我们要对一个dom节点进行批量操作(例如:批量插入一些节点)时,我们可以通过以下步骤减少重排和重绘次数:

      1. 使元素脱离文档流;
      1. 对其进行批量操作;
      1. 将元素带回文档流;

    参考文献

    [1] 高性能JavaScript Nicolas C. Zakas 著

    相关文章

      网友评论

          本文标题:《高性能JavaScript》第1-3章

          本文链接:https://www.haomeiwen.com/subject/eflmsltx.html