在梳理浏览器渲染过程之前,先来了解一下浏览器内核。
浏览器内核
当HTML代码在浏览器中执行时,必不可少需要浏览器内核的帮助。事实上,浏览器内核 包括 渲染引擎(包含HTML解析器、CSS解析器) 和 JS引擎(也叫JS解释器),不过一般提及 浏览器内核 时,我们就认为指的是 渲染引擎。
渲染引擎 负责对网页语法的解释(如HTML、XML等)并渲染网页(CSS)。
JS引擎 负责负责对JavaScript脚本的解释与执行。
常见浏览器的 渲染引擎 和 JS引擎 如下表所示。
浏览器渲染过程
从输入URL得到IP地址,到与服务器建立TCP连接,直至浏览器发送请求的详细过程在此就不赘述了。
在浏览器接收到服务器发来的资源(HTML文件)之后,浏览器的渲染引擎 自上而下 解析。在此过程中,
- 若遇到外部CSS(
<link>
标签)或图片(<img>
标签),浏览器会另外发送请求去获取相应资源。该过程是异步的,即不会影响渲染引擎会继续向下解析。 - 若遇到JS文件(
<script>
标签),不论是外部加载的JS文件,还是直接写在HTML里的JS代码,渲染引擎都会先暂停渲染,浏览器将调用JS引擎进行解析。该过程会阻塞HTML文件继续向下执行,直至JS代码解析完毕,再继续调用渲染引擎向下执行HTML代码(所以一般建议将<script>
放在页面最后,这样可以保证在加载JS时,页面有内容可以显示,而非空白)。
以上是网传浏览器渲染时,CSS文件和JS文件的加载情况。那么对于外部资源,浏览器是在解析到时再去请求资源进行加载吗?对于 “多个外部JS文件,加载是同时进行的,执行是按先后顺序的” 又如何理解呢?这点我一直很困惑… 直到看到这篇文章 各浏览器对页面外部资源加载的策略,我终于有种醍醐灌顶的赶脚~推荐大家阅读。
不同浏览器并发HTTP数(默认加载时是HTTP请求)和加载顺序有所不同,下面选择了几个常见的浏览器,简单粘贴一下该作者的结论,有时间再学习验证一下。
IE6
- 各资源按照在HTML中的顺序加载
- 最大并发HTTP数为2,即同时可以加载两个外部文件
- 当遇到JS文件时,会阻塞后面文件的加载(仅一个HTTP请求)
- 图片资源(
<img>
标签)执行到的时候开始加载,异步
IE8(Firefox3.6差不多)
- 会分析HTML结构,优先下载
<script>
和<link>
标签定义的外部资源 - 最大并发HTTP连接数为6
- JS文件不会阻塞其他资源的加载,多个JS文件可以一起加载,执行顺序按照在HTML中的顺序
- 图片资源(
<img>
标签)执行到的时候开始加载,异步
Chrome
- 优先加载
<head>
中<script>
和<link>
标签中的外部资源,并且此时阻塞<body>
中的资源加载 - 执行到
<body>
标签时,优先下载<script>
和<link>
标签定义的外部资源 - 最大并发HTTP连接数为6
- JS文件不会阻塞其他资源的加载,多个JS文件可以一起加载,执行顺序按照在HTML中的顺序
- 图片资源(
<img>
标签)执行到的时候开始加载,异步
所以说,对于现在大多数常见的浏览器,都是在加载页面(HTML文件)的同时,就同时开始加载外部资源。注意,不论是外部加载的JS文件,还是内嵌入的JS代码,都是按先后顺序执行。
那么,渲染引擎执行过程中在干嘛呢?当然是生成Render树啦。具体如下:
- 调用HTML解析器,构建DOM树
- 调用CSS解析器,构建CSSOM树
- 根据最终的DOM树和CSSOM树,生成Render树
- 布局:根据Render树来计算每个节点在屏幕中的位置
- 渲染:将各节点的内容绘制在屏幕
值得注意的是
- 在构建DOM树和CSSOM树时,可能因为执行中遇到JS代码,从而DOM树和CSSOM树发生改变。
- 当外部JS代码和CSS代码还没加载完成时,如果DOM树上有可视元素的话,浏览器通常会将一些内容提前渲染到屏幕上。