1、从输入url到浏览器呈现页面中间经历了什么?
-
在输入url的时候,会进行本地历史记录和标签页的查询,提供模糊查询效果
-
浏览器查找当前URL是否存在缓存,并比较缓存是否过期 HTTP缓存有多种规则,根据是否需要向服务器重新发起请求来分类,将其分为强制缓存,对比缓存。 强制缓存:判断HTTP首部字段:Expires 和 cache-control。 Expires是一个绝对时间,即服务器时间。浏览器检查当前时间,如果还没到失效时间就直接使用缓存文件。但是该方法存在一个问题:服务器时间与客户端时间可能不一致 cache-control中的max-age保存了一个相对时间。例如Cache-Control: max-age = 484200,表示浏览器收到文件后,缓存在484200s内有效。 如果同时存在cache-control和Expires,浏览器总是优先使用cache-control。 对比缓存:通过HTTP的 last-modified(最新-改进),Etag字段进行判断。 last-modified 表示请求的URL(资源)最后一次更新的时间。下一次浏览器请求资源时就发送if-modified-since字段。服务器用本地Last-modified时间与if-modified-since时间比较,如果不一致则认为缓存已过期并返回新资源给浏览器;如果时间一致则发送304状态码,让浏览器继续使用缓存。 Etag:资源的实体标识(哈希字符串),当资源内容更新时,Etag会改变。服务器会判断Etag是否发生变化,如果变化则返回新资源,否则返回304。
-
DNS解析URL对应的IP 首先查询本地host文件是否有对应地址的一个映射关系,如果没有找到,会查找本地DNS解析器缓存,如果还是没有找到则会查找本地DNS服务器,最后迭代查询,按根域服务器库(.com,.cn,.vip,.top...)->顶级域(com)->->第二层域子域(baidu.com),最后根据baidu.com的域名找到相应的IP,返回给浏览器。
-
根据IP建立TCP连接(三次握手) 浏览器用这个IP地址与服务器建立TCP连接,如果用的是HTTPS,还有完成TLS / SSL的握手。 第一次握手: 建立连接时,客户端发送syn包(syn=j)到服务器,并进入等待服务器确认的状态; 第二次握手: 服务器收到syn包,必须确认客户端的syn(ack=j+1),同时自己根据syn生成一个ACK包,此时服务器进入等待状态; 第三次握手: 客户端收到服务器的ACK包,向服务器发送确认,此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
-
发送HTTP请求 在建立好连接以后呢,构造HTTP请求,在构造请求的过程中,要填充少量至HTTP头部
-
服务器解析请求返回结果 然后通过这个TCP连接发起HTTP请求,当服务器收到这个HTTP请求以后,返回给浏览器以HTTP页面作为包体的HTTP响应。
-
浏览器解析结果并渲染页面 根据html代码生成DOM树 ,在解析到外部的css和js文件时,向服务器发起请求下载资源,如果是CSS代码会在下载的同时进行解析,如果是JS代码会阻塞页面加载,根据CSS代码生成OM树,然后生成layout树(重排),生成painting树(重绘),然后生成渲染树。
-
关闭TCP连接(四次挥手) 第一次握手是浏览器发完数据,然后发送FIN请求断开连接。 第二次握手是服务器向客户端发送ACK,表示同意。 第三次握手是服务器可能还有数据向浏览器发送,所以向浏览器发送ACK同时也发送FIN请求,是第三次握手。 第四次握手是浏览器接受返回的ACK,表示数据传输完成。
相关链接: 输入url至呈现页面过程 三次握手 四次挥手
2、js基本数据类型
Number、String、Boolean、undefined、object、symbol、bigInt、Null js基本数据类型
3、typeof返回类型
number、 string、boolean、 undefined、object、symbol、bigint、function typeof NaN == 'number'
4、最大安全值和最大值
Number.MAX_SAFE_INTEGER 进行运算不会丢失精度 Numebr.MAX_VALUE js能表示的最大值
5、this的绑定规则
显示绑定 call、apply、bind 隐式绑定 obj对象的属性为函数时,内部指向obj 默认绑定 函数内部的this默认指向window new绑定 this的绑定规则
6、call、bind、apply
改变this指向的方法 call参数为列表、apply为数组、立即执行 bind为等待状态
Math.max.call(null, 1,3,5,2,4)
Math.max.apply(null, [1,3,5,2,4])
7、promise
创建对象
let p1 = function(){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('成功1!')
},1000)
})
}
let p2 = function(){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('成功2!')
},1000)
})
}
let p3 = function(){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('成功3!')
},1000)
})
}
链式操作
p1().then((data)=>{
console.log(data)
return p2()
}).then((data)=>{
console.log(data)
return p3()
}).then((data)=>{
console.log(data)
})
race函数
Promise.race([p1(),p2(),p3()]).then((data)=>{
console.log(data) //[p1,p2,p3]
}).catch((err)=>{
console.log(err)
})
all函数
Promise.all([p1(),p2(),p3()]).then((data)=>{
console.log(data) //p1
})
8、观察者模式
class Event{
constructor(){
this.list = []
}
subscrible(type, handler){
if(this.list[type]){
this.list[type].push(handler)
}else{
this.list[type] = [handler]
}
}
unSubscrible(type, handler){
if(this.list[type]){
let index = this.list[type].indexOf(handler)
this.list[type].splice(index, 1)
}
}
publish(type){
if(this.list[type]){
this.list[type].forEach((item)=>{
item()
})
}
}
}
let event = new Event()
function load(index){
console.log('load')
}
function click1(index){
console.log('click')
}
function click2(index){
console.log('click')
}
event.subscrible('load', load)
event.subscrible('click', click1)
event.subscrible('click', click2)
event.publish('load')
event.publish('click')
9、发布订阅模式
class Dog{
call(){
console.log('汪汪')
}
}
class Pubsub{
constructor(){
this.list = []
}
subscrible(call){
this.list.push(call)
}
publish(){
this.list.forEach((item)=>{
item()
})
}
}
let pubsub = new Pubsub()
class Thief{
constructor(){
this.list = []
}
action(){
pubsub .publish()
}
}
let thief = new Thief()
let dog1 = new Dog()
let dog2 = new Dog()
pubsub .subscrible(dog1.call)
pubsub .subscrible(dog2.call)
thief.action()
10、eventLoop (堆、栈、队列)
1、先执行主线程(包含执行栈和堆) 2、遇到宏队列(macrotask)放到宏队列(macrotask) 3、遇到微队列(microtask)放到微队列(microtask) 4、主线程执行完毕(执行栈Stack被清空) (栈内存出栈后自动销毁) 5、执行微队列(microtask),微队列(microtask)执行完毕 6、执行一次宏队列(macrotask)中的一个任务,执行完毕 (宏任务有可能产生微任务) 7、执行微队列(microtask),执行完毕 8、依次循环...