你们好,林三心又来了。看了十几遍
《康熙王朝》
和《雍正王朝》
,今天,就给你们讲讲“九龙夺嫡”
的那些事,顺便讲讲浏览器渲染
(实际上是讲浏览器渲染
,顺便讲讲“九龙夺嫡”
,嘿嘿),以为讲得好记得给个赞
哦。css
毕竟,我也是一个有梦想的做者呢!html
请记住对应的关系哦,有利于后面更好地理解模块之间的关系jquery
提及我们的康熙大帝啊,那可就牛逼了,擒鳌拜,平三番,远征葛尔丹。可是也不耽误他风流啊。“九子夺嫡”,说白了就是九个臭小子互相干架争本身老子的皇位,那也怪不得这些臭小子啊,谁叫康熙大帝生那么多呢?固然,九子中最突出的那几个分别是大阿哥胤禔(HTML解析器),老三胤祉(绘图模块),老四胤禛(JS引擎),老八胤禩(CSS解析器),老十三(布局Layout模块)
webpack
HTML标签
,顺便解析内联style标签
里的样式,构建DOM树
link
标签里的外联漂亮样式,构建CSS树
样式
和DOM节点
(增删改查或者绑定事件)DOM树
和CSS树
合并,并制成一张布局图纸
(不负责渲染,只提供图纸)图纸
,并绘制
出来给大伙看看如下内容以前,你们要先明白一个道理:
解析
和渲染
是两个过程,解析
了不必定会渲染
(也就是你还看不到页面效果),渲染
了说明解析
完了,这就比如:你有了钱(解析
)不必定会去买别墅(渲染
),可是若是你买了别墅(渲染
)那说明你是真的有钱(解析
)web
<style>
// 6万行css样式
.box { background: red } // 最后一行
</style>
<div class="box"></div>
<div></div>
<div></div>
<div></div>
复制代码
- 问: HTML解析器负责解析
HTML标签
,顺便解析内联style标签
里的样式,那么问题来了:style标签里有6万多行样式,会由于解析得太慢,而致使后面的div标签都没法解析而且渲染吗?
- 答:
不会
,HTML解析器是异步解析
的,而且不
阻塞渲染
。大阿哥(HTML解析器)从上往下走,碰到了style标签,发现里面实在是太多样式了,判断须要解析好久,便派了四个小兵,先去解析下面的四个div标签并先渲染出来,提升效率。
- 形成的问题: 因为style里太多样式,因此小兵们解析渲染div标签完,大阿哥却还未解析完style里的样式,因此class="box"的div标签先渲染出来(无样式),等大阿哥解析完style标签,才会把.box的样式赋给这个渲染出来的div标签,这就致使了这个div标签在页面上出现了
无样式 -> 有样式
的效果,也就是所谓的闪屏现象
- 如何解决问题: 少用style内联标签,大阿哥要带兵解析HTML已经够累了,你还让他去解析style标签,不形成'闪屏现象'才怪
// index.css里
// 6万行css样式
.box { background: red } // 最后一行
// html代码
<link href="index.css"></link> // 引入 <div class="box"></div>
<div></div>
<div></div>
<div></div>
复制代码
- 问: CSS解析器负责解析
link
标签里的外联样式,那么问题来了:link标签外联样式有6万多行,会由于解析得太慢,而致使后面的div标签都没法解析而且渲染吗?
- 答:
不会
阻塞后面div标签的解析
,可是会
阻塞后边div标签的渲染
,也就是说,CSS解析器
在解析link标签里这6万行样式的同时,HTML解析器
已经带了几个小兵去把下面的div标签全解析了,但只是解析了,并未渲染出来,等到CSS解析器
把6万行样式解析完,再一次性合并CSS树
和DOM树
并渲染到页面上去
- 为何: 由于这么作能够避免
闪屏现象
并提升渲染性能
。上面说了闪屏现象
就是页面上出现了无样式 -> 有样式
的效果,体验不好,因此如何避免呢?最好的办法就是等到最终的DOM树
与最终的CSS树
结合完,再一次性渲染上去,这样页面就不会出现无样式 -> 有样式
这样的问题了。屡次的渲染如今变成了一次性渲染,那天然是提升了渲染的性能。
- 形成的问题: 若是CSS解析器解析的太慢,那么页面就一直没法完成最终渲染,也就会出现一小段时间
白屏现象
- 如何解决问题: 核心就是加快外联样式的加载速度:
- 使用CDN节点进行外部资源加速
- 对外部样式文件进行压缩(使用打包工具,例如webpack,gulp等)
- 优化你的样式文件的代码
// index.js文件
// 6万多行代码,对dom进行了一系列操做
// html页面
<script src="index.js"></script> // 引入 <div id="box"></div>
<div></div>
<div></div>
<div></div>
复制代码
- 问: JS引擎暗地里操纵各类
样式
和DOM节点
(增删改查或者绑定事件),会由于执行script标签的引用代码太慢,而致使后面的div标签都没法解析而且渲染吗?
- 答:
会
阻塞后面div标签的解析和渲染,等到JS引擎
把全部JS代码加载
并执行
完成,才会放HTML解析器
往下解析DOM,而且一次性渲染出来
- 为何: 举个反例,在四阿哥(JS引擎)缓慢地执行这6万行代码同时,康熙命令大阿哥(HTML解析器)不要管四阿哥,大胆地往下解析HTML,大阿哥立刻带着本身的小兵们立刻解析完全部div标签,而后满怀成就感地想跑去康熙面前请功领赏,而此时四阿哥还未执行完他的JS代码,大阿哥跑啊跑啊,跑到康熙面前的一瞬间,四阿哥恰好执行完JS代码,并把大阿哥刚刚解析完的全部标签都删了(毕竟四阿哥拥有操控DOM的能力啊),康熙一看,雷霆大怒:“WDNMD!!!老大,你不是说都解析好了吗?在哪呢??敢骗老子?”对着大阿哥一顿臭骂。大阿哥心想:“老四,WDNMD,敢把老子解析的成功给删了!”后来康熙得知后,便制定了一套规则:之后四阿哥先执行代码,而后再派大阿哥去解析HTML,这样大阿哥就不会作无用功啦!
- 问题: 若是JS代码执行报错或者执行过慢,那么后面的HTML就会永远没法解析了,那么页面有可能就一直是一片空白。
- 如何解决问题: 核心就是改变JS代码的执行顺序,或者优化JS执行速度:
<script async></script>
加上async
属性,JS代码会异步加载并执行(多script标签状况下,并不会按着script在页面中的顺序来执行,而是谁先加载完谁执行)<script defer></script>
加上defer
属性,JS代码会异步加载(若是有多个设置了defer的script标签存在,则会按照顺序执行全部的script,会在DOMCotentLoaded
前执行)- 把script标签放在页面尾部
- 优化JS代码,加快执行速度
跟上面
HTML解析器和JS引擎
同理,只不过是DOM树
和CSS树
的区别gulp
<script src="jquery.js"></script>
<script src="bootstrap.js"></script>
复制代码
会先执行完上边script再执行下边script,由于有可能下边的script依赖于上边的script代码(上方例子,bootstrap依赖于jquery)bootstrap
<script src="index1.js"></script>
<script src="index2.js"></script>
<div></div>
复制代码
会先执行完上边script再执行下边script,由于上方script可能修改dom,下方也修改dom,那确定是排队一个一个来,否则就乱套了浏览器
<script src="index1.js" defer></script>
<script src="index2.js" defer></script>
复制代码
会异步加载,也就是下方可能比上方加载更快,可是最终代码执行仍是会按顺序由上往下,而且在DOMContentLoaded以前执行markdown
<script src="index1.js" async></script>
<script src="index2.js" async></script>
复制代码
会异步加载并异步执行,也就是谁先加载完谁就先执行,不按顺序app
问:为何CSS解析器只能阻塞HTML渲染但不能阻塞HTML解析,但JS引擎却能同时阻塞HTML的解析和渲染呢?
答:由于CSS并不能操做DOM啊,因此也不必阻塞HTML解析。可是JS引擎就不同了,能随意操做DOM,因此须要阻塞HTML解析,避免HTML解析器作无用功。
再来看看渲染大体过程:
DOMContentLoaded
发生在这onload
发生在这
JavaScript
是浏览器中运行的大脑,最能获得浏览器(康熙)青睐的确定是JavaScript(四阿哥),因此最后确定是四阿哥胤禛
胜出啦,恭喜雍正帝
!
雍正也是我很喜欢的一位,
推行新政
,火耗归公
,摊丁入亩
,士绅一体当差一体纳粮
,派年羹尧平定罗布赞旦增阿拉布坦叛乱
等等,都很出色!
感兴趣的能够去看看
《雍正王朝》
,和《大明王朝》
并列为中国古装剧的巅峰之做!