页面渲染过程涉及的一系列问题

一:从输入URL到页面显示中间发生了什么?

  1. (涉及缓存问题)浏览器查看浏览器缓存-系统缓存-路由器缓存,若有直接显示,若没有进入下一步
  2. DNS解析获取IP地址(关于DNS解析,主机向本地域名服务器的查询一般都是采用递归查询,本地服务器到顶级域名服务器是迭代查询的过程)
  3. 向IP地址服务器发起TCP连接(TCP三次握手)
  4. 进行HTTP请求,浏览器发送请求报头(涉及请求报文)
  5. 服务器处理请求并返回HTTP报文(涉及响应报文,状态码)
  6. 浏览器解析渲染页面(形成DOM,CSSOM树的过程)
  7. TCP断开连接(四次挥手,TIME_WAIT的作用)

二、浏览器缓存问题

浏览器和服务器的应答模式

浏览器发起HTTP请求——服务器响应该请求
所以发起请求的过程为:

  1. 浏览器发起请求,在浏览器缓存中查找该请求的结果及缓存标识
  2. 若没有,说明是第一次发起HTTP请求,则向服务器发送请求,服务器返回该请求结果和缓存规则。浏览器把拿到的结果和缓存标识存入浏览器缓存中。

根据是否需要向服务器重新发起请求进行划分

强缓存

强缓存就是向浏览器缓存查找该请求结果,根据结果的缓存规则决定是否使用该缓存。

有以下几种情况:

  1. 不存在该缓存结果和标识,强缓存失效,直接向服务器发起请求
  2. 存在缓存结果和标识,但结果已失效,强缓存失效,使用协商缓存
  3. 存在缓存结果和标识,且结果有效,强缓存生效,直接返回该结果。

缓存规则:
浏览器向服务器发送请求,服务器将缓存规则放入HTTP响应头中:
Expires:过期时间戳:是HTTP/1.0字段,原理是:使用客户端的时间和服务端返回的时间做对比

Cache-control:缓存资源的过期时间间隔如:max-age=7200:优先级比expires高,是HTTP/1.1字段

Cache-Control的其他字段:
- public:允许浏览器缓存,也允许其他代理服务器缓存
- private:只允许浏览器缓存
- no-store:不使用任何缓存,直接向服务器发送请求
- no-cache:绕开浏览器,直接向服务器确认资源是否过期

补充:在浏览器中如何判断强制缓存生效?
状态码为灰色的代表使用了强缓存,请求对应的size值代表该缓存的位置(memory cache和disk cache)
==memory cache:==内存缓存

  • 具有时效性(进程关闭,则进程的内存清空)
  • 快速读取(编译解析后的文件,直接存入该进程的内存中,占据该进程一定的内存资源)
    ==disk cache:==硬盘缓存,直接将缓存写入硬盘文件,读取缓存需对硬盘文件进行I/O操作,重新解析,速度比内存缓存慢。

在浏览器中,js和图片等文件解析后直接存入内存缓存,刷新页面只需from memory cache,而css文件一般存入硬盘文件,所以每次渲染都需from disk cache。

协商缓存

协商缓存是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。

  1. 协商缓存生效,返回304(该资源无更新)
  2. 协商缓存失败,返回200和请求结果

相关字段:
Last-Modified/If-Modified-Since:
Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间
If-Modified-Since:客户端再次发起该请求时,携带上次返回的最后修改时间。服务器端接受该请求,发现有该字段,就会和服务端的Last-Modified比较,若服务器端最后被修改的时间比较大,则重新返回资源,状态码为200,否则状态码为304,表示无资源更新,可继续使用缓存文件
Etag/If-None-Match:

  1. Etag时服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器产生,利用hash算法,内容有一点改变,则标识完全不一样的特性)
    2)If-None-Match是客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。服务器收到该请求后,发现该请求头中含有If-None-Match,则会根据If-None-Match的字段值与该资源在服务器的Etag值做对比,一致则返回304,代表资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200

三、DNS解析

DNS

域名系统,是互联网的一项服务。是将域名和IP地址相互映射的一个分布式数据库。
DNS解析是分布式存储的,如根域名服务器(.)只存储了260个顶级域名服务器,顶级域名服务器存储的是一些一级域名服务器

为什么要进行域名解析

输入的url为域名,而为了识别一个实体,TCP/IP使用IP地址来唯一确定一台主机到因特网的连接,DNS会帮助我们完成域名到IP地址映射的工作

DNS解析过程

区别:
递归查询:主机到本地域名服务器的过程,若不知道IP地址,则由本地域名服务器以DNS客户身份向根域名服务器发送请求,即替主机继续查询
迭代查询:本地域名服务器向根域名服务器的查询为迭代查询。特点:要么给出索要查询的IP地址,要么告诉本地域名服务器下一步该向哪个服务器进行查询。

过程:

  1. 输入网址
  2. 浏览器先查询本地hosts是否有记录,有则返回IP地址给浏览器,无则下一步
  3. 向运营商localDNS发起请求,若有记录,直接返回,没有则进行迭代查询
  4. 根域名服务器-顶级域名服务器-直到查到IP地址

DNS优化

缓存:
若是没有缓存,会非常耗时,如果DNS查询时间过长,甚至会影响到用户体验
所以现阶段用缓存进行优化:从离浏览器距离排序,浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。
DNS负载均衡:
用一句话概括就是:根据用户的位置或机器负载量返回一个合适的IP给用户用。
拓展——CDN
CDN:内容分发网络,目的是通过在现有的Internet中增加一层新的CACHE层,将网站的内容发布到最接近用户的网络“边缘”节点,使用户可以就近的取得所需内容。
工作原理:将您源站的资源缓存到位于全球各地的CDN节点上,用户请求资源时,就近返回节点上缓存的资源,而不需要每个用户的请求都回您的源站获取,避免网络拥塞、缓解源站压力,保证用户访问资源的速度和体验

一个面试问题——为什么利用多个域名放置资源(如图片)

  • 针对DNS优化,即减少DNS解析的时间,由于浏览器缓存机制的存在,只需对首次访问进行优化(虽然只请求了一个HTML文件,可还会有后续要请求的css/js/img等),所以多个域名放置,会节约主域名的连接数,优化页面响应速度
  • CDN缓存更方便
  • 突破浏览器并发限制
  • 节约cookie带宽
  • 防止不必要的安全问题

四、建立TCP连接

五、发起HTTP请求及请求报文

六、服务器返回响应及响应报文

七、浏览器解析渲染页面

浏览器解析的内容

  1. HTML/SVG/XHTML HTML字符串描述了一个页面结构,浏览器会把HTML结构字符串解析转换DOM树形结构
  2. CSS 解析CSS会形成CSSOM树
  3. Javascript脚本,等到脚本文件加载后,通过DOM API 和 CSSOM API来操作DOM和CSSOM树

解析完成后,浏览器引擎会通过DOM TREE 和CSS Rule Tree 来构造Rendering Tree

  • 渲染树只包括节点和节点样式信息
  • CSS的Rule Tree主要是为了匹配并把规则附加到渲染树上的每个Element
  • 然后,计算每个元素的位置,这就是布局和绘制的过程

最后,调用操作系统的GUI API 绘制

构建DOM

  1. **转换:**浏览器从磁盘或网络读取HTML的原始字节,并根据文件的指定编码将它们转换成字符串
  2. **令牌化:**将字符串转换为TokenToken会标识出当前Token是开始标签或结束标签,亦或是文本等信息
  3. **词法分析:**生成节点对象
  4. 构建DOM(注意:构建DOM的过程中,是一边生成Token,一边消耗来生成节点对象)

构建CSSOM

与构建DOM的过程相似
注意:CSS规则匹配时,是从右向左的,所以尽量使用id或class,而不要过度层叠。

构建渲染树

渲染树只会包括需要显示的节点和这些节点的样式信息(display:none是不会在渲染树中出现的)
CSS样式资源:
不会阻塞浏览器构建DOM树,但会阻塞渲染
JS资源:
JS资源会阻塞浏览器解析,需要等待脚本下载完成并执行后才继续解析HTML。
因为:GUI渲染进程和JS引擎进程是互斥的,所以为了首屏渲染的较快,最好将script标签防止body标签底部。(或给其添加defer或者async属性)
JS文件不只是阻塞DOM的构建,它会导致CSSOM也阻塞DOM的构建。虽原本构建DOM和CSSOM是互不影响,但JS也可以改变样式,如果想要访问和修改,是需要完整的CSSOM树,所以在这种情况下,浏览器会先下载和构建CSSOM,然后再执行JS,最后再继续构建DOM
defer和async
async:无顺序的加载表示异步执行,如果已经加载好,就会开始执行,这种方式依然会阻塞load事件
async-script 可能再DOMContentLoaded触发之前或之后执行,但一定再load触发之前执行
defer:有顺序的加载表示延迟执行引入的JS,加载JS和解析HTML是并行的,等解析完毕和defer-script也加载完成,会执行所有defer-script,然后触发DOMContentLoaded事件。

关于回流和重绘

重绘:样式发生变化,其几何属性并未发生变化,不需要重新计算元素的几何属性
回流:引发了DOM几何尺寸的变化,浏览器需重新计算然后绘制,也叫重排
回流必定会引发重绘,重绘不一定会引发回流
引起回流的有:

  • 添加或者删除可见的DOM元素;
  • 元素尺寸改变——边距、填充、边框、宽度和高度
  • 内容变化,比如用户在input框中输入文字
  • 浏览器窗口尺寸改变——resize事件发生时
  • 计算 offsetWidth 和 offsetHeight 属性
  • 设置 style 属性的值
  • 激活css伪类
    减少回流的方法:
  • 使用visibility替代display
  • 尽量不要使用table布局
  • 减少逐项修改样式,最后一次性更改style,或将样式定义为class并一次性更新
  • 避免循环操作DOM,创建一个documentFragment或div,在它上面进行操作,然后再把它添加到window.document
  • 将复杂的元素绝对定位或固定定位,脱离文档流
  • 避免多次读取offset等属性

补充:关于display,visibility,opacity

结构:

  • display:none 不会出现在渲染树中,渲染时不占据空间,不可点击
  • visibility:hidden 出现在渲染树中,占据空间,内容不可见,不可点击
  • opacity:0 出现在渲染树中,占据空间,可点击
    继承:
  • display:none ;opacity:0;修改子孙节点也无法显示
  • visibility:hidden:修改子孙节点为visible可显示
    性能:
  • display:none :修改元素会造成回流
  • visibility:hidden,opacity:0:修改元素会重绘,不会回流。

JS编译原理

程序在执行前,会经历三个步骤,统称为编译:

  1. **分词/词法分析:**把字符串分解成有意义的代码块,这些代码块被称为“词法单元”
  2. 解析/语法分析:将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树——抽象语法树AST
  3. 代码生成:将AST转换为可执行代码的过程被称为代码生成
    对于JS来说,大部分情况下编译发生在代码执行前的几微秒(或更短)时间内
引擎,编译器,作用域
  • 引擎:从头到尾负责js程序的编译及执行过程
  • 编译器:负责语法分析及代码生成
  • 作用域:负责收集并维护由所有声明的标识符组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。
    总结:变量的赋值会执行两个操作:1、编译器会在当前作用域声明一个变量(之前没有声明过);2、运行时引擎会在当前作用域中查找该变量(找不到就向上一级作用域查找),如果能找到就对其赋值
LHS RHS

对变量进行赋值所执行的查询叫 LHS。
找到并使用变量值所执行的查询叫 RHS。

作用域和执行上下文&this

作用域:是在编译阶段确定的
作用域简单来说就是一个区域,包含其中变量,常量,函数等定义信息和赋值信息,以及这个区域内代码书写的结构信息。
作用域可以嵌套,在进行变量查找的过程,由当前作用域到最外层作用域,这样一条有序列表就是作用域链

执行上下文:是在函数执行时确定的,每次函数执行都会产生执行上下文
执行上下文用于跟踪代码的运行情况,是在函数被调用时产生的,将其压入执行栈,执行完毕弹出,栈底永远都是全局上下文,栈顶时当前处于活动状态的正在执行的上下文。
this:通常指向函数的拥有者(执行上下文),由函数执行时确定的,谁调用就指向谁
绑定规则优先级从低到高:

  • 默认绑定
  • 隐式绑定
  • 显式绑定
  • new绑定

八、TCP 断开连接 四次挥手

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值