浏览器底层渲染机制全套详解
一、如何创建一个个人的网站
我们如何发布一个自己的网站,可以供别人看?
-
第一步:购买一台服务器:阿里云、腾讯云
- 每台服务器都有一个自己的外网IP:123.111.222.12
-
第二步:基于FTP上传工具[fileZilla]将自己创作的网站代码,放到服务器的磁盘空间中(服务器本质就是一台电脑) -
第三步:基于nainx、apache、iis等把作品进行发布:在服务器创建一个web服务,让其管理项目资源(一台服务器可以有多个服务)
- 到目前为止:别人基于IP地址+端口号 就可以访问到我们的内容了,(但是这样访问太麻烦了)
-
第四步:这时就需要购买域名:域名的作用就是简化服务器web服务的访问方式
如何以开一家超市的例子来理解发布一个网站的全过程?
二、URL请求网址过程
从输入URL地址到看到页面中间都经历了啥?
一共分七步
- 第一步:URL地址解析
- 第二步:缓存检查
- 第三步:DNS解析
- 第四步:TCP三次握手(目的:建立客户端与服务器端的通道)(修路)
- 第五步:基于HTTP或HTTPS等实现通信
- 第六步:TCP四次挥手
- 第七步:浏览器渲染获取的代码
1.URL地址解析
URL地址:http://www.xxx.com:80/index.html?name=sjh&age=18#video ;
- 1、http:传输协议:[作用:用户客户端和服务器端的信息传输]
- http:超文本传输协议[最常用]
- https:http+SSL[比http更安全的传输机制]
- ftp:文件传输协议,把本地开发的资源上传到服务器
- 2、www.xxx.com域名:[作用:给外网IP起一个好听的名字]
- 顶级域名:xxx.com[需要购买]
- 一级域名:www.qq.com
- 二级域名:sports.qq.com
- 三级域名:kbs.sports.qq.com
- 3、80端口号:[作用:区分相同服务器上的不同服务的 0~65535]
- 浏览器有一个默认操作,如果我们自己没有写端口号,浏览器会根据传输协议自己加上默认的端口号
- http->80
- https->443:https://www.baidu.com->https://www.baidu.com:443/
- ftp->21
- 4、index.html:请求资源的路径名称[如果不写,则默认一般都是index.html(服务器可以自己配)]
- 5、问号传参:
- 把信息传递给服务器
- 在页面跳转的过程中,基于问号参数传递给另外一个页面一些信息
- …
- 6、#video哈希值:
2.缓存检查
- 缓存方式有三种:强缓存、协商缓存、数据缓存
- 缓存位置有两种:
- 内存条:[Memory Cache]虚拟内存缓存(临时)
- 硬盘:[Disk Cache]物理内存缓存(持久)
- 缓存存取方式三种:最开始从服务器获取信息,如果存在缓存机制,则会在Memory和Disk各存储一份
- 普通刷新(F5):从Memory Cache 中获取
- 页面关闭再重新打开:从Disk Cache中获取
- 强制刷新(Ctrl+F5):清除本地缓存,重新从服务器获取最新的内容
2.1强缓存
强缓存:本地存在缓存(且未过期),则直接从本地缓存中获取渲染{不论服务器端是否更新了内容},如果没有缓存(或者过期了),才从服务器重新获取;
-
实现步骤:
- 第一次向服务器发送请求(本地无缓存):服务器把信息返回给客户端[同时在响应头中设置
Expires 或者Cache-Control ]:用来规定是否设置强缓存以及缓存的周期;客户端获取信息后,渲染的同时,根据缓存的规则,把信息缓存在本地;
Cache-Control :max-age=2592000 单位秒 Http1.1expries : 具体时间 Http1.0- 两个都被服务器返回,则按照浏览器HTTP版本的支持度,去最高版本支持的项,http1.1比http1.0高
- 第二次向服务器发送请求(本地有缓存):先看本地是否有缓存以及是否过期,有且未过期,直接读取缓存的信息,如果缓存失效,则从服务器重新获取…,重新获取后再把最新的内容缓存到本地
-
如何设置强缓存:是由服务器端在响应头中基于Expires和Cache-Control设置缓存规则的,二客户端自己会根据这些规则,完成强缓存的存储及校验。 -
强缓存的作用:保证第二次及以后访问资源更快,对第一次没啥特殊效果! -
强缓存的副作用:在缓存有效期内,服务器资源更新了,我们获取的也是本地缓存信息,无法获取最新的信息。所以真实项目中,HTML页面是"绝对不能设置强缓存的",一旦html都缓存了,则和服务器彻底失联了,服务器不论如何更新,客户在缓存有效期内都无法获取最新的资源。
- 加载一个页面,首先获取的是html,在浏览器渲染html的时候,遇到link/script/img等标签,才会从服务器获取这些资源信息。
- 解决方法:html文件不做缓存,服务器端只要代码更改,我们让其在html中重新导入新的文件名[使用webpack实现],我们下次再访问html页面时,新导入的文件会重新向服务器请求
-
强缓存特点:不论是从服务器获取的还是从缓存中读取的资源,返回状态码都是200。
2.2协商缓存
- 协商缓存:如果强缓存和协商缓存都设置了,必须等待强缓存失效后,才会执行协商缓存(协商缓存是对强缓存的一种辅助)
- 实现步骤:
- 第一次向服务器发送请求:服务器返回对应的资源信息[同时在响应头中返回两个字段]:
last-modified (HTTP 1.0):当前资源最后一次更新时间etag (HTTP1.1):只要服务器资源更新就会产生一个唯一的etag值- 当客户端获取信息之后,发现存在这两个字段会在客户端本地存储资源信息及相关表示字段
- 第二次发送请求:即便发现本地有缓存信息,也需要先和服务器协商【协商内容:问一下服务器,这个资源有没有再更新过?】
- 客户端把自之前缓存中的
last-modified 和etag 基于请求头中的If-Modified-Since 和If-Node-Match 发送给服务器,服务器根据传递过来的文件更新时间(标识)和目前服务器最新的更新时间(标识)去对比 - 两次时间(标识)一致:说明服务器资源距离上一次缓存没有任何的更新,此时服务器返回304状态码即可,客户端接收到这个状态后,从本地缓的信息中获取渲染即可
- 如果不一致:说明更新过,返回状态码200以及最新的信息(和新的last-modified和etag),客户端再重新渲染并缓存最新的信息
- 协商缓存也是由服务器设置的:在响应头中返回
last-modified 和etag - 协商缓存是对于强缓存的一种补充:对于html页面无法设置缓存但是可以设置协商缓存、而且在强缓存失效的情况下,我们依然可以基于协商缓存验证一下服务器是否更新
-------------------------》不论强缓存还是协商缓存,都是服务器设置的[在响应头返回对应的字段],而客户端需要做的事情,浏览器自己就处理了,不需要我们前端写啥代码:而且都是针对于静态资源文件的缓存设置(例如:html、css/js/图片…),对于ajax数据请求,强缓存和协商缓存是无效的。
2.3数据缓存
- 数据缓存:[ajax数据通信的时候,对于不经常更新的数据,我们基于本地存储实现缓存]
- 实现步骤:
- 第一次本地没有存储过任何信息:此时向服务发送ajax请求,从服务器获取数据,获取数据后一方面进行数据绑定和渲染,另外一方面把数据存储到本地【基于本地存储方案、设置有效时间】
- 后期再发送请求:首先看本地是否存储过这些数据,且是否过期
- 存储过且未过期:不需要从服务器获取,只需要获取本地存储的内容即可
- 未存储或者过期了:重新向服务器发送请求获取最新的信息,同时本地也把最新内容存储
- 数据缓存需要前端开发工程师基于 JS代码+本地存储方法,自己去实现
- 本地存储方案:把一些信息存储到本地(Application->Storage)应用->数据库
- 特点:明文存储而且可以被查看(所以重要敏感信息不要存储,即便存储也要加密)
- 而且存储的信息都是以字符串类型进行存储[排除虚拟内存存储]
- 有源的限制(在某个域下存储的信息,只能在本域中获取)
数据缓存存储的方案有哪些?
- @1 cookie:一段小文本信息(key-value格式)
- @2 localStore:本地数据库
- @3 sessionStore:会话数据库
- @4 vuex/redux:
- @5 IndexedDB:@5和@6都是本地数据库存储,很不常用
- @6 WebSQL:
数据缓存存储中,cookie、localStore、sessionStore、vuex/redux的区别?
- 兼容性:
- cookie:兼容所有浏览器
- localStore/sessionStore:H5新增的API,不兼容IE6~8
- 存储内容大小:
- cookie:同源下最多允许
4kb - localStore/sessionStore:同源下最多允许存储
5MB - 有效期:
- cookie:持久化存储,具备存储有效期,需要自己设置
- localStore:持久化存储,除非手动删除,否则一直存着,不具备有效期
- sessionStore:临时存储,页面刷新还在,关闭页面就没了
- vuex/redux:临时存储,页面刷新就没了
- 稳定性:
- cookie:不稳定,清除历史记录、电脑垃圾会清除cookie,网站无痕模式下禁止存放cookie
- localStorage/sessionStore:稳定,干掉cookie的那些操作暂时都干不掉localeStorage/sessioStore
- 与服务器关系:
- cookie:无论服务器需不需要,每次请求,都会在请求头中携带cookie,影响请求速度
- localStorage/sessionStore:绝对的本地存储,和服务器之间没有任何关系,可手动向服务器传缓存
数据缓存各存储方式详解?
- @1 cookie:
- document.cookie:获取所有Cookie
- document.cookie=(name,value):设置Cookie
- 优点:兼容所有的浏览器,是传统的本地存储方案
- 特点:存储内容大小有限制,同源下最多允许4kb
- 有效期:持久化存储,具备存储有效期,需要自己设置
- 稳定性:不稳定,清除历史记录或者电脑垃圾可能会清除cookie、以及网站的隐私/无痕模式下是禁止存储cookie的
- 与服务器的关系:cookie不是单纯的本地存储,和服务器之间有"猫腻":知道本地存储cookie,无论服务器需不需要,每一次请求都会基于请求头中的cookie字段,把存储的信息传递给服务器(如果存储东西多,导致每一次请求会变慢);服务器只要在响应头中设置set-Cookie字段,浏览器自己就会在本地设置cookie;
- @2 localStore:
- localStorage.setItem([key],[value]):设置一个项
- localStorage.getItem([key]):获取一项
- localStorage.removeItem([key]):移除某项
- localStorage.clear():清除所有项
- 缺点:H5中新增的API,不兼容IE6~8
- 特点:存储内容有大小限制:同源下最多允许存储5MB
- 有效期:持久化存储,除非手动删除,否则一直存着,不具备有效期
- 稳定性:干掉cookie的那些操作暂时都干不掉localeStorage
- 与服务器的关系:绝对的本地存储,和服务器之间没有任何关系[可以手动把本地存储的信息传递给服务器]
- @3 sessionStore:
- sessionStore.setItem([key],[value]):设置一个项
- sessionStore.getItem([key]):获取一项
- sessionStore.removeItem([key]):移除某项
- sessionStore.clear():清除所有项
- 特点:页面刷新还在,关闭页面就没了,无论是localStorage还是cookie,只要本地存储了信息,页面刷新或者页面关闭后重新打开,存储的信息都在,而sessionStore属于会话存储:页面刷新存储的信息时存在的,以为会话还没结束;但是一旦页面关闭,会话结束,则存储的信息就会释放掉。
- @4 vuex/redux:
- 特点:页面刷新就没了,他们类似于在全局上下文中创建全局变量(或者容器)来存储信息,所以只有页面刷新或者管理,之前存储的信息都会释放。
- @5 IndexedDB:@5和@6都是本地数据库存储,很不常用
- @6 WebSQL:
- …
3.DNS解析
- 域名解析:基于域名到DNS服务器上进行查找,找到服务器的外网IP[每次解析大概需要20~120ms左右]
- 解析步骤:
- 1、递归查询:从本地获取DNS解析记录(本地解析记录一般是缓存下来的,也有自己手动配置的)
- 递归查询的步骤:客户端->浏览器的DNS解析缓存->本地HOSTS文件->本地DNS解析器缓存->本地DNS服务器
- 以上只要某一步找到,就返回给客户端,如果都没找到,再进行迭代查询
- 2、迭代查询:本地没有找到解析记录,才会去公网上查询
- 迭代查询的步骤:根域名服务器->顶级域名服务器->权威域名服务器
- 以上三步必须全部查询
- 项目优化:
- 1、提高域名的解析效率/速度
- 把资源放到相同服务器的相同服务下,确保页面中域名解析的次数少,这样的操作虽然优化了DNS的解析,但是可能导致服务器压力过大,服务处理速度变慢,导致网站整体性能更差!(所以真实项目中,我们宁愿增加域名解析次数,也会把不同的资源分散到不同的服务器上部署)
- web服务器:处理html/css/js…静态资源
- 数据服务器:处理ajax请求的、实现数据管控和业务逻辑的
- 图片/音视频服务器:处理富媒体资源的
- …
- 在域名解析增加的情况下,我们可以基于DNS Prefetch(DNS预解析)来优化域名
- 原理:利用link标签的异步处理,在GUI主线程渲染过程中,同时在预先完成DNS解析,这样后续到了指定资源请求的时候,DNS可能已经解析过了,此时我们从缓存中获取解析记录即可,也优化了页面渲染的速度!!
4.TCP三次握手
5.基于HTTP建立连接
- http事务:
- http报文:请求报文&响应报文
- 请求方式:GET/POST/DELETE/PUT/HEAD/APTCH/OPTIONS
- HTTP状态码:200 301 302 307 304 400 401 403 404 500 503 …
- 请求主体&响应主体的数据格式要求…
6.TCP四次挥手
- :TCP四次挥手【作用:把建立的链接通道释放掉】
- 如果每一请求都需要重新的TCP[三握四挥],很耽误时间也很消耗性能,我们最好保持TCP通道的持久性->"长链接"
- 长连接:服务器在响应头中设置
Connection:keep-alive ,浏览器也在请求头中设置Connection:keep-alive ; - 我们可以设定长连接的周期:
Keep-Alive:timeout=15,max=300 ;
7.浏览器底层渲染
|