一、闭包(Closure)
闭包,没有明确的定义,每个人的理解都不一样。
MDN上面这样说的:闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。
简单来说,闭包就是指有权访问另一个函数作用域中的变量的函数。
产生一个闭包
创建闭包最常见的方式,就是在一个函数内部创建另一个函数。
function func(){
var a = 1,b = 2;
function closure(){
return a+b;
}
return closure;
}
闭包的作用域链包含着它自己的作用域,以及包含它的函数的作用域和全局作用域。
匿名函数最大的用途是创建闭包,并且还可以构建命名空间,以减少全局变量的使用。从而使用闭包模块化代码,减少全局变量的污染。
按照我的理解 JavaScript 里面所有的函数都是闭包,因为有全局环境,所有的函数都可以访问全局变量。
一个闭包计算器
var countNumber = (function(){
var num = 0;
return function(){
return ++num;
};
})();
一个闭包面试题
function fun(n,o){
console.log(o);
return {
fun: function(m){
return fun(m,n);
}
};
}
var a = fun(0); // ?
a.fun(1); // ?
a.fun(2); // ?
a.fun(3); // ?
var b = fun(0).fun(1).fun(2).fun(3); // ?
var c = fun(0).fun(1); // ?
c.fun(2); // ?
c.fun(3); // ?
undefined 0 0 0 undefined 0 1 2 undefined 0 1 1
二、函数的防抖(debounce)
- 任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。
function debounce(fn, wait) {
let timeout = null;
return function() {
if(timeout!==null) clearTimeout(timeout);
timeout = setTimeout(() => {
fn.call(this, arguments);
}, wait);
};
}
三、函数的节流(throttle)
- 指定时间间隔内只会执行一次任务。
function throttle(fn, wait) {
let canRun = true;
return function() {
if(!canRun) return;
setTimeout( () => {
fn.call(this, arguments);
canRun = true;
}, wait);
};
}
四、重绘(repaint)与回流(reflow)
- 重绘:当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要UI层面的重新像素绘制,因此损耗较小。 常见的重绘有:
- color
- background
- 等
- 回流:当元素的尺寸、结构或者触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。 -常见的回流有:
- 页面初次渲染
- 浏览器窗口大小gaibai
- 元素尺寸/位置/内容发生改变
- 元素字体大小变化
- 添加或删除可见的DOM
- 激活css伪类
回流必定重绘,重绘不一定回流。重绘开销小,回流开销大。
- 总结:
- 避免频繁操作样式,可汇总后统一一次修改
- 尽量使用class进行样式修改,而 不是直接操作样式
- 减少dom操作
五、浏览器解析URL
- 用户输入URL地址。
- 对URL进行DNS域名解析(ip直接跳过)
- 建立TCP连接(三次握手)
- 浏览器发起http请求报文
- 服务器返回http请求报文
- 关闭tcp连接(四次挥手)
- 浏览器解析文档资源并渲染页面
三次握手 客户端:“喂,你听得到吗?” 服务端:“我听得到呀,你听得到我吗?” 客户端:“我能听到你,今天balabala……”
四次挥手 客户端:“你好,我这边没有数据要传了,我要关闭咯。” 服务端:“收到~我看一下我这边有没数据要传的。” 服务端:“我这边也没有数据要传啦,我们可以关闭连接咯~” 客户端:”ojbk~“
六、性能优化
web性能优化主要包括
- 度量标准
- 编码优化
- 静态资源优化
- 交付优化
- 构建优化
- 性能监控
度量标准
- 首次有效绘制 当主要内容呈现在页面上
- 英雄渲染时间 当用户最关心的内容渲染完成
- 可交互时间 基本上用户可以点击UI并与其交互
- 输入响应 界面响应用户输入所需的时间
- 感知速度指数 测量填充页面内容的速度。 分数越低越好
- 自定义
编码优化
- 数据读取速度
- 字面量与局部变量的访问速度最快,数组元素和对象成员相对较慢
- 变量从局部作用域到全局作用域的搜索过程越长速度越慢
- 对象嵌套的越深,读取速度就越慢
- 对象在原型链中存在的位置越深,找到它的速度就越慢
- DOM 减少dom操作
- 流程控制 if-else 没有switch快 for in 因为能枚举到原型慢 forEach同理
静态资源优化
- 文本文件压缩
- 图片压缩
交付优化
- 懒加载视频、图片等
构建优化
其他
css选择器的使用,
- 保持简单,不要使用嵌套过多过于复杂的选择器。
- 通配符和属性选择器效率最低,需要匹配的元素最多,尽量避免使用。
- 不要使用类选择器和ID选择器修饰元素标签,如h3#markdown-content,这样多此一举,还会降低效率。
- 不要为了追求速度而放弃可读性与可维护性。