- 浏览器渲染进程的线程有哪些?
- 僵尸进程和孤儿进程是什么?
- 如何实现浏览器内多个标签页之间的通信?
- 对浏览器的缓存机制的理解
- 协商缓存和强缓存的区别
- 点击刷新按钮或者按 F5、按 Ctrl+F5(强制刷新)地址栏回车有什么区别?
- 常见的浏览器内核比较
- 浏览器的渲染过程
- 渲染过程中遇到 JS 文件如何处理?
- 前端储存的方式有哪些?
- 事件是什么?事件模型?
- 对事件循环的理解
- 垃圾回收机制
- 跨域解决方案
从用户输入网址到客户端展示,发生了什么事情
DNS解析
- 浏览器请求域名,通过DNS服务器解析为对应的IP,返回给浏览器
- 浏览器再把IP和参数打在协议上发送给服务器
TCP连接
三次握手
- 浏览器告诉服务器,我要发送请求了
- 服务器告诉浏览器,我准备接受了
- 浏览器告诉服务器,我马上就发了,准备接收吧
三次握手的原因:为了防止已失效的连接请求报文又传到了服务端,因而产生错误
四次挥手
- 发送http请求(ajax、axios)
- 服务器处理请求并返回http报文
- 浏览器解析渲染页面
- 连接结束
Event Loop
不同的任务源会被分配到不同的 Task 队列中,任务源可以分为 微任务(microtask) 和 宏任务(macrotask)。在 ES6 规范中,microtask 称为 jobs
,macrotask 称为 task
。下面来看以下代码的执行顺序:
console.log('script start')
async function async1() {
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2 end')
}
async1()
setTimeout(function() {
console.log('setTimeout')
}, 0)
new Promise(resolve => {
console.log('Promise')
resolve()
})
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')
})
console.log('script end')
// script start => async2 end => Promise => script end => async1 end => promise1 => promise2 => setTimeout
Event Loop 执行顺序如下所示
- 首先执行同步代码,这属于宏任务
- 当执行完所有同步代码后,执行栈为空,查询是否有异步代码需要执行
- 执行所有微任务
- 当执行完所有微任务后,如有必要会渲染页面
- 然后开始下一轮 Event Loop,执行宏任务中的异步代码,也就是
setTimeout
中的回调函数
微任务包括 process.nextTick
,promise
,MutationObserver
。
宏任务包括 script
, setTimeout
,setInterval
,setImmediate
,I/O
,UI rendering
备注:这里很多人会有个误区,认为微任务快于宏任务,其实是错误的。因为宏任务中包括了 script
,浏览器会先执行一个宏任务,接下来有异步代码的话才会先执行微任务
垃圾回收机制
垃圾回收(Garbage Collection)是一种自动管理内存的机制,其主要目的是在程序运行过程中自动释放不再被使用的内存,以便重新利用。
垃圾回收的原理
- 标记-清除(Mark and Sweep): 这是最常见的垃圾回收算法之一。它通过标记不再使用的对象,然后清除它们来回收内存。垃圾回收器首先会从根对象(通常是全局对象或执行栈)开始,标记所有能够访问到的对象,然后遍历堆中的所有对象,将未标记的对象视为垃圾并进行清除。
- 引用计数(Reference Counting): 这种方法会为每个对象维护一个引用计数,当引用计数为零时,表示该对象不再被使用,可以进行回收。然而,引用计数容易出现循环引用的问题,导致内存泄漏,因此在实践中并不常用。
垃圾回收的触发时机
- 定时触发
- 空闲时触发
缓存机制
- 缓存位置
- Service Worker
- Memory Cache
- Disk Cache
- Push Cache
- 网络请求
-
缓存策略
强缓存和协商缓存,并且缓存策略都是通过设置 HTTP Header 来实现的。
-
实际场景应用缓存策略