理解阅读器渲染网页的每个步骤机制!
我的设法:假如我要构建快速可靠的网站,需要真正理解阅读器渲染网页的每个步骤机制,这样就可以在开发历程中对每个步骤停止优化。 这篇文章是我在较高水平上对端到端历程的学习总结。
好了,废话不多说,我们开端吧。这个历程可以分为以下几个主要阶段:
1、开端解析HTML
2、猎取外部资源
3、解析 CSS 并构建CSSOM
4、施行 JavaScript
5、合并 DOM 和 CSSOM 以结构渲染树
6、运算规划和绘制
1.开端解析HTML
当阅读器通过网络接收页面的HTML
数据时,它会马上设定解析器将HTML
转换为文档对象模型(DOM)。
文档对象模型 (DOM) 是HTML和XML文档的编程接口。它供给了对文档的构造化的表述,并定义了一种方式可以使从程序中对该构造停止拜访,从而改动文档的构造,样式和内容。DOM 将文档解析为一个由节点和对象(包括属性和办法的对象)组成的构造汇合。简言之,它会将web页面和足本或程序说话连接起来。
解析历程的第一步是将HTML分解并表示为开端标志、完毕标志及其内容标志,然后它可以结构DOM。
2. 猎取外部资源
当解析器碰到外部资源(如CSS或JavaScript文件)时,解析器将提取这些文件。 解析器在加载CSS文件时连续运转,此时会阻挠页面渲染,直到资源加载解析完(稍后会具体介绍)。
JavaScript 文件略有不一样-默许状况下,解析器会在加载 JS 文件然后停止解析同时会阻挠对HTML的解析。 可以将两个属性增加到足本标签中以减轻这种状况:defer
和async
。 两者都同意解析器在后台加载JavaScript 文件的同时连续运转,但是它们的施行方式不一样。 关于这一点后面还会再讲一点,但总的来说:
defer
表示文件的施行将被延迟,直到文档的解析完成为止。 假如多个文件具有defer
属性,则将依照页面放置的次序顺次施行。
<script type="text/javascript" src="script.js" defer>
async
意味着文件将在加载后马上施行,这大概是在解析历程中或在解析历程之后施行的,因此不克不及包管异步足本的施行次序。
<script type="text/javascript" src="script.js" async>
预加载资源
<link>
元素的 rel
属性的属性值preload
能够让你在你的HTML页面中 <head>
元素内部书写一些声明式的资源猎取恳求,可以指明哪些资源是在页面加载完成后即刻需要的。
关于这种即刻需要的资源,你大概但愿在页面加载的生命周期的早期阶段就开端猎取,在阅读器的主渲染机制介入前就停止预加载。这一机制使得资源可以更早的得到加载并可用,且更不易堵塞页面的初步渲染,进而晋升机能。
<link href="style.css" rel="preload" as="style" />
3.解析CSS并构建CSSOM
你大概很早就知道DOM,但对CSSOM(CSS对象模型)大概听得少,反正我也没听过几次。
CSS 对象模型 (CSSOM) 是树形情势的所有CSS选中器和每个选中器的相关属性的映射,具有树的根节点,同级,后代,子级和其他关系。CSSOM 与 文档对象模型(DOM) 非常类似。两者都是关键渲染途径的一部分,也是准确渲染一个网站必需采取的一系列步骤。CSSOM 与 DOM一起构建渲染树,阅读器顺次使用渲染树来规划和绘制网页。
与HTML文件和DOM类似,加载CSS文件时,必需将它们解析并转换为树-这次是CSSOM。 它描写了页面上的所有CSS选中器,它们的层次构造和属性。
CSSOM
与 DOM
的不一样之处在于它不克不及以增量方式构建,由于CSS
规则由于特定性而可以在各个不一样的点彼此覆盖。 这就是CSS 堵塞渲染的缘由,由于在解析所有CSS并构建CSSOM此前,阅读器没法知道每个元素在屏幕上的位置。
4.施行JavaScript
不一样的阅读器有不一样的 JS 引擎来施行此任务。从运算机资源的角度来看,解析 JS 大概是一个昂贵的历程,比其他类型的资源更昂贵,因此优化它关于获得良好的机能是如此重要。
载入事件
加载的JS和DOM被完全解析并预备就绪后就会 emit document.DOMContentLoaded
事件。 关于需要拜访DOM的任何足本,例如以某种方式停止操纵或侦听会员交互事件,优秀作法是在施行足本此前先等候此事件。
document.addEventListener('DOMContentLoaded', (event) => { // 这里面可以平安地拜访DOM了 });
在所有其他内容(例如异步JavaScript,图像等)完成加载后,将触发window.load
事件。
window.addEventListener('load', (event) => { // 页面现已完全加载 });
5.合并DOM和CSSOM 构建渲染树
渲染树是DOM和CSSOM的组合,表示将要渲染到页面上的所有内容。 这并不必然意味着渲染树中的所有节点都将在视觉上显现,例如,将包括opacity: 0
或visibility: hidden
的样式的节点,并依然可以被屏幕阅读器等读取,而display: none
不包罗任何内容。 此外,诸如<head>
之类的不包括任何视觉信息的标签将始终被忽略。
与 JS 引擎一样,不一样的阅读器具有不一样的渲染引擎。
6. 运算规划和绘制
此刻我们有了完全的渲染树,阅读器知道了要渲染什么,但是不知道在哪里渲染。 因此,必需运算页面的规划(即每个节点的位置和大小)。 渲染引擎从顶部开端不断向下遍历渲染树,运算应显示每个节点的坐标。
完成之后,最后一步是猎取规划信息并将像素绘制到屏幕上。
原文地址:https://dev.to/jstarmx/how-the-browser-renders-a-web-page-1ahc
作者:James Starkie
译文地址:https://segmentfault.com/a/1190000037650883