「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战」
变量读取速度
作用域链和读取速度
1、链式查找经历层级越多,则越慢。因此局部变量速度会优于全局变量
var a = 1;
function foo() {
var b = 2;
console.log(a); // a的读取速度慢
console.log(b); // b的读取速度快
}
2、动态作用域(eval、with、try()catch(e){})
// js引擎会在编译阶段,确定变量的使用位置,用标识符索引方法代替链式查找
// 而动态作用域没办法做这种优化
var a = 1;
function foo() {
eval('var a = 2');
console.log(a) // 2
}
var obj = {
a: 2
}
with(obj) {
console.log(a) // 2
}
原型链和读取速度
原型链是逐层查找,则越深查找速度越慢
var obj = {
a: 1,
b: {
c: 2
}
}
console.log(obj.a); // 速度快
console.log(obj.b.c); // 速度慢
// 优化方法,用局部变量保存,减少读取时间
function foo() {
const c = obj.b.c;
// 之后使用c
}
DOM操作
渲染引擎和js引擎之间切换是非常消耗性能
优化策略:
- 大量更新HTML可用innerHTML、outerHTML
- 用变量保存节点,后续操作变量
- 使用querySelector("#menu a")和querySelectorAll("div.warning, div.notice")更快的获取想要的节点
每次渲染时经历,重排(回流)和重绘,消耗性能
DOM树 + CSS数 = 渲染树(没有隐藏节点)
重排(回流):dom几何属性或者位置变化
重绘:颜色等变化
优化策略:
1、简单样式修改
el.style.cssText += "border-left: 1px; border-right: 2px; padding: 5px";
// 或者直接切换class名
2、批量操作dom(但是太大批量的操作,会导致页面卡顿,如:长列表。因地制宜)
- 使元素脱离文档流
- 对其应用多重改变
- 把元素带回文档中
实施方法:
(1)隐藏元素,修改,重新显示
(2)文档碎片createDocumentFragment(),创建子树,再拷贝回文档**(最实用)**
(3)把元素拷贝到一个脱离文档的节点,修改,再替换回去
事件委托
- 事件捕获
- 到达目标
- 事件冒泡
多节点需要绑定同样事件,如:列表点击事件
// 避免给每个元素都绑定事件
odiv.onclick = function(e) { //odiv是父元素
e.target || e.srcElement // target是真实点击到的元素
// 通过判断e.target执行不同的操作
}
使用防抖和节流
利用事件循环,避免页面卡顿
算法上的优化
条件语句
- 尽量把概率更大的放在前面。
- 合理使用二分法。
if (value < 6) {
if (value < 3) {
// 0 1 2
} else if (value >= 3) {
// 3 4 5
}
} else if (value >= 6) {
}
- 大量离散值,可用查找表,内容放在Object、Array中
- 递归调用栈,参考合并排序和尾调
合理利用缓存
- 避免函数的重复执行
- 较少HTTP请求,合理利用HTTP