# css从入门到入门---3更

**URL:** <https://www.shiqidu.com/t/topic/775>\
**Category:** 开发调优\
**Tags:** CSS\
**Created:** [2022 年2 月 21 日 13:39 UTC](https://www.shiqidu.com/t/topic/775 "2022-02-21T13:39:00Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

作者： ![shanliren](https://www.shiqidu.com/user_avatar/www.shiqidu.com/shanliren/32/952_2.png) [@shanliren](https://www.shiqidu.com/u/shanliren)\
发布日期： [2022 年2 月 21 日 13:39 UTC](https://www.shiqidu.com/t/topic/775/1 "2022-02-21T13:39:00Z")

</div>

### 页面从服务器访问回来后，浏览器拿到页面源代码之后做的一些事情

#### 具体处理

```css
1、生成dom Tree ==> 对html处理
		+ 基于http获取的流文件（进制编码）
		+ 把进制编码编译为具体的字符
		+ 按照token进行解析（词法解析）
		+ 生成具体的节点（元素节点、文本节点。。。）
		+ 按照相互的嵌套关系生成一个dom树（节点树）
		
2、生成CSSOM TREE ==>对css处理(css tree 得生成可dom tree 生成细节大致一样)

3、生成rendertree （渲染树）
		+ css tree + dom tree = render tree
		+ 对与开始设置为 display：none 的元素是不会在渲染树中生成的（开始加载页面这些元素不会被渲染）
		
4、布局、重流、重排 Layout
		+ 按照渲染树，计算出每一个元素在视口中具体的位置和大小
		
5、分层
		+ 按照计算出来的层级进行分层
		+ 单独计算出每一层的绘制列表（具体怎么绘制）
		
---------------------------------> 以上的操作都是交给GUI渲染线程来完成的

6、绘制、重绘
		+ 把生成的绘制列表交给‘’合成线程‘’
		+ 合成线程进行我们最后的绘制，呈现在浏览器上

```

#### 浏览器具体的解析过程 ‘GUI’渲染线程：

```css

关键节点优化

1、自上而下解析完所有的html标签/各种节点后，dom tree 就生成了
2、但是过程遇到特殊的情况

                                                                css
---- link href 外链式导入资源
--------浏览器会分配一个新的Http网络线程去加载资源
--------不会阻碍dom树的解析
---- 遇到《style》
--------不会请求资源了，但是此时样式还没有处理，浏览器会做一个记录，他会等待所有的css资源加载回来以后，
            按照先后顺序，依次渲染css
---- 遇到@import
--------虽然会分配http网络线程加载资源
--------但是此时gui渲染线程会被阻塞，阻碍dom树渲染，只有等资源加载回来，才会继续渲染dom

                                                                    js
---- 遇到script 内嵌js代码的
--------立即执行js ，阻碍dom树渲染，

---- 遇到外联script 外联js代码
--------阻碍dom书渲染，同时分配一个http线程加载资源文件
--------加载回来立即执行js
--------如果js中没有采用异步，直接获取dom元素，如果dom元素还没有渲染，js是获取不到的(放在页面底部)

                                                                    图片
---- 遇到img
--------老版本浏览器阻碍dom树渲染
--------新版本浏览器虽然不会阻碍dom渲染，但是图片资源请求会占用http线程，但是浏览器只能开
			6-7个http线程，这样图片、音视频资源加载本来很慢，会影响其他资源（link/script）的加载
--------图片资源渲染也比一般的资源耗时，也会拖累页面的渲染速度

css性能优化针对以上几个关键节点

```

#### css性能优化

```css
1、不适用import
2、link放在header中
	dom渲染完成，css资源也加载回来了，
	当代浏览器扫描 src、link标签，避免加载资源等待时间，实现提前加载及加载执行的分离
3、css代码少用内嵌式，减少http请求，如果样式多，第一次加载html费时，不如用link分开加载(移动端开发内嵌优先)
4、减少DOM或者dom层级嵌套，以及标签语义化（不是语义化，会做特殊处理），
	---第一次只加载首屏结构或者内容，页面滚动时候，在基于js创建其他屏幕的结构和内容，
	---骨架屏/ssr=》客户端骨架屏，开始首屏结构都没有，只有一个laoding或者占位图而已....
5、	吧script标签放到底部(先渲染dom tree， 在执行js，不会阻碍dom树渲染，也可以获取到dom元素),
     也可以基于事件domcontentloaded/load等到结构加载完再去获取dom元素
6、async defer 给script设置属性
		async 是开辟http线程加载资源文件，此时dom tree继续，但是资源文件一旦加载回来，停止dom树，先执行
		js代码(不考虑js引入顺序，谁先加载回来先执行谁)
		defer 也是开辟http线程加载资源文件，既是资源文件加载回来，也会等待dom 树渲染完，按照js的引入顺序依次
		执行js（不兼容低版本浏览器）
7、图片合并（Spirit、只请求一次就行）/ base64(好用慎用，浏览器直接识别，不需要再请求资源，编码，省了好多) / iconfont（css绘制） / svg
	===> 图片的懒加载

```

### 如何减少回流重绘

```css
传统dom消耗性能: DOM的回流(重排)和重绘

回流: 页面布局或者几何信息发生变化，浏览器可能需要重新创建dom或者重新计算每一个元素在视口
中的位置和大小，重新layout，重新计算完之后，让浏览器重新渲染

====> 回流必然引起重绘

 回流
 --->dom增删改
 --->dom样式如宽高、大小、位置发生改变
  --->内容发生变化
 --->浏览器窗口发生变化
 --->页面第一次加载
 
 
 重绘: 元素样式发生改变，但是几何信息和结构信息没有变化，不需要回流，只要浏览器把改变的元素重新渲染就行
  --->color
 --->background-color
 
 避免回流：
 --->放弃传统dom操作,基于vue、react开始数据影响试图
 --->读写分离，现代浏览器有渲染队列机制，如offsetTop、clientWidth、等
 --->样式集中改变（渲染队列）
 
 --->缓存布局信息---使用变量
--->元素批量修改---文档碎片（createDocumentFragment）、模板字符串拼接等

 --->动画应用到position为fixed、absolute元素上(脱离文档流，只在当前层处理)
 --->transform，基于transform修改元素的样式，会直接跳过render tree 和 layout阶段，
		 直接把更改的样式告诉合成线程去渲染，不会引发回流，只会重绘----开启了渲染的硬件加速
 --->css3硬件加速transform、opacity、filters...这些属性会触发硬件加速，不会引发回流重绘
		 但是占用大量内存，性能消耗严重，有时候导致字体模糊等
 --->牺牲平滑度换取速度，
		 每次1像素移动一个动画，如果此动画使用了100%CPPU，动画看上去是跳动的，因为浏览器正在
		 与更新回流作斗争，每次移动3像素，平滑度可能降低了，但是他不会导致cpu在较慢的机器中抖动
--->避免table布局和使用css的javascript表达式
 --->

```

#### onload 和 DOMContentLoaded 区别

```css

window.onload 所有资源都加载完成,（包含DOM TREE/CSS/图片资源等）
DOMContentLoaded 触发条件 DOM tree 加载完成即可

```

### 进程和线程

```css

进程：一个程序（浏览器新建一个也卡就是一个进程) --------------------------->工厂
线程：一个进程中可能包含多个线程，每一个线程可以同时做一件事情-----------> 工人

真正同时做多件事情，必须依赖多线程（浏览器）是多线程的 
		+ 但是JS本身是单线程的(因为浏览器本身只分配一个线程 GUI渲染线程 运行JS代码
				+ 同步： 上一件事情完成，再去做下一件事情
				+ 异步： 上一件事情没有完成，（我们做一些特殊处理），下一件事情据需执行（但是绝对不是JS可以同时处理两 
								 个事情
		+ 浏览器生成DOM TREE CSSOM TREE....的过程也是单线程的（配合浏览器的多线程去完成一些事情，例如：资源请求
			就是利用浏览器的HTTP网络线程去做的)		

```

### 

```css

```

### 

```css

```

### 

```css

```

### 

```css

```

### 

```css

```
