HTML文档解析

一个网页三大组成部分:
html:网页的内容
css:增加网页样式
js:增加业务逻辑

问题:在我们刚进行学习前端网页的时候:老师说:我们需要将css放在head的底部,而js需要放在html的底部?可是这个原理是什么勒?原因是什么勒?

要想知道css和js引入方式和位置对页面的影响,首先要知道浏览器是如何根据HTML、CSS和JS来渲染页面的

一、对于html的处理

我们先来模拟一遍请求页面的过程:
首先当我们输入一个页面地址,浏览器会发送请求给服务器,服务器以字节形式返回一个HTML文档。浏览器首先会解析字节得到字符,之后根据W3C标准对这些字符进行识别,得到Tokens,有了Token就可以进行词法分析得到节点了;这些节点带有属性,和规则信息;最后将这些节点之间的关系进行连接,就会得到一个树形结构,这个树形结构就是我们平时所说的DOM全称:Documenet Object Model,DOM表示了页面的结构,如下图所示;
在这里插入图片描述

二、对于CSS的处理

为了渲染页面的样式:浏览器还需要知道页面内元素的样式信息;因此需要解析css样式:
它会对css进行解析形成结构化数据,过程与解析html很类似
当浏览器接收到字节码形式的css样式时,将他转化为字符,之后根据css规则转换为tokens,nodes,最终构建成一个树形结构------>cssom;

cssom的树形结构与DOM是对应的,由于样式有继承关系,因此他会循环计算每个节点的样式:由于下图:此外处理开发者,CSS中指定的样式信息,cssom还会包含浏览器默认的样式;
在这里插入图片描述

三、HTML和CSS进行整合————>Render Tree

现在我们有了DOM和CSSOM,他们在当前阶段是两个独立的数据结构,一个表示页面内容,一个表示样式。
现在进行合并————>Render Tree只会包含需要的节点不需要的节点进行省略。
Render Tree表示了每个节点的样式信息。
四、Layout绘制
因为页面元素节点在屏幕中的具体大小和位置,还跟屏幕的大小有关;浏览器接下来会进行Layout步骤,根据Render Tree计算得到每个元素节点在屏幕中的尺寸,计算完成后就可以将像素绘制在屏幕上了

以上四步称为:关键渲染路径

知道了步骤,进行分析:
问题一、在构建DOM过程中如果遇到了CSS,浏览器会在该CSS解析生成CSSOM后,在进行渲染,确保遇到的css都解析完成后,浏览器才会进行渲染,如果不等css解析完就进行渲染,会发生什么情况勒?

如果不等css解析完,那么页面的首屏就会渲染出一个,只有浏览器默认样式的结果,之后css解析完毕,页面再次渲染出一个带有样式的完整结果。虽然有可能发生的很快,但不过页面会进行闪烁,会影响体验。
因此css是一个会阻塞页面渲染的资源,会加载完css之后生成cssom,然后和DOM合成Render Tree进行一次渲染,内容有了样式也有了。

现在就看js逻辑了;

JS:
JS可以直接操作DOM,也可以直接添加属性和样式,因此它对于页面渲染过程有着非常重要的限制和影响;
首先浏览器在解析HTML时,如果遇到JS,因为JS中可能会对DOM进行操作,因此这段JS需要在文档的当前位置立刻开始执行,在JS执行完毕后再加载剩下的HTML内容;也就是JS会阻塞DOM的构建使页面初次渲染变慢;其次JS在执行过程中,除了操作DOM还操作样式内容,而样式内容依赖于CSSOM,如果在需要执行JS的时候,CSSOM还没有生成怎么办,此时浏览器会暂时JS的执行,在CSSOM生成以后在继续执行JS逻辑;

总结一下:css会阻塞页面渲染,当浏览器遇到css之后会保证css加载完成cssom后,才进行页面的渲染,当浏览器遇到JS内容时,会停止继续构建DOM,直到JS执行完毕,JS会查询和修改DOM,CSSOM;因此浏览器会停止执行JS,直到CSSOM生成完毕。
css和js都会阻塞html,而css又会阻塞js执行;

有了上面的知识储备:
开始解决开始的问题

为什么css在head的最下面?
首先我们不希望用户看到没有样式的页面,如果css放在一些页面元素的后面,这些元素会先显示出来,样式加载后再重新进行渲染带有样式的结果,造成页面的闪烁,此外如果css是外链的,我们需要尽早让浏览器开始请求这些css资源。

那么为什么JS要放在body底部呢?
这是因为JS会阻塞页面的渲染,而我希望用户尽快看到有内容的页面,如果JS放在boyd顶部,那么就需要等待 js执行完毕之后首屏才会出现,增加了首屏时间,另一个原因我们在js中,会对DOM和cssom进行操作,放在body底部可以确保DOM和cssom,都已经生成完毕了,否则会出现我们获取一个DOM,去发现获取不到的情况,影响js逻辑执行;

总得来说css放在header以及js放在body底部
目的:获得更好的用户体验的同时,尽量提高页面的加载性能。
除此之外,为了获得更好的性能我们还可以将css内联,而将js外链,因为css首屏渲染是必须的,希望节省掉请求css资源的时间。而js外链则可以减小整个HTML文档体积。减小HTML文档下载时长,更快开始解析HTML CSS构建DOM和CSSOM,而浏览器进行上述操作的时候,也可以并行请求JS资源,这样即使请求慢了,页面也是有内容的,只是缺少了逻辑交互。
当我们在HTML文档中引入JS资源时,可以添加一个async属性,async属性标记了这段js是可以异步进行加载的,默认情况下,我们知道js会阻塞页面渲染,浏览器会等待js文件的请求执行,因为JS中可能会对DOM和CSSOM进行操作,如果我们确定一段js不会对DOM进行操作,就可以添加此属性

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值