前端,从输入URL到用户看到页面,简述

参考优质博文:从输入URL到页面加载的过程?如何由一道题完善自己的前端知识体系!

浏览器分配一个进程(浏览器渲染线程)给这个页面

页面是多线程的:

  • http请求会被分配一个异步http请求线程,
  • 页面渲染分配一个GUI渲染线程,
  • JS代码涉及到JS引擎线程、事件触发线程、计时器触发器线程
    • 代码中的setTimeout和setInterval等计时器,会放入计时器触发器线程,到时间了回调函数就被推入执行事件队列
    • 事件触发线程是浏览器给JS引擎线程开的外挂,用来控制事件循环的。
    • JS引擎线程用于执行JS代码,从事件队列中取事件执行,JS引擎线程和GUI渲染线程是互斥的,所以JS代码如果太拉了,就会影响页面渲染。

强缓存判断,如果缓存失效了的话,进行下面的

  • http1.1,在头中添加 Cache-Control 字段,例如:Cache-Control: Max-Age = 3600 ,单位是秒,使用绝对时间,由后台给出,相对于前端时间进行计算,设置为Cache-Control: no-cache则不使用缓存,直接请求。
  • http1.0 头:Expires:值为一个GMT时间,用的是后台的,如果前后台有时差那就会出问题;然后Pragma设置为no-cache的时候就禁用缓存了
  • Cache-Control优先于Expires

URL解析:

  • 如果host不是ip地址,就拿着host去DNS域名服务器进行查询,中间可能经过路由、缓存
  • 拿到了ip地址,准备握手建立连接。

三次握手建立TCP连接

  • 客户端:外,哥们,开个门,听到了没,听到了吱一声。(试图确认服务端的正常收发能力)
  • 服务端:听到了,超,我听到了,你听到我了吗。(确认了客户端的正常发送能力,试图确认客户端的正常接收能力)
  • 客户端:听到了,ok,可以建立连接了。(客户端确认了服务端的正常收发能力)
  • 服务端收到最后一次招呼,确认了客户端的正常接收能力,连接建立。

https的话再进行 SSL/TLS 握手

简单版(面试的时候应该背这个的,,,,面试官理解了半天还做了笔记才明白我背的下面的那个随机数版):

  • 客户端发出请求,指明自己能使用的hash算法和加密算法列表
  • 服务端拿到,挑选一组hash和加密算法,将自己的公钥A+服务端信息进行hash,得到一个摘要,使用ca私钥对摘要进行加密。将加密后的摘要(数字签名) + 明文(公钥A + 服务端信息) + 选择的hash算法和加密算法 = 数字证书 ,发送给客户端
  • 客户端拿到,在本地取出ca公钥,对证书进行验证:解密数字签名,拿到一个摘要,使用同样的hash算法对明文进行hash,得到另一个摘要,两个摘要进行对比,如果一致,说明证书有效,服务端的公钥A有效。客户端生成一个对称密钥X,使用服务端公钥A配合指定的加密算法加密对称密钥X,发送给服务端。
  • 服务端收到,用服务端私钥解密密文,得到对称密钥X,用X加密一段数据得到密文,并把这段数据进行hash得到一段明文摘要密文和明文摘要发送给客户端
  • 客户端收到,用X解密密文得到明文,用同样的hash算法对明文进行hash得到摘要,这段摘要刚才收到的明文摘要进行对比,若一致,说明客户端可以确认服务端收到的密钥X是对的,可以建立对称加密
  • 然后进行正常请求。

复杂版:

  • 客户端:生成一个随机数A,将随机数A和一系列加密算法发送给服务端
  • 服务端:收到,存下A,挑选一组加密算法Z和hash算法,生成一个随机数B,将随机数B和加密算法Z发送给客户端。然后,自己的网址+自己的公钥+证书颁发机构的信息打包 = 证书,发送给客户端。一共两个包,两次发送
  • 客户端:收到,验证证书是否值得信任,完事儿拿到服务端的公钥,存下随机数B,自己生成一个随机数C,用服务端公钥和加密算法Z加密C。用A+B+C按照一定方式生成对称密钥X,使用X加密一段明文信息得到密文,然后用约定方式hash明文信息,得到hash段,加密了的C+密文+hash段打包发送给服务端
  • 服务端:收到,用私钥和加密算法Z解密得到C,用相同的一定方式将A+B+C生成对称密钥X,用X解密密文得到明文信息,用约定的hash算法hash同一段明文信息得到服务端hash段,同客户端发来的hash段进行比较,一致则说明ok。然后使用X加密一段明文得到密文,并hash这段明文,hash段和密文一同发送给客户端
  • 客户端:收到,用X解密密文得到明文,明文进行hash,和服务端发来的hash端进行比较,一致则说明可以建立加密通道。使用X进行对称加密通话。

发出正式的 http 请求

  • tcp连接建立了就可以正式发送请求了。
  • get请求就只发送一个包,复杂的post的话先发送预检请求,得到status=100后,再发送正式请求,返回status=200的话,ok。

协商缓存判断,如果缓存失效了的话,进行下面的

  • 如果上面返回的只是一个返回头,然后返回头的E-tag和浏览器请求头的If-None-Match匹配,说明304,使用本地的协商缓存,http1.1。如果是http1.0,则是服务端Last-Modified和客户端If-Modified-Since两个头字段进行匹配。
  • E-tag优先于Last-Modefied

后台交互,把资源发给前端

  • 后端的,不去了解。

前端拿到返回资源,解析

  • 解析HTML,构建DOM树,bytes-characters-tokens-nodes-DOM
    • 转换:bytes->字符
    • 分词:字符->词元(有了自己的含义)
    • 词法分析:词元->对象(有了自己的属性和规则)
    • DOM构建:对象->树形结构(对象之间有了关系)
  • 解析CSS,构建CSS规则树,bytes-characters-tokens-nodes-CSSOM
  • 合成DOM树和CSS规则树,生成render树
    • 将两棵树合成,样式和DOM元素合成,一些不可见的元素(存在于DOM树中的)就不会进入渲染树
  • 布局render树,引起回流(reflow|重排),元素的尺寸、位置计算(这中间可能就有一些JS代码影响了渲染树,导致了回流和重绘)(用本地缓存存储一些访问时会导致回流的变量,可以降低回流的频率,灵活利用transform也可以减少回流)
  • 绘制render树(paint),绘制页面像素信息
  • 浏览器将各层信息发送给GPU,GPU将各层合成(composite),显示在屏幕上
  • 单独的,外链资源的加载:
    • img资源,异步下载,不会阻塞各种解析,下载完就直接替换原有src的位置
    • css资源,不会阻塞HTML的解析,但是会阻塞渲染树的构建(media query声明的css资源不会阻塞)
    • js资源,会阻塞HTML的解析,下载完并执行后才会继续HTML的解析。
      • 如果加了defer,下载完之后等待到html解析完了才会执行,是延迟执行;如果加了async,下载完就立即执行,没有先后顺序,谁先下载完谁先执行,所以可能造成js之间的阻塞,是异步下载。
      • 有的浏览器也有优化,可以并发下载,但也只是优化下载过程,解析和执行过程的阻塞还是管不着的。
  • JS引擎解析(单独拿出来讲):
    • 解释阶段
      • 词法分析,代码->词元
      • 语法分析,词元->语法树
      • 使用翻译器将代码转换成字节码(bytecode),谷歌的V8引擎会直接把代码转换成机器码。
      • 使用字节码解释器将字节码转换成机器码
    • 预处理阶段,为了确保JS代码正确执行
      • 变量提升
      • 分号补全等
    • 执行阶段
      • 执行上下文,下面三个都是执行上下文的三个属性;执行堆栈。
        • 执行上下文都存在一个栈中
          • 浏览器组开始执行JS,创建一个全局执行上下文,压入执行栈
          • 然后每进入一个作用域,就创建对应的执行上下文压入栈顶
          • 每从一个作用域退出,就把栈顶的执行上下文弹出来,将上下文控制权交给栈顶元素
          • 最后都会回到全局执行上下文。
      • VO和AO,对象变量和活动变量:函数中AO === VO,全局中AO === this === global
        • 对象变量和当前执行上下文有关。
        • 活动变量是函数被调用者激活之后出现的。
      • 作用域链,类似于原型链,变量的寻找是从内向外的,一层一层,最外面都找不到那就报错
      • this,this引出的变量,本层找不到的话不会沿着作用域链找,只和当前上下文有关。
    • 回收机制(我看看书再补充)
      • 标记清除
        • 垃圾回收程序运行,给所有在内存中的变量加上标记
        • 变量进入上下文环境后被加上"进入环境"的标记
        • 垃圾回收程序运行:把在环境内的所有变量以及其引用的变量都去掉标记
        • 变量离开上下文环境之后被加上"离开环境"的标记,这些就是待删除的了
        • 垃圾回收程序执行一次内存清理,所有带标记的变量被销毁,被收回内存
        • 标记实现方式:变量进入上下文时翻转一位;维护“在上下文中”和“不在上下文中”两个变量列表,列表中的元素可以转移到另一个中
      • 引用计数
        • 被引用时加一
        • 被减持时减一
        • 清除引用数为0的变量

用户看到页面

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值