欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

高性能js-笔记

程序员文章站 2022-06-29 08:10:17
高性能js-笔记 1. 加载和执行 当遇到script标签时,会停止处理页面,先执行js代码,然后再继续解析和渲染页面。 使用src加载js的过程中,浏览器必须先花时间下载外链...

高性能js-笔记

1. 加载和执行

当遇到script标签时,会停止处理页面,先执行js代码,然后再继续解析和渲染页面。 使用src加载js的过程中,浏览器必须先花时间下载外链文件中的代码,然后解析并执行,在这过程中,页面渲染和用户交互是阻塞的。 js下载和执行会阻塞其它资源的下载,比如图片 逐步加载js文件,不会阻塞浏览器,秘诀在于,在页面加载完成之后才加载js代码,这意味着window的load事件出发后再下载脚本

延迟脚本

1.defer
当一个带有defer属性的js文件下载时,不会阻塞浏览器的其它进程,因此与其它资源并行下载。
<script defer="defer" src="./defer.js"></script>//alert('defer')
<script>
    alert('script')
</script>
<script>
    alert('1')
</script>
<script>
    window.onload=function() {
        alert('load')
    }
</script>
结果为: script 1 defer load

注意:
defer在src外链js时才起作用,js脚本的执行需要等到文档所有元素解析完成之后,load事件触发执行之前。
多个defer的文件,加载完顺序执行;多个async文件,哪个先加载完执行哪个

2.动态脚本元素
function loadscript(url, callback) {
    var script = document.createelement('script');
    script.type = "text/javascript";
    if(script.readystate) {//ie
        script.onreadystatechange = function() {
            if(script.readystate === 'complete' || script.readystate === 'loaded') {
                script.onreadystatechange = null;
                callback()
            }
        }
    }else {//其他浏览器
        script.onload = function() {
            callback()
        }
    }
    script.src = url;
    document.getelementsbytagname('head')[0].appendchild(script);
}

文件在该元素被添加到页面时开始下载,文件的下载和执行过程不会阻塞页面其他进程

3.ajax注入
var xhr = new xmlhttprequest();;
xhr.open('get','./defer.js',true);
xhr.onreadystatechange = function() {
    if(xhr.readystate == 4) {
        if(xhr.status >= 200 && xhr.status <300 || xhr.status == 304) {
            var script = document.createelement('script');
script.type = "text/javascript";
script.text = xhr.responsetext;
document.getelementsbytagname('head')[0].appendchild(script);
        }
    }
}
xhr.send(null)

优化准则

将脚本放在底部,之前 减少页面中外链脚本的数量

2. 数据存取

管理作用域

内部属性[[scope]]包含了一个函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链

执行函数时会创建一个执行环境,它的作用域链初始化为当前运行函数的[[scope]]属性中的对象。这些值按照它们出现在函数中的顺序,被复制到执行环境的作用域链中,这个过程完成一个活动对象就为执行环境创建好了。执行过程中,每遇到一个变量,都会经历一次标识符解析过程以决定从哪里获取或存取数据。当函数执行完毕时,执行环境就被销毁

全局变量总是存在于执行环境作用域链的最末端,可以用局部变量代替全局变量

最好避免使用with语句,因为延长作用域链后访问局部变量将变慢。对于try-catch推荐将错误委托给一个函数处理
try{
    method();
}catch(ex) {
    handleerror(ex)
}
闭包性能问题:
function assignevent(){
    var id = "xdi9592";
    document.getelementbyid('save-btn').onclick=function(){
    savedocument(id);
}
}

当assignevent函数执行时,一个包含了变量id以及其他数据的活动对象被创建。它成为执行环境作用域链中的第一个对象,而全局对象紧随其后。这个活动对象无法在assignevent执行后被销毁,因为闭包也引用了它。当闭包执行时会创建一个执行环境,又一个活动对象为闭包自身所创建。

对象成员包括属性和方法。 对象成员搜索会消耗性能