生成器函数:是一个带星号函数,是可以暂停执行和恢复执行的
执行器:执行生成器函数的函数,则成为执行器
携程: 是一种比线程更加轻量级的存在,
- 一个线程上可以存在多个协程,但是同时只能执行一个协程,因此要在协程之间进行切换
- 如果从 A 协程启动 B 协程,我们就把 A 协程称为 B 协程的父协程
function* genDemo() {
console.log("开始执行第一段");
yield 'generator 1';// 遇到yield 关键字,JavaScript 引擎会暂停该函数的执行,并将关键字后面的内容返回给外部,外部函数可以通过next()恢复继续执行
console.log("开始执行第二段");
yield 'generator 2;
}
console.log('main 0')
let gen = genDemo(); //创建了一个gen协程,但是并没有执行
console.log(gen.next().value) ; //generator 1
console.log('main 1')
console.log(gen.next().value); //generator 2
console.log('main 2')
2. 事件循环机制
参考文档https://www.jianshu.com/p/12b9f73c5a4f/,这个应该是讲得比较详细的
栈的概念理解(3种):
- 一段代码的运行环境,后进先出(执行上下文栈)
- 存放数据的一种内存区域,栈空间、堆空间
栈空间是有结构的,每个区块按照一定次序存放
堆空间没有结构的,数据可以任意存放。
栈空间的寻址速度要快于堆空间 - 可执行代码执行方式,执行栈(调用栈),先进先出
事件循环执行过程:
setTimeout(function () {
console.log('timeout1');
},0)
new Promise(function (resolve) {
console.log('promise1');
resolve(100)
}).then(() => {
console.log('then1');
})
new Promise(function (resolve) {
console.log('promise2');
resolve(200)
}).then(() => {
console.log('then2');
})
setTimeout(function () {
console.log('timeout2');
},0)
console.log('global1');
- 第一步,开始执行Javascript脚本,进入宏任务队列,因为只有一个script(整体代码)任务,直接开始执行
- 第二步,遇到setTimeout,setTimeout为一个宏任务,异步处理,等待时机成熟(100ms之后),timeout1加入宏任务队列
- 第三步,遇到Promise,Promise本身是同步任务,promise1, resolve(100),立即放到执行栈( 按顺序执行 ),
then才是回调异步函数,异步处理,处理完成后,then1加入微任务队列(异步任务执行加入微任务队中的时间是任务异步处理完成的时间顺序,不是在代码中的上下位置顺序) - 第四部,遇到第二个Promise,promise2, resolve(200),立即加入执行栈,
then2加入微任务队列 - 第五步,遇到第二个setTimeout,timeout2加入宏任务队列
- 至此,调用栈为空,Javascript宏任务中的同步任务函数全部执行完毕
- 第六步,然后去微任务队列查看可执行的微任务,then1加入执行栈执行,执行完成,执行栈为空,再去微任务队列查看可执行的微任务,加入执行栈执行,反复循环,直到微任务队列为空
- 第七步,查看宏任务队列可执行宏任务,timeout2执行完成时间早于timeout,因此先进入执行栈执行,反复循环,直到宏任务任务队列为空
- 任务全部执行完毕,调用栈为空
页面的生命周期:
- 加载阶段
- 更新阶段(交互阶段)
- 销毁阶段
从页面的生命周期方向思考:
1. 加载阶段:如何让页面渲染快?关键资源(核心资源):阻塞页面首次渲染的资源称为页面的关键资源,HTML、CSS、Javascript
- 减少关键资源个数,减少请求次数
- 减小关键资源大小,提高资源加载速度
- 传输关键资源需要多少个 RTT(Round Trip Time)
--TCP协议传输资源时,是将资源分成一个个数据包(一般为14KB 左右),来回多次进行传输
--RTT ,是指客户端开始发送数据开始,到收到服务器端接收确认信息所经历的时间
具体优化方法:
(1)压缩HTML文件,移除 不必要注释
(2)合并并压缩CSS 、JavaScript等文件 ,script 标签加上 async 或 defer属性
(3)避免使用table布局
(4)缓存(第二次请求命中缓存则直接读取缓存)
目标是减少页面渲染过程的重排、重绘
具体优化方法:
(1)减少DOM操作,将多次操作DOM合并为一次,如插入元素节点
(2)减少逐项更改样式,最好一次性更改style,或者将样式定义为class并一次性更新
(3)前端框架Vue、React(虚拟DOM和Diff算法等)
(3)避免多次读取offset等属性,使用变量做缓存
(4)防抖、节流
(5)做动画效果时,使用will-change和transform 做优化
- 多次
- 首次加载时,先创建虚拟DOM树,
- 再根据虚拟DOM树创建真实的DOM树,然后继续一系列渲染流水线工作
- 如果数据发生了改变,再创建一棵新的虚拟DOM树
- 两棵虚拟DOM树对比,计算出最少变化
- 把所有变化记录一次性更新到真实DOM树上,然后继续一系列渲染流水线工作
引入虚拟DOM树执行流程.png
五、浏览器中安全同源策略:协议、域名、端口三者都相同则称为同源1. XSS 攻击:跨站脚本攻击(Cross Site Scripting)XSS 攻击是指黑客往 HTML 文件中或者 DOM 中注入恶意 JavaScript 脚本,在用户浏览页面用户实施攻击的一种手段
(1)风险:- 窃取用户Cookie信息
-- 通过document.cookie获取用户Cookie 信息,发送到恶意服务器
-- 恶意服务器拿到用户的 Cookie 信息之后,就可以模拟用户的登录,进行转账等操作 - 监听用户行为
-- 通过addEventListener来监听键盘事件,获取用户账号、密码、信用卡等信息, 发送到恶意服务器
-- 恶意服务器拿拿到这些信息,又可以做很多违法的事情 - 生成广告等影响用户体验
- 对输入脚本进行过滤或转码
如:<script> --><script>
- 响应头Set-Cookie加使用限制
-- httpOnly,通知浏览器此 Cookie 只能通过浏览器 HTTP 协议传输,浏览器的 JS 引擎就会禁用 document.cookie;
-- SameSite=Strict,限制此Cookie不能随着跳转链接跨站发送
目的是利用服务器的漏洞和用户的登录状态来实施攻击
发起CSRF攻击的方式:
- 通过<img src="恶意网站">,自动跳转到恶意网站
- 通过诱导用户点击隐藏链接,指向恶意网站
解决方法:
-- SameSite=Strict,限制此Cookie不能随着跳转链接跨站发送
-- 验证请求来源站点
-- 使用Token验证
服务器第一次返回时生成一个Token
再次请求客户端带着对应的Token,进行验证