本日,我们来理解一下 HTML 和网页有什么关系,以及与 DOM 有什么不同。通过本讲内容,你将节制浏览器是怎么处理 HTML 内容的,以及在这个过程中我们可以进行若何的处理来提升网页的性能,从而提升用户的体验。
一、浏览器页面加载过程
不知你是否有过这样的体验:当打开某个浏览器的时候,创造一贯在转圈,或者等了好永劫光才打开页面……
此时的你,会选择关掉页面还是耐心等待呢?
这一征象,除了网络不稳定、网速过慢等缘故原由,大多数都是由于页面设计不合理导致加载韶光过长导致的。
我们都知道,页面是用 HTML/CSS/JavaScript 来编写的。
HTML 的职责在于奉告浏览器如何组织页面,以及搭建页面的基本构造;CSS 用来装饰 HTML,让我们的页面更好看;JavaScript 则可以丰富页面功能,使静态页面动起来。HTML由一系列的元素组成,常日称为HTML元素。HTML 元素常日被用来定义一个网页构造,基本上所有网页都是这样的 HTML 构造:
<html> <head></head> <body></body></html>
个中:
html元素是页面的根元素,它描述完全的网页;head元素包含了我们想包含在 HTML 页面中,但不肯望显示在网页里的内容;body元素包含了我们访问页面时所有显示在页面上的内容,是用户终极能看到的内容;HTML 中的元素特殊多,个中还包括可用于 Web Components 的自定义元素。
前面我们提到页面 HTML 构造不合理可能会导致页面相应慢,这个过程很多时候表示在<script>和<style>元素的设计上,它们会影响页面加载过程中对 Javascript 和 CSS 代码的处理。
因此,如果想要提升页面的加载速率,就须要理解浏览器页面的加载过程是若何的,从根本上来办理问题。
浏览器在加载页面的时候会用到 GUI 渲染线程和 JavaScript 引擎线程(更详细的浏览器加载和渲染机制将在第 7 讲中先容)。个中,GUI 渲染线程卖力渲染浏览器界面 HTML 元素,JavaScript 引擎线程紧张卖力处理 JavaScript 脚本程序。
由于 JavaScript 在实行过程中还可能会改动界面构造和样式,因此它们之间被设计为互斥的关系。也便是说,当 JavaScript 引擎实行时,GUI 线程会被挂起。
以网易云教室官网为例,我们来看看网页加载流程。
(1)当我们打开官网的时候,浏览器会从做事器中获取到 HTML 内容。
(2)浏览器获取到 HTML 内容后,就开始从上到下解析 HTML 的元素。
(3)<head>元素内容会先被解析,此时浏览器还没开始渲染页面。
我们看到<head>元素里有用于描述页面元数据的<meta>元素,还有一些<link>元素涉及外部资源(如图片、CSS 样式等),此时浏览器会去获取这些外部资源。除此之外,我们还能看到<head>元素中还包含着不少的<script>元素,这些<script>元素通过src属性指向外部资源。
(4)当浏览器解析到这里时(步骤 3),会停息解析并下载 JavaScript 脚本。
(5)当 JavaScript 脚本下载完成后,浏览器的掌握权转交给 JavaScript 引擎。当脚本实行完成后,掌握权会交回给渲染引擎,渲染引擎连续往下解析 HTML 页面。
(6)此时<body>元素内容开始被解析,浏览器开始渲染页面。
在这个过程中,我们看到<head>中放置的<script>元素会壅塞页面的渲染过程:把 JavaScript 放在<head>里,意味着必须把所有 JavaScript 代码都下载、解析和解释完成后,才能开始渲染页面。
到这里,我们就明白了:如果外部脚本加载韶光很长(比如一贯无法完成下载),就会造成网页永劫光失落去相应,浏览器就会呈现“假去世”状态,用户体验会变得很糟糕。
因此,对付对性能哀求较高、须要快速将内容呈现给用户的网页,常常会将 JavaScript 脚本放在<body>的末了面。这样可以避免资源壅塞,页面得以迅速展示。我们还可以利用defer/async/preload等属性来标记<script>标签,来掌握 JavaScript 的加载顺序。
百度首页
三、DOM 解析
对付百度这样的搜索引擎来说,必须要在最短的韶光内供应到可用的做事给用户,个中就包括搜索框的显示及可交互,除此之外的内容优先级会相对较低。
浏览器在渲染页面的过程须要解析 HTML、CSS 以得到 DOM 树和 CSS 规则树,它们结合后才天生终极的渲染树并渲染。因此,我们还常常将 CSS 放在<head>里,可用来避免浏览器渲染的重复打算。
二、HTML 与 DOM 有什么不同
我们知道<p>是 HTML 元素,但又常常将<p>这样一个元素称为 DOM 节点,那么 HTML 和 DOM 到底有什么不一样呢?
根据 MDN 官方描述:文档工具模型(DOM)是 HTML 和 XML 文档的编程接口。
也便是说,DOM 是用来操作和描述 HTML 文档的接口。如果说浏览器用 HTML 来描述网页的构造并渲染,那么利用 DOM 则可以获取网页的构造并进行操作。一样平常来说,我们利用 JavaScript 来操作 DOM 接口,从而实现页面的动态变革,以及用户的交互操作。
在开拓过程中,常常用工具的办法来描述某一类事物,用特定的构造凑集来描述某些事物的凑集。DOM 也一样,它将 HTML 文档解析成一个由 DOM 节点以及包含属性和方法的干系工具组成的构造凑集。
三、DOM 解析
我们常见的 HTML 元素,在浏览器中会被解析成节点。比如下面这样的 HTML 内容:
<html> <head> <title>标题</title> </head> <body> <a href='xx.com'>我的超链接</a> <h1>页面第一标题</h1> </body></html>
打开掌握台 Elements 面板,可以看到这样的 HTML 构造,如下图所示:
在浏览器中,上面的 HTML 会被解析成这样的 DOM 树,如下图所示:
我们都知道,对付树状构造来说,常常利用parent/child/sibling等办法来描述各个节点之间的关系,对付 DOM 树也不例外。
举个例子,我们常常会对页面功能进行抽象,并封装成组件。但不管怎么进行整理,页面终极依然是基于 DOM 的树状构造,因此组件也是呈树状构造,组件间的关系也同样可以利用parent/child/sibling这样的办法来描述。同时,现在大多数运用程序同样以root为根节点展开,我们进行状态管理、数据管理也常常会呈现出树状构造。
四、事宜委托
我们知道,浏览器中各个元素从页面中吸收事宜的顺序包括事宜捕获阶段、目标阶段、事宜冒泡阶段。个中,基于事宜冒泡机制,我们可以实现将子元素的事宜委托给父级元向来进行处理,这便是事宜委托。
如果我们在每个元素上都进行监听的话,则须要绑定三个事宜;(假设页面上有a,b,c三个兄弟节点)
function clickEventFunction(e) { console.log(e.target === this); // logs `true` // 这里可以用 this 获取当前元素}// 元素a,b,c绑定element2.addEventListener("click", clickEventFunction, false);element5.addEventListener("click", clickEventFunction, false);element8.addEventListener("click", clickEventFunction, false);
利用事宜委托,可以通过将事宜添加到它们的父节点,而将事宜委托给父节点来触发处理函数:
function clickEventFunction(event) { console.log(e.target === this); // logs `false` // 获取被点击的元素 const eventTarget = event.target; // 检讨源元素`event.target`是否符合预期 // 此处掌握广告面板的展示内容}// 元素1绑定element1.addEventListener("click", clickEventFunction, false);
这样能办理什么问题呢?
绑定子元素会绑定很多次的事宜,而绑定父元素只须要一次绑定。将事宜委托给父节点,这样我们对子元素的增加和删除、移动等,都不须要重新进行事宜绑定。常见的利用办法紧张是上述这种列表构造,每个选项都可以进行编辑、删除、添加标签等功能,而把事宜委托给父元素,不管我们新增、删除、更新选项,都不须要手动去绑定和移除事宜。
如果在列表数量内容较大的时候,对成千上万节点进行事宜监听,也是不小的性能花费。利用事宜委托的办法,我们可以大量减少浏览器对元素的监听,也是在前端性能优化中比较大略和根本的一个做法。
把稳:
如果我们直接在document.body上进行事宜委托,可能会带来额外的问题;由于浏览器在进行页面渲染的时候会有合成的步骤,合成的过程会先将页面分身分歧的合成层,而用户与浏览器进行交互的时候须要吸收事宜。此时,浏览器会将页面上具有事宜处理程序的区域进行标记,被标记的区域会与主线程进行通信。如果我们document.body上被绑定了事宜,这时候全体页面都会被标记;纵然我们的页面不关心某些部分的用户交互,合成器线程也必须与主线程进行通信,并在每次事宜发生时进行等待。这种情形,我们可以利用passive: true选项来办理五、总结我们理解了 HTML 的浸染,以及它是如何影响浏览器中页面的加载过程的,同时还先容了利用 DOM 接口来掌握 HTML 的展示和功能逻辑。我们理解了DOM解析事宜委托等干系观点。
true选项来办理
五、总结我们理解了 HTML 的浸染,以及它是如何影响浏览器中页面的加载过程的,同时还先容了利用 DOM 接口来掌握 HTML 的展示和功能逻辑。我们理解了DOM解析事宜委托等干系观点。