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

22-02-21 21:39 字数 3932 阅读 1564 已编辑

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

具体处理

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’渲染线程:


关键节点优化

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性能优化

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
    ===> 图片的懒加载

如何减少回流重绘

传统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 区别


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

进程和线程


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

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

0人点赞>
关注 收藏 改进 举报
0 条评论
排序方式 时间 投票
快来抢占一楼吧
请登录后发表评论