共计 2651 个字符,预计需要花费 7 分钟才能阅读完成。
作者:James Starkie
译者:前端小智
起源:dev
最近开源了一个 Vue 组件,还不够欠缺,欢送大家来一起欠缺它,也心愿大家能给个 star 反对一下,谢谢各位了。
github 地址:https://github.com/qq44924588…
我的想法:如果我要构建疾速牢靠的网站,须要真正理解浏览器渲染网页的每个步骤机制,这样就能够在开发过程中对每个步骤进行优化。这篇文章是我在较高水平上对端到端过程的学习总结。
好了,废话不多说,咱们开始吧。这个过程能够分为以下几个次要阶段:
- 开始解析 HTML
- 获取内部资源
- 解析 CSS 并构建 CSSOM
- 执行 JavaScript
- 合并 DOM 和 CSSOM 以结构渲染树
- 计算布局和绘制
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-th…
代码部署后可能存在的 BUG 没法实时晓得,预先为了解决这些 BUG,花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。
交换
文章每周继续更新,能够微信搜寻「大迁世界」第一工夫浏览和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 曾经收录,整顿了很多我的文档,欢送 Star 和欠缺,大家面试能够参照考点温习,另外关注公众号,后盾回复 福利,即可看到福利,你懂的。