协议
URL:url - 资源定位符
三种
1. http://
追问:http和tcp
2. https://
3. file:///c:/User 本地文件地址,只在本机打开
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是长连接,可以及时通讯,服务端可以及时通知客户端
https://
追问:http和https
- https是什么? https = http + ssl(TLS) 位于TCP协议与各种应用层协议之间
- 原理: 加密逻辑
3. HTTPS多次连接:导致网络请求加载时间延长,增加开销和功耗 优化: => 和并请求和长连接
中间层 整合请求时 - 异常处理
域名解析
- 浏览器缓存中 - 浏览器中会缓存DNS一段时间
- 系统缓存 - 系统中找缓存 -> HOST
- 路由器缓存 - 各级路由器缓存域名信息
- 运营商地方站点的缓存信息 - partner
- 根域名服务器
优化:CDN - Content Delivery Network
作用:
- 给同一个主机配置多个IP地址
- 负载均衡 => 缓存 => 各级缓存 => 浏览器区分缓存(强缓存 弱缓存)
web服务器
apache ngnix
- 接收请求 => 传递给服务端代码
- 通过反向代理 => 传递给其他服务器
- 不同的域名 => 指向相同ip的服务器 => ngnix域名解析 => 引导到不同的服务监听端口
服务 涉及到网络优化
手写并发 QPS
面试:并发优化 10个请求,由于后台或者业务需求,只能同时执行三个
分析:
- 输入:promise数组,limit参数
- 存储:reqpool - 并发池
- 思路:塞入+执行
function qpsLimit(requestPipe, limitMax) {
let reqPool = []
let reqMap = new Map()
// 往并发池里塞入promise
const add = () => {
// shift: 把数组的第一个元素从其中删除,并返回第一个元素的值
let _req = requestPipe.shift();
reqPool.push(_req)
}
// 执行实际请求
const run = () => {
if (requestPipe.length === 0) return;
// 池子满了发车后,直接race,但凡有一个请求完成
let _finish = Promsie.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 避免reflow
display:none => reflow
visibility:hidden => repaint
脚本执行时 - 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
垃圾回收
- 内存分配:申明变量、函数、对象
- 内存使用:读写内存
- 内存释放
注意点:
- 对象层级,宜平不宜深
- 深层引用最好深拷贝,或者用完直接销毁
- 避免循环引用
内存泄漏
- 全局变量
function foo() {
bar1 = ''
this.bar2 = ''
}
- 未清理的定时器
setInterval(() => {}, 1000)
- 使用后的闭包
function zhaowa() {
const _no = 1
return {
number: _no
}
}
打包配置优化
- 懒加载
- 按需加载
- 抽离公共