【JavaScript】浏览器的解析过程
解析过程
这里省略了浏览器从输入 URL 到拿到 DNS,然后打开网页的过程。
相当于直接就从服务器请求了一个index.html
1. 先写一个导入的 html 看看
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <link rel="stylesheet" href="style.css" /> <!-- 下载的过程 不会阻碍html本身一行行的解析 --> </head> <body> <script></script> <h1>hello javascript</h1> </body> </html> <!-- 1 首先像服务器请求,请求过来的是一份index.html,记住,此时只有一个html文件 2 然后浏览器index.html从上到下一行行解析,看到了link css文件 3 此时会下载css文件,但不会阻止浏览器继续解析html,css也只是下载而已 4 如果此时遇到了script标签 那么就会阻塞html, -->
2. 整体流程
- 下载单个 html
- 逐行解析
- 遇到 link 里的 css 之后另起一个线程下载 + 解析
- 遇到 script 标签直接阻塞,直到 js 下载解析完才行
- 构建 DOM Tree
- css 解析完成之后 构建 CSSOM Tree
- DOM Tree + CSSDOM Tree = Render Tree 此时有了这个 Render Tree。这个时候信息是整体很全的(包裹节点以及样式,但没节点的尺寸和位置信息)。还有由于一些
display:none
等等。此时是不会显示页面上的 - Layout 闪亮登场,来计算一下位置和尺寸信息,layout 里面包含很多位置信息,Render Tree 只有节点和样式而已。
- Layout + Render Tree = Painting 了
- 最后 Display(Painting 绘制到像素点之上,就会 display)
这里有几个难点
Q:就是 Render Tree 最后是不是就是显示在页面上的样子?
A:当然不是了。因为还有 Layout,需要对一些位置和大小信息进行计算,还有一些不需要显示在页面上的,比如display:none
进行计算。
Q:JS 和 CSS 标签会阻碍 DOM 渲染吗?
CSS 并不会组合 DOM Tree 渲染,但是 JS 会。CSS 会组合 Render Tree 渲染,因为 Render Tree 就是 CSSOM+DOM 的合体。
3. 回流(reflow)
为什么会有回流呢?
比如你 JS 操作 dom 了,这一下 DOM Tree 都少了,接下来肯定必须重新计算以后的步骤了。位置也要变。
修改个颜色 color 这样的就不是 reflow,因为位置大小都没变。
<body> <h1>hello javascript</h1> <script> var el = document.querySelector('h1'); el.addEventListener('click', () => { el.remove(); }); </script> </body>
第一次生成页面就是叫 layout 布局
第二次之后都要 reflow 了。
4. 重绘(repaint)
这个其实很好理解,直接和 reflow 对比来看就可以了。
⚠️ 回流一定会触发重绘,而重绘不一定会回流
这肯定的,reflow 发生在位置有变化,位置都变了那么肯定 repaint 了。
但是 repain 有可能只是改个颜色,跟你位置没关系。
5. 合成(composite)
这个其实就类似于 ps 那种一张图片有很多图层 layer,html 显示其实也有的。
我们看到的页面其实是由于多重 layer 才显示出来的。
- 标准流是一个图层
Q:新的 layer 如何创建呢?
以下几个属性可以生成新的 layer
Q:那么如何验证呢?
在浏览器的工具类
写一个验证一下多重 layer
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> .box { width: 200px; height: 200px; background-color: gold; } .h2 { /* fixed会生成新的图层,absolute不会 */ background-color: pink; position: fixed; } </style> </head> <body> <div class="box"></div> <div class="h2">h2</div> </body> </html>
那么如何优化呢?
多了一层 layer 会在另一层,这样就不会影响标准流的那一层的位置等等信息,性能上可能会好一点,但也不是什么都要新建一层,因为内存和浏览器还需要点性能。还是要看情况的。
共有评论(0)