浏览器渲染页面过程(具详细)

1,572 阅读5分钟

一张图就能看懂!这里只总结浏览器如何把一个页面渲染出来!域名解析那一步略过! image.png

  1. 发送HTTP请求:浏览器首先向服务器发送HTTP请求,请求服务器提供指定的网页资源。
  2. 接收HTML文件:服务器接收到请求后,会将网页的HTML文件作为响应返回给浏览器。
  3. 构建DOM树:浏览器解析HTML文件,构建DOM树(文档对象模型)。DOM树是表示网页内容的树状结构,它由多个节点构成,每个节点代表HTML中的一个元素、文本内容或注释。
  4. 加载CSS样式(异步微任务):浏览器解析HTML文件时,(遇到样式表)会同时解析其中的CSS样式表,并将其应用到相应的元素上,从而实现网页的样式和布局。
  5. 构建渲染树:浏览器根据DOM树和CSS样式信息构建渲染树。渲染树是表示网页视觉呈现的树状结构,它包含了所有需要显示的元素,以及它们的样式和布局信息。
  6. 进行布局和绘制:浏览器根据渲染树进行布局和绘制。布局是指确定每个元素在屏幕上的位置和大小,而绘制则是将元素绘制到屏幕上。
  7. 显示网页:经过布局和绘制后,浏览器将网页显示在屏幕上。

以上过程中,JavaScript代码也可能会对网页的显示产生影响。当浏览器遇到JavaScript代码时,它会暂停当前DOM的渲染过程,执行JavaScript代码,执行完之后,然后再继续进行渲染。这可能会导致页面加载速度变慢,影响用户体验。为了避免这种情况,可以使用上文提到的一些技术,如异步加载JavaScript、动态加载JavaScript、将JavaScript放到底部等

DEMO:

注意:这里加载JS时会阻塞HTML和CSS渲染,但是JS中的异步任务不会对主线程造成影响

<div style="color: red">我还没被阻塞</div>
			<!--  
			这个script会阻塞下面的代码执行,等到i+到10万才可以给下面的div才会被渲染 
    	setTimeout不会影响主线程,不会影响下面div的渲染
			-->
    <script>
      for (i = 0; i < 100000; i++) {
        console.log(i)
      }
     setTimeout(() => {
        console.log('我对主线程没影响')
      }, 10000)
    </script>
 <div>我会被阻塞</div>

部分细节问题详解:

  1. 既然浏览器是单线程的,怎么能在解析HTML文件时同时解析CSS样式表
1.  虽然浏览器是单线程的,但是在解析HTML文件时同时解析CSS样式表并不会产生阻塞,这是因为浏览器采用了一种基于事件循环的异步模型来处理各种任务。
2.  当浏览器解析HTML文件时,如果遇到了CSS样式表,它会发送请求加载CSS样式表,但是加载和解析CSS样式表的过程是异步的,并且不会阻塞HTML的解析。当CSS样式表加载完成后,浏览器会将其解析成CSS规则,并将其应用到DOM元素上。
3.  在解析HTML和CSS的过程中,如果遇到JavaScript代码块,浏览器会将其添加到JavaScript引擎的执行队列中,等待执行。由于JavaScript引擎的执行是异步的,所以即使在执行JavaScript代码的同时,浏览器也可以继续解析HTML和CSS,从而实现了并发处理。
4.  需要注意的是,如果CSS样式表过多或者JavaScript代码量过大,可能会影响页面的加载性能。因此,为了提高网页的性能和用户体验,可以采用一些优化技术,例如将JavaScript代码放在底部,压缩和合并CSS和JavaScript文件,使用CDN等。

2. 把JS代码放在HTML底部不也是要等同步的JS执行完完成的渲染DOM树吗

1. 是的,放在底部也会等待同步JavaScript代码执行完毕后再构建DOM树。但是,相比于放在头部,放在底部能够更早地开始构建DOM树,因为在构建DOM树期间,浏览器仍然可以下载并执行JavaScript代码。而如果JavaScript文件放在头部,则必须等待JavaScript代码执行完成后才能继续构建DOM树。
2.  此外,对于一些不必要同步加载的JavaScript代码,可以使用异步加载的方式,如使用 **<script>** 元素的**async**属性或使用**defer**属性,或者通过动态创建 **<script>** 元素并添加到文档中,以避免对DOM树的阻塞。这样可以更好地平衡JavaScript代码的执行和DOM树的构建。

3. 当DOM树渲染的时候加载到了新的HTML文件怎么办?

1.  当DOM树渲染时,如果浏览器加载到新的HTML文件,会立即停止当前HTML的渲染并开始加载新的HTML。新的HTML文件的解析和渲染过程会在当前HTML文件的解析和渲染过程结束后开始。这种情况下,如果新的HTML文件包含CSS或JS等外部资源,这些资源的下载和解析过程也会在当前HTML文件的解析和渲染过程结束后开始。
2.  值得注意的是,如果浏览器加载到新的HTML文件,用户可能会感觉到页面的“闪烁”或者“重绘”,因为浏览器需要重新构建DOM树和CSSOM,并重新计算布局和绘制。因此,在实际开发中,应该尽可能避免在渲染过程中加载新的HTML文件,以提高页面的性能和用户体验。

4. 在DOM树渲染完成之前,是没有样式的,因为此时还没有与CSSOM结合