# Review
# css
# 垂直居中
display:flex; justify-content:center; align-items:center;
display:inner; text-align:center;
display:grid; justify-content:center;
display:grid; place-items:center;
position:relative; margin:auto;
position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
display:flex; margin:auto;
# BFC
overflow:hidden;
position: absolute;或者position: fixed;
display: flex;
display: grid;
# js
# event loop
同步任务(script)=>微任务(promise.then().catch()await,process.nextTick())=>宏任务(setTimeout()setInterval(),IO操作(fetch,XMLHttpRequest),UI交互事件(点击,滚动,输入))
宏任务队列和微任务队列,系统首先开始执行主线,遇到宏任务,加入到宏任务队列,遇到微任务也加入微任务队列,然后主线往下执行,直到主线执行完毕,系统会查看微任务队列中是否存在微任务,如果存在,则将所有微任务也按主线方式执行完成,然后清空微任务,开始将宏任务队列中的第一个宏任务设置为主线继续执行,直到所有的宏任务队列执行清空完成。
在 JavaScript 中,Promise、setTimeout
等任务的执行遵循 Event Loop(事件循环) 的规则。以下是宏任务(macrotasks)和微任务(microtasks)在事件循环中的执行步骤:
# 1. 任务分类
- 宏任务(Macrotask)
- Examples:
setTimeout
、setInterval
、setImmediate
(Node.js)、I/O
操作、UI 渲染。
- Examples:
- 微任务(Microtask)
- Examples:
Promise.then
、catch
、finally
、MutationObserver
、queueMicrotask
。
- Examples:
微任务的优先级高于宏任务,每次宏任务执行完成后,会优先清空微任务队列。
# 2. 执行步骤(事件循环机制)
- 执行全局代码:
- 从同步代码开始,直接依次执行,进入调用栈。
- 处理微任务:
- 同步代码执行结束后,清空当前产生的所有微任务队列。
- 执行宏任务:
- 从宏任务队列中取出一个任务执行,然后再次检查微任务。
- 重复步骤 2 和 3:
- 不断重复,直到队列为空。
console.log('1'); // 同步任务
setTimeout(() => {
console.log('3'); // 宏任务
}, 0);
logger = () => {
console.log('2'); // 普通函数,直接执行
}
async function asfn(params) {
console.log('4'); // 同步任务
await logger(); // 调用 logger() 是同步任务,但 await 会暂停后续代码并将其转成微任务
console.log('5'); // 微任务
}
asfn();
const p = new Promise((resolve, reject) => {
console.log('6'); // 同步任务
resolve('success'); // 执行 resolve,触发微任务
console.log('7'); // 同步任务
});
p.then((res) => {
console.log(res); // 微任务
});
# promise
promise是异步编程的一种解决方案 微任务
有padding进行中、 fulfilled已成功 、reject已失败三个状态
解决回调地狱 1通过链式调用.then 2多次调用async、await方法 使代码读起来像是同步的
promise本身是同步,.then.catch.finally和await这些是异步的
async和await ,async return 一个promise对象 await后面不管跟着什么 都会阻塞后面的代码 会先执行外面的同步的代码
# websocket
客户端和服务器之间建立持久连接的协议 双向实时通信
连接 => 更新数据 => beforedestory断开连接
心跳机制 一般30s~60s
一方发送PING 一方发送PONG ,指定时间没有接到PONG消息认为连接断开,重新连接或关闭
# 内存泄露
程序运行时未能释放不再使用的内存 导致内存不断被占用 从而降低性能甚至导致奔溃
未清除的定时器、事件监听器、闭包、全局变量、大型数据结构
beforedestory里去解除绑定 或者赋值为null
意外的全局变量: 无法被回收
定时器: 未被正确关闭,导致所引用的外部变量无法被释放
事件监听: 没有正确销毁 (低版本浏览器可能出现)
闭包: 会导致父级中的变量无法被释放
dom 引用: dom 元素被删除时,内存中的引用未被正确清空
# 闭包
嵌套函数被导出外部执行 函数内部的值会被保存到内存中 不被销毁
优点 延长了变量的生命周期 利用闭包访问函数中的变量
缺点 一直保存在内存中直到页面关闭 解决 在不需要的时候清除引用 不必要不使用闭包
# vue2
# keep-alive
# 介绍
keep-alive可以缓存组件的v-node
在组件反复切换的时候,去复用缓存的v-node,可以提高页面的渲染效率
可以防止组件的切换中导致组件状态变化
# 属性
# include
记录的是哪些组件可以被缓存
# exclude
哪些组件不能被缓存
# max
可以缓存组件的最大数量
还提供两个生命周期钩子函数
actived 在激活的时候 mounted之后
dectived 在失活的时候
# 实现原理
keep-alive内部保存了一个key的数组和一个组件缓存对象
# v-if和v-show
v-if是控制真实的dom渲染和摧毁 性能消耗较大
v-show是控制css的display 初始会渲染 适合经常切换的场景
# vue3
# 浏览器
# 从输入 url 到展示的过程
- DNS 解析
- TCP 三次握手
- 发送请求,分析 url,设置请求报文(头,主体)
- 服务器返回请求的文件 (html)
- 浏览器渲染
- HTML parser --> DOM Tree
- 标记化算法,进行元素状态的标记
- dom 树构建
- CSS parser --> Style Tree
- 解析 css 代码,生成样式树
- attachment --> Render Tree
- 结合 dom树 与 style树,生成渲染树
- layout: 布局
- GPU painting: 像素绘制页面
- HTML parser --> DOM Tree
# 本地存储
Cookie | localStorage | sessionStorage | indexedDB | |
---|---|---|---|---|
容量大小 | 4kb左右 | 5M左右 | 5M左右 | 无限容量 |
过期时间 | 只在设置的过期时间之前一直有效, 即使窗口或者浏览器关闭 | 始终有效 | 当前浏览器窗口关闭前有效 | 始终有效 |
存储方式 | 浏览器和服务器间来回传递 | 本地保存 | 本地保存 | 本地保存 |
作用域 | 在同源窗口中共享 | 在同源窗口中共享 | 在同源窗口并且同一窗口中共享 | 在同源窗口中共享 |
# 项目优化
# 1 资源文件方向
压缩缓存
懒加载异步加载
使用iconfont替代图标
精灵图雪碧图
img标签的loading="lazy"进入视口才加载
渐进式加载图片 先加载模糊的 加上css过渡效果高清加载完成再替换
# 2 网络请求方向
减少请求次数
检查视口高度按需发送请求
# 3 代码方向
优化代码性能 优化算法
减少dom操作 应用到虚拟dom上 最后一次性应用到dom上 缓存访问过的元素
通过async defer 异步加载文件
虚拟滚动
事件委托到父元素上
放弃js动画,用canvas动画和css动画
语法使用上 v-if,v-show .v-for-v-if
# 4 webpack
缩小代码体积 资源体积
# 5 ssr服务端渲染
使用nuxt或nextjs 优点 首屏加载快 有利于seo 缺点 服务器消耗大
# 首屏加载
减少网络请求
使用缓存
路由懒加载 图片懒加载 异步加载script标签
服务端渲染
体验 增加骨架屏 增加loading