·先在地址栏输入url浏览器判断是否为地址(关键词则搜索)
·浏览器吊起beforeUnload钩子,等待当前页面处理完毕
·域名解析
[1]判断是否有缓存记录该地址对应的ip地址(近期访问过)
[2]如果没有则查找本地host是否有记载(就是那个host文件)
[3]如果都没有去访问DNS服务器询问ip地址
·与主机连接【这里有好几种情况】
第一种情况:就是我要访问的浏览地址
[1]「http协议相关」是否握手连接(这里应拓展http3知识点)
[2] 连接成功之后取得返回值,检查response header里的content-type 是否是文件类型,是要下载(mp3)之类的,不是的话要准备开始绘制网页了, 文件类型:multiply,image之类的,如果是301 302之类的重定向,则需要重新发起新地址的请求
第二种情况:这是由浏览器发起的对资源的访问(比如请求一张图片)
强缓存和协商缓存:
缓存的标识字段[cache-control](两边的头都有这个,但是通常在 response header里带着)里的max-age, 记录了该资源的缓存时效性,多长时间
【强缓存】有两个,一个就是在max-age里有具体时间,如果监测到时 间超出时效性就重新请求,没有就用缓存中的,但是刷新页面的话会 重新请求,通常是max-age=xxxx, public还有一个就是max-age:xxx, immutable意思是强制使用缓存, 刷新也会用缓存的资源,而不是重新请求,fb15年搞的
【协商缓存】在上面强缓存的基础上多了两个字段etag和last-modified,etag就是该资源的hash标识,用来做资源的唯一性鉴别, last-modified是上一次修改时间,浏览器识别到此再请求会发起协商请求,目的是询问服务器该资源是否更新(PS:这应该是个head 类型请求,有待查证)如果没有更新返回的是304,更新了就返回200,并一起返回新的值,下面是我随手截的一张图
·准备渲染(指上文第一种情况渲染网页)
[1]新建进程:
如果没有同源网址在打开状态,则需要需要新建进程,(以Chrome为例,可以打开Chrome的任务管理器看到这个细节)
[2] 复用进程:
如果是同源网址下的新窗口(比如打开B站的视频页),会复用进程,创建新的子进程以及任务队列
PS:浏览器有哪些进程?(以Chrome为例)
(1)浏览器进程:主要负责界面展示,子进程管理,用户交互,提供存储等功能
(2)渲染进程:主要任务是将HTML、CSS 和 JavaScript转化成用户交互的网站(就是我们最终使用的样子),像排版引擎blink和js引擎v8都是在这个进程中,默认状态下打开一个tab会新建一个进程,出于安全考虑该进程是在沙箱环境下运行(除了避免不法黑客入侵计算机获得更高等级权限,也防止了因一个tab崩溃而引起的浏览器乃至计算机系统级别的资源崩溃,这段建议查阅早期浏览器的历史)
(3)GPU进程:开始是没有的,后因为需求提升,chrome引入了GPU进程,用于绘制网页以及谷歌自己的UI页面
(4)网络进程:近几年才分离出来的进程,顾名思义,主要负责网络请求
(5)插件进程:chrome的插件是单独的进程,也是为了防止崩溃带来的负面影响
·提交文档:开始更新web页面
这里其实只是个时间节点,意味着浏览器开始解析并绘制接下来的页面了
·开始渲染(指的客户端渲染)
解析html => Dom树
解析css => Css树
整合生成Render树(渲染树)
PS:这里的步骤并不是完全同步操作的,并不是说先解析完html然后再解析css,实际上浏览器通常在解析到</body>尾标签的时候就开始拉取js代码了
布局(layout):Render树记载了所有节点的位置信息,浏览器会根据这些节点确定布局信息
回流(reflow):即因为节点布局信息改变重新确定布局的操作,如高度改变
绘制(paint):浏览器根据节点信息绘制当前我们看到的页面
重绘(repaint):即因为节点绘制信息的改变而重新绘制页面的操作,如颜色改变
重组(recomposite):transform触发,原理是在涂层的最上层重新绘制你需要的css效果,一般为动画,这样不会影响原有布局,而且效率很高
以上就完成URL渲染的所有步骤了
·加餐:V8如何执行一段js代码
V8采用的即使编译(JIT)来解读一段js代码,一段js代码要在电脑上运行,先经过编译器进行词法分析,语法分析,生成抽象语法树(AST),再经过解释器生成字节码,早期的V8则是直接生成的机器码,这样运行效率确实高,但是因为机器码占用的内存空间远远大于字节码,这会造成一些机器内存较小的用户在浏览网页的时候出现崩溃的事情,在之后V8团队的迭代下选择了生成字节码,这样在保证多平台的无差别使用前提下减少了内存压力
抽象语法树(AST)小知识:我们熟知的Babel就是通过AST来进行向后兼容的,ESlint也是通过生成的AST来判断语法是否符合规范