如题,本文将简介一下 浏览器对页面的渲染的过程。
一个网页里面主要包含三大块东西,Html/CSS/JavaScript。
一.先说几个概念:
1.DOM:Document Object Model DOM:浏览器将HTML解析成树形的数据结构,简称DOM。
2.CSSOM:CSS Object Model,浏览器将CSS代码解析成树形的数据结构。
3.Render Tree:DOM树和CSSOM树连接在一起形成(称之为)Render Tree(渲染树)。
3.Layout:计算出Render Tree每个节点的具体位置。
4.Painting:通过显卡,将Layout后的节点内容分别呈现到屏幕上。
二.浏览器渲染过程
1.Create/Update DOM And request css/image/js:浏览器请求到HTML代码后,在生成DOM的最开始阶段(应该是 Bytes → characters 后),并行发起css、图片、js的请求,无论他们是否在HEAD里。
2.Create/Update Render CSSOM:CSS文件下载完成,开始构建CSSOM。
3.Create/Update Render Tree:所有CSS文件下载完成,CSSOM构建结束后,和 DOM 一起生成 Render Tree,Render Tree用来描述所有可见的DOM内容,并且将CSSOM样式信息附加到节点上。
为了形成渲染树,浏览器大致做的事情有:
(1)从DOM树根节点开始,遍历每一个可见的节点
- 一些节点是完全不可见的(比如 script标签,meta标签等),这些节点 会被忽略,因为他们不会影响渲染的输出
- 一些节点是通过CSS样式隐藏了,这些节点同样被忽略——例如某个元素的样式指定为display:none;将被忽略。
- 注意:“visibility:hidden”和“display:none”之间的不同:“visibility:hidden”将元素设置为不可见,但是同样在布局上占领一定空间(例如,它会被渲染成为空盒子),“display:none”的元素是将节点从整个Render Tree中移除,所以不是布局中的一部分 。
(2)对每一个可见的节点,找到合适的匹配的CSSOM规则,并且应用样式
(3)显示可见节点(节点包括内容和被计算的样式)
4.Layout:有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。Layout,顾名思义就是计算出每个节点在屏幕中的位置。
5.Painting:Layout后,浏览器已经知道了哪些节点要显示(which nodes are visible),每个节点的CSS属性是什么(their computed styles),每个节点在屏幕中的位置是哪里(geometry)。就进入了最后一步:Painting,按照算出来的规则,通过显卡,把内容画到屏幕上。
-
以上五个步骤前3个步骤之所有使用 “Create/Update” 是因为DOM、CSSOM、Render Tree都可能在第一次Painting后又被更新多次,比如JS修改了DOM或者CSS属性。
-
Layout 和 Painting 也会被重复执行,除了DOM、CSSOM更新的原因外,图片下载完成后也需要调用Layout 和 Painting来更新网页
三.CSS和JavaScript特性:
1.CSS会并发加载:浏览器解析http response 下载html文件会”自上而下“加载,并在加载过程中进行解析渲染。加载过程中遇到外部css文件,浏览器另外发出一个请求,来获取css文件。这里css解析会生成一个rule tree(规则树),这个以后会更新。
2.JavaScript只能单独加载:当文档加载过程中遇到js文件,html文档会挂起渲染(加载解析渲染同步)的线程,不仅要等待文档中js文件加载完毕,还要等待解析执行完毕,才可以恢复html文档的渲染线程
四.JavaScript有哪些形式,可以放在什么地方?
-
外部引入
<body>...<script src="index.js"></script></body> -
Html内置
<body>
...
<script>
alert(1);
</script>
</body>
注意:根据页面渲染原理和JavaScript单独加载的特性,以上两种形式都需放置在<body>标签内接近闭合标签的地方(head内的js会阻塞页面内容的呈现及渲染,也会阻塞其后组件的下载,会导致“白屏”现象)
五.加载异步
- 加关键字 defer或async,浏览器会立即加载并执行指定脚本,“立即”指的是不等待后续文档载入,读到就加载并执行。
1.async,加载和渲染后续文档元素的过程将和script.js的加载与执行并行进行(异步)。
<script async src="index.js"></script>
2.defer,加载后续文档元素的过程将和script.js的加载并行进行(异步),但script.js的执行要在所有元素解析完成之后DOMContentLoaded事件触发之前完成。
<script defer src="index.js"></script>
defer和async作用:页面引入其他网站代码,引入的代码不会影响当前页面的展现
注意:
defer:脚本延迟到文档解析和显示后执行,有顺序。
async:不保证顺序。
本文配图及部分内容来自于饥人谷,版权归饥人谷_海瀚和饥人谷所有,转载需说明来源
网友评论