浏览器解析html相关

浏览器解析html步骤

  • 浏览器通过DNS服务器得到域名的IP地址,向这个IP地址请求得到HTML文本
  • 浏览器渲染进程解析HTML文本,构建DOM树
  • 解析HTML的同时,如果遇到内联样式或者样式文件,则下载并构建样式规则,如果遇到JavaScript脚本,则会下载执行脚本
  • DOM树和CSSOM构建完成之后,渲染进程将两者合并成渲染树(render tree)
  • 渲染进程开始对渲染树进行布局,生成布局树(layout tree)
  • 渲染树对布局树进行绘制,生成绘制记录
    在这里插入图片描述

解析方式

html解析

逐行解析 遇到引入资源马上去下载引入(不阻塞) js马上执行(阻塞DOM解析)

css解析

从右往左解析选择器

易错问题

CSS不会阻塞DOM的解析,但会阻塞DOM的渲染

因为CSS需要和DOM解析完成之后的DOM树结合成渲染树。阻塞渲染是因为CSS树和DOM树合成渲染树之后,才要进行渲染。

CSS会阻塞JS执行,但不会阻塞JS文件的下载

JavaScript线程与UI线程是互斥的,如果不互斥,js中涉及到对样式的增删改,css又同事对该元素样式进行绘制,会发生不可预料的错误。

JS需要等待CSS的下载

如果JS脚本的内容是获取元素的样式,那它就必然依赖CSS。因为浏览器无法感知JS内部到底想干什么,为避免样式获取,就只好等前面所有的样式下载完毕再执行JS。但JS文件与CSS文件下载是并行的,CSS文件会在后面的JS文件执行前先加载执行完毕,所以CSS会阻塞后面JS的执行

JS会阻塞页面吗?

JS会阻塞DOM的解析,因此也就会阻塞页面的加载
由于 JavaScript 是可操纵 DOM 的,如果在修改这些元素属性同时渲染界面(即 JavaScript 线程和 UI 线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。

defer和async的区别?

两者都是异步去加载外部JS文件,不会阻塞DOM解析

  • Async是在外部JS加载完成后,浏览器空闲时,Load事件触发前执行,标记为async的脚本并不保证按照指定他们的先后顺序执行,该属性对于内联脚本无作用 (即没有**「src」**属性的脚本)。
  • defer是在JS加载完成后,整个文档解析完成后,触发 DOMContentLoaded 事件前执行,如果缺少 src 属性(即内嵌脚本),该属性不应被使用,因为这种情况下它不起作用

重排和重绘

  • 重排:当某个元素的大小、位置发生了变化时,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树;
  • 重绘:当某个元素的字体颜色等不影响布局的属性变化时,不需要重新构建渲染树,只需直接重新绘制页面即可;

下面HelloWorld如何输出

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>测试</title>
    </head>
    <body>
        <h1>Hello</h1>
        <script type="text/javascript">
            let i = 1000000000
            while(i>0){
                i-- 
            }
        </script>
        <h1>world</h1>
    </body>
</html>

一开始渲染进程的HTML 解析器开始解析DOM,当解析到内联script 脚本标签时,HTML 解析器会暂停解析DOM,此时JavaScript 引擎介入,并执行内联script 标签中的这段脚本,脚本执行完成之后,HTML 解析器恢复解析过程,继续解析DOM,然后进行后续的渲染,最终将页面上同时渲染出 Hello World

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>测试</title>
    </head>
    <body>
        <h1>Hello</h1>
        <script type="text/javascript" src="index.js"></script>
        <h1>world</h1>
    </body>
</html>

先渲染出Hello ,然后过一会儿(这个期间在执行js),再渲染出World

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值