性能优化
一、从url输入到页面展示发生了什么
- 输入
URL :url - 资源定位符
www.baidu.com - http协议
http与TCP
- http是应用层协议,TCP是传输层协议
- http基于TCP进行实现连接,http发请求时会建立对接服务器的通道并且发送请求,发送请求结束之后会断开这个连接。建立,发送,断开的实际上是一个TCP连接
-
优化点 :1.0 1.1 2.0
1.1开始http添加了keep-alive 可以保持TCP的连续畅通,不用反复地建立连接 2.0 多条并发请求复用同一条通路 - 复用通路,无并发限制
- http是无状态的连接,TCP是有状态的
-
优化点:
socket连接:封装化的TCP,让我们的应用更加方便地使用调用
www.baidu.com - https协议
http和https
- https = http + SSL(TLS)位于TCP协议与各种应用层协议之间
- 实现原理
- HTTPS多次连接会导致网络请求加载时间延长;增加开销和功耗
- 优化点:合并请求 长连接
file:///C:/Users/xxx 本地文件目录地址,只在本机打开
- 域名解析
-
浏览器缓存中 - 浏览器中会缓存DNS一段时间
-
系统缓存 - 系统中找缓存 ,系统中没有就去 host找
-
路由器缓存 - 各级路由器缓存域名信息
-
运营商地方站点的缓存信息
-
根域名服务器
-
优化:CDN
CDN - Content Delivery Network
- 为同一个主机配置多个IP地址
- LB - 负载均衡
-
- web服务器
- 接收请求,传递给服务端代码
- 通过反向代理传递给其他服务器
- 不同域名,解析指向相同ip的服务器 => nginx域名解析 =>引导到不同的服务监听端口
服务 涉及到网络优化
- 并发 - QPS
//并发优化 10个请求,只能同时执行三个
//分析
//输入:promise数组;limit参数
//存储:reqpool - 并发池
//思路:塞入 + 执行
function qpsLimit(requestPipe,limitMax = 3){
let reqPool = [];
let reqMap = new Map();
//往并发池里加入promise
const add = () =>{
let item = requestPipe.shift()
reqPool.push(item);
}
//执行实际请求
const run =() =>{
if(requestPipe.length === 0 ) return
//池子满了发车后,直接race
let _finish = Promise.race(reqPool)
_finish.then(res=>{
let _done = reqPool.indexOf(_finish)
reqPool.splice(_done,1)
add()
})
}
while(reqPool.length < limitMax){
add()
}
run()
}
浏览器渲染时
- 浏览器执行顺序
主线:HTML => DOM + CSSOM => renderTree + js => layout => paint 支线: repaint:改变文本颜色等展示 reflow:元素集合尺寸变了
- 优化点:减少repaint,避免reflow display:none => reflow; visibility:hiden; =>repaint
执行脚本时 - JS
垃圾回收机制:mark & sweep => 触达标记,锁定清空、未触达直接抹掉
内存分配:申明变量、函数、对象
内存使用:读写内存
内存释放:mark & sweep
- 对象层级宜平不宜深
- 深层引用最好深拷贝,或者用完直接销毁
- 避免循环引用
内存泄漏
1. 莫名其妙的全局变量
2. 未清理的定时器
3. 使用后的闭包
打包配置优化
- 懒加载 - 非必要不加载
- 按需引入 - 非必要不引入
- 抽离公共 - 相同项目合并公用