4.11 浏览器工作原理

4.11.1 请求响应过程

HTML文件引用CSS文件时,请求响应过程如下。

img

(1)第1次请求。浏览器向web服务器请求页面地址http://127.0.0.1:12345/test.html。

(2)第1次响应。web服务器接收请求,找到test.html文件,然后将文件传输给浏览器。如果响应成功则响应码是200;如果请求页面不存在则响应失败,响应码是404。

(3)解析HTML文件。浏览器获取test.html进行解析,发现test.html包含引用CSS文件,css文件地址是test.css。

(4)第2次请求响应。浏览器再次发出新的请求,请求地址http://127.0.0.1:12345/test.css,服务器进行响应。浏览器通过两次请求响应获取服务器的test.html与test.css文件内容。

同理,当HTML文件引用其它CSS文件、图片、JS文件,相应进行更多请求相响。


4.11.2 生成盒子树

浏览器工作原理示意图

img

浏览器工作流程包括5个过程:请求响应、解析HTML生成DOM树、解析CSS生成CSSOM树、合并生成盒子树、后续处理。具体步骤如下。

(1)请求响应。

(2)解析HTML代码生成DOM树。浏览器解析上步获得的test.html代码,生成元素结构树(也称DOM树),可直观理解成开发者工具元素面板的内容,DOM树的每个节点称为DOM节点。当发现HTML文件加载CSS文件、图片等外部资源(HTML文件之外的文件),同时再次向服务器发出请求。

元素面板DOM树结构

img

JS对象DOM树结构如下。

img

查看方法。开发者工具—“源代码/来源”—“监视”—添加对象document。


(3)解析CSS代码生成CSSOM树。根据外部样式表CSS文件、HTML文件的内部样式、HTML文件的内联样式,三者组合生成样式树,也称CSSOM树,CSSOM树的每个节点是CSSOM节点,也称CSSOM。CSSOM没有将样式与元素匹配。

JS对象CSSOM树结构如下。

img

查看方法。开发者工具—“源代码/来源”—“监视”—添加对象document.styleSheets。


(4)合并生成盒子树(也称渲染树)。因为第2步生成DOM树的DOM节点不存在样式信息,第3步生成CSSOM树的CSSOM节点不存在DOM节点信息,这一步将两者关联匹配生成新的树,即盒子树。盒子树是树状结构,每个节点是盒子Box,盒子实现DOM与CSSOM的整合。盒子即渲染时元素生成的盒子,遵循盒子模型。详情见“第6章 盒子模型”。

(5)后续显示。根据盒子树的信息进一步处理显示页面。


4.11.3 CSS文件缓存

1、查看网络面板判断是否使用缓存

开发环境与生产环境。在自己电脑开发项目时的环境称为开发环境,真正供用户使用会部署到生产服务器,称为生产环境。因为开发环境使用LiveServer的web服务,与生产环境有差别,所以这里不以自己项目进行测试。

下面以jd.com为例。第1次访问时网络请求CSS如下,过滤只显示CSS文件。

img

状态响应码是200,且大小显示相应具体数值。再次打开页面时,网络请求状态如下。

img

如果大小出现“磁盘缓存(disk cache)”字样,表示使用缓存,还有可能出现状态码304、大小出现“内存缓存(memory cache)”,也表示使用缓存。


2、CSS文件缓存的优点

发布到生产环境的CSS文件一般不会修改,为了减少浏览器的网络请求,减轻服务器的压力,提高页面显示速度,浏览器与服务器共同配合实现CSS文件缓存。图片、JS等文件同理也会缓存,HTML文件一般不会缓存。当项目升级再次发布时,生产服务器的CSS文件被修改,浏览器请求能够判断页面已被修改,重新请求新的CSS文件,同理再访问使用缓存。


3、浏览器工作原理之CSS文件缓存原理

img

第1步:浏览器从web服务器请求html文件,然后解析html文件,发现其中含有css文件,于是进入第2步。

第2步:向web服务器发出第2个请求,请求CSS文件,请求成功后进入第3步。

第3步:浏览器会自动把CSS文件保存到本地电脑的缓存目录。

后续请求:以后再次请求这个CSS文件时(无论是网站的哪个HTML文件发起),浏览器会判断web服务器的CSS文件是否修改过:如果没有修改,则会本地缓存读取;如果已经被修改,会重新请求CSS文件,再次执行第2步与第3步。


4、判断CSS文件是否修改的策略

浏览器需要判断web服务器存放的CSS文件是否修改过,判断策略如下。现在有两份CSS文件:本地缓存CSS文件、web服务器的CSS文件,浏览器会跟web服务器进行一次交互,web服务器对比两个文件的最后更新时间与文件大小,如果一致则判断没有被修改,反之则判断为修改。上述是大致方法说明,不同web服务器有自己的具体实现。


5、强制刷新与停用缓存

开发环境偶尔会抽风,明明已经修改CSS文件、JS文件、图片文件等外部引用文件,但仍使用缓存的旧文件,最新文件无法应用。请求最新引用文件包括两种方法。

方法1:强制刷新Ctrl+F5。浏览器快捷键F5刷新页面时仅重新请求html,不会重新请求CSS,通过Ctrl+F5能够强制全部重新请求。

方法2:停用缓存。调试时每次Ctrl+F5手动强制刷新页面过于麻烦,开发者工具网络面板提供“停用缓存”选项,表示每次请求会自动请求最新文件。“停用缓存”只在开发者工具打开时起作用,平时没有打开仍正常使用缓存。

img

生产环境偶避免缓存方案。通常CSS文件引用链接加上版本号参数,升级重新发布时修改版本号,浏览器识别是一个新的请求,不会使用缓存。

<link rel="stylesheet" href="test.css?v=0.1">

版本升级后,用户第1次访问时该版本则请求最新页面,在下次升级之前的后续访问则继续使用缓存。