性能优化
一、相关协议
- 输入 URL: url - 资源定位符
- http协议
- https协议
- 本地文件目录 // file:///C:/Users/class/zhaowa/document 本地文件目录地址,只在本机打开
1. http协议
追问: http 与 TCP
- http - 应用层 < = > TCP - 传输层
- 关联 http 基于 TCP实现连接 => http请求、发送、断开
- http:1.0
浏览器每次请求都与服务器建立一次TCP连接 - http:1.1
keep-alive - 保持tcp的连续畅通,不用反复的建立连接(复用同一条tcp通道) - http:2.0
多条并发请求复用同一条通路 - 复用通路(无并发限制) chrome限定了最大通路是6条
- http:1.0
- 两者差异
- http - 无状态连接
- TCP - 有状态连接
- 优化点:
- socket 连接,封装化的TCP。让我们的应用,更加方便地使用调用
- socket是长连接,可以及时通讯,服务端可以及时通知客户端
2. https协议
追问: http 和 https
-
https = http + SSl(TLS) => 位于TCP协议与各种应用层协议之间
-
实现原理 - 原理图
-
HTTPS多次连接:导致网络请求加载时间延长;增加开销和功耗
- 优化:合并请求时 - 长连接;中间层 整合请求时 - 异常处理
二、域名解析
- 浏览器缓存中 - 浏览器中会缓存DNS一段时间
- 系统缓存 - 系统中找缓存 -> HOST
- 路由器缓存 - 各级路由器缓存域名信息
- 运营商地方站点的缓存信息 - partner
- 根域名服务器
优化:CDN (Content Delivery Network)
CDN作用:
-
为同一个主机配置多个IP地址
-
负载均衡 => 缓存 => 各级缓存 => 浏览器区分缓存(强/弱缓存)
三、web服务器
- apache、ngnix
- 接收请求 => 传递给服务端代码
- 通过反向代理 => 传递给其他服务器
- 不同域名 => 指向相同ip的服务器 => ngnix域名解析 => 引导到不同的服务监听端口
四、web服务 涉及到 网络优化
- 老前端人员手写并发 - QPS
面试:并发优化 10个请求,由于后台或者业务需求只能同时执行三个
分析:
- 输入:promise数组、limit参数
- 存储:reqpool - 并发池
- 思路:塞入 + 执行
function qpsLimit(requestPipe, limitMax = 3) {
let reqPool = []
let reqMap = new Map()
// 往并发池里塞入promise
const add = () => {
let _req = requestPipe.shift()
reqPool.push(_req)
}
// 执行实际请求
const run = () => {
if(requestPipe.length === 0) return
// 池子满了发车后,直接race
let _finish = Promise.race(reqPool)
_finish.then(res => {
// 做一个id整理
let _done = reqPool.indexOf(_finish)
reqPool.splice(_done, 1)
add()
})
run()
}
while(reqPool.length < limitMax) {
add()
}
run()
}
五、浏览器渲染时
浏览器执行顺序
主线:HTML => DOM + CSSOM => renderTree + js => layout => paint
支线:repaint - 改变文本、颜色等 展示;reflow - 元素几何尺寸变了
优化点:
- 减少repaint:visibility:hidden; => repaint
- 避免reflow:display: none => reflow
六、JS脚本执行时
mark & sweep => 触达标记,锁定清空、未触达直接抹掉
// 内存分配:申明变量、函数、对象
// 内存使用:读写内存
// 内存释放
const zhaowa = {
js: {
performance: 'good',
teacher: '云隐'
}
}
// 建立引用关系
const _obj = zhaowa
// 引用源给替换掉了 - 暂未gc 垃圾回收
zhaowa = 'best'
// 深入层级做引用 - 暂未gc
const _class = _obj.js
// 引用方替换 - 暂未gc
_obj = 'over'
// gc 完成
_class = null
1. 垃圾回收
垃圾回收 (GC) 是一种自动内存管理形式。垃圾收集器,或只是收集器,尝试回收垃圾,或由程序不再使用的对象占用的内存。自动查找是否“不再需要”某些内存的一般问题是无法确定的。结果,垃圾收集器对一般问题的解决方案实施了限制。
垃圾收集算法依赖的主要概念是引用的概念。在内存管理的上下文中,如果一个对象可以访问另一个对象(隐式或显式),则称该对象引用另一个对象。
- 内存分配:申明变量、函数、对象
- 内存使用:读写内存
- 内存释放
2. 脚本执行注意点
-
对象层级,宜平不宜深
-
深层引用最好深拷贝,或者用完直接销毁
-
避免循环引用
3. 内存泄露
-
莫名其妙的全局变量
function foo() { bar1 = '' this.bar2 = '' }
-
未清理的定时器
setInterval(() => { }, 1000)
-
使用后的闭包
function zhaowa() { const _no = 1 return { number: _no } }
七、打包配置优化
- 懒加载 - 非必要不加载
- 按需引入 - 非必要不引入
- 抽离公共 - 相同项目合并公用