zoukankan      html  css  js  c++  java
  • CSS动画属性/重绘重排组合层/GPU加速 渲染优化相关及联系

    1、现代浏览器,比如chrome,firefox都支持硬件加速,GPU加速功能,开启后,使用相关CSS属性,3D API,canvas等,都会默认用GPU渲染的方式去绘制图像。

    浏览器渲染的过程,网上图片杂且准确性出处都有待考究,关于这个过程和原理,国外有一个最权威的文档资料:链接
    (差不多网上的文章都是从这里盗的内容了),浓缩一下流程,可以概括为:
    在这里插入图片描述
    1)可以看到DOM Tree 是由HTML等标签和Script的构建的,然后是解析Scipt标签,这里并行,异步,还是阻塞,可以通过script的async defer来控制,没有加这些默认是会阻塞DOM Tree的构建。

    2)解析完成后,浏览器引擎会通过DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree。
    CSS 的 Rule Tree主要是为了完成匹配并把CSS Rule附加上Rendering Tree上的每个Element。也就是DOM结点。也就是所谓的Frame。(这里的Rendering Tree和Frame的叫法查资料是分别在WebKit和Gecko内核的两种叫法)
    然后,计算每个Frame(也就是每个Element)的位置,这又叫layout或者reflow过程。(layout是Webkit的叫法,reflow是Gecko的叫法)

    3)最后通过调用操作系统Native GUI的API绘制。

    2、上面是浏览器的过程,这里再重点说绘制像素前的关键的两个概念,回流Reflow(也叫重排),重绘Repaint。

    Repaint——屏幕的一部分要重画,比如某个CSS的背景色变了。但是元素的几何尺寸没有变。

    Reflow——意味着元件的几何尺寸变了,我们需要重新验证并计算Render Tree。是Render Tree的一部分或全部发生了变化。这就是Reflow,或是Layout。(HTML使用的是flow based layout,也就是流式布局,所以,如果某元件的几何尺寸发生了变化,需要重新布局,也就叫reflow)reflow 会从这个root frame开始递归往下,依次计算所有的结点几何尺寸和位置,在reflow过程中,可能会增加一些frame,比如一个文本字符串必需被包装起来。

    Reflow的成本比Repaint的成本高得多的多。DOM Tree里的每个结点都会有reflow方法,一个结点的reflow很有可能导致子结点,甚至父点以及同级结点的reflow。在一些高性能的电脑上也许还没什么,但是如果reflow发生在手机上,那么这个过程是非常痛苦和耗电的。(之前强哥就说用了容易引起reflow的方式做动画最后手机表现上很卡)

    reflow肯定会引起repaint(注:display:none会触发reflow,而visibility:hidden只会触发repaint,因为没有发现位置变化。)

    3、一个可能会引起你惊讶的消息是,当你获取请求DOM的一些值的时候也会立即引起reflow:

    	offsetTop, offsetLeft, offsetWidth, offsetHeight
    	scrollTop/Left/Width/Height
    	clientTop/Left/Width/Height
    	IE中的 getComputedStyle(), 或 currentStyle
    

    到底那些会引起浏览器的这些过程,除了靠经验和想象,也可查:
    https://gist.github.com/paulirish/5d52fb081b3570c81e3a

    哪些CSS属性会引起reflow还是repaint,会不会走GPU加速,在不同浏览器会不会有差异,这些可查:https://csstriggers.com (神站!)

    4、浏览器在每一帧中,都要经过下列动作

    在这里插入图片描述

    所有的渲染对象都有一个layout或reflow方法,每个渲染对象调用需要布局的children的layout方法。
    (JavaScript和Style可以看做dom解析和样式表解析并合并render tree的过程)
    减少layout(这个应该就是重排回流动作),paint(这个当重新渲染的时候就对应重绘操作),就尽量应该让属性引起的变化在Composite过程完成,也就是组合层,也叫渲染层合并,按照合理的顺序合并图层然后显示到屏幕上。

    利用 GPU 加速优先使用渲染层合并属性,避免 layout,paint。

    例如一个网页的加载过程:
    在这里插入图片描述

    可以在上面看到,transform这个属性过程是在Composite过程完成,相当于自己提升(创建)了一个图层,最后合并,没有影响之前的图层,不会引起layout和paint了,这样动画效果更加流畅。

    打开chrome工具rendering的layer Borders可以看到很多边框和栅格,

    黄色边框:有动画 3d 变换的元素,表示放到了一个新的复合层(composited layer)中渲染

    蓝色的栅格:这些分块可以看作是比层更低一级的单位,这些区域就是 RenderLayer

    打开一个页面,如果该页面的黄色边框很多,那么肯定要查看一下原因了

    打开csstrigers网站,查询transform,可以看到
    在这里插入图片描述
    在这里插入图片描述
    在Blink Chrome浏览器和WebKit火狐浏览器上都是在Composite上完成的。“更改变换不会触发任何几何更改或绘制,这非常好。这意味着该操作可能由合成器线程在GPU的帮助下执行。”

    参考:https://aotu.io/notes/2017/04/11/GPU/index.html

    5、CSS会不会阻塞DOM解析/DOM渲染/浏览器渲染?

    这个问题在实际表现中其实复杂,参考:链接

    这位博主也只是列出了几种情况下的表现,总结为:

    1. CSS加载不阻塞DOM解析。DOM解析和CSS解析是两个并行的进程。

    2. CSS加载会阻塞DOM的渲染。由于Render Tree是依赖于DOM Tree和CSSOM Tree的,所以他必须等待到CSSOM Tree构建完成,也就是CSS资源加载完成(或者CSS资源加载失败)后,才能开始渲染。

    3. CSS会阻塞后面js的执行。由于js可能会操作之前的Dom节点和css样式,因此浏览器会维持html中css和js的顺序。因此,样式表会在后面的js执行前先加载执行完毕。所以css会阻塞后面js的执行。

    写到这里,就不得不提下浏览器中的一个生命周期事件:DOMContentLoaded

    6、关于DOMContentLoaded

    首先看看MDN上的定义:

    当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载。另一个不同的事件 load 应该仅用于检测一个完全加载的页面。 在使用 DOMContentLoaded 更加合适的情况下使用 load 是一个令人难以置信的流行的错误,所以要谨慎。注意:DOMContentLoaded 事件必须等待其所属script之前的样式表加载解析完成才会触发。

    看看,一下子就把上面联系起来了,举了一个例子:
    在这里插入图片描述
    如果script前有CSS的link,那么这个事件就会在3秒css解析完才会触发执行。如果link放在之后,就会立即执行打印。

    解释:
    因为js会阻塞DOM解析,DOMContentLoaded是在DOM解析完成后才触发。因此,当css后面有js的时候,css会阻塞js运行,而js会阻塞DOM解析,从而导致DOMContentLoaded必须等到css以及css后面的js执行完成后,才会触发。(而当css后面没有js的时候,由于css不阻塞DOM的解析,因此DOMContentLoaded不会等待css的加载。)

    需要注意的是,现在我们一般把script放在body的最后,如果这块的script含有对DOMContentLoaded事件的监听回调函数,那么就不合理了,因为放在最后的这块一定会被head的CSS link所阻塞。解决方法是把DOMContentLoaded监听回调函数单独放在一个script放在head的所有link CSS之前。或者用新H5 API defer和asyc script解决(未验证)。

  • 相关阅读:
    四瓶化学试剂合成了人工生命
    DNA 就是软件代码
    首例人造生命,碱基对达到100多万个
    看到一个新闻管理系统,看上去开源,其实是骗你使用
    日本可合成碱基对 遗传信息"无中生有"
    新生命如何在实验室“被创造”
    一个基因有多少碱基对
    A、T、G、C四个字母(构成碱基的基本单位)的不同排列,画出一张基因图谱
    远程图片下载不能显示的问题
    30亿个碱基对组成,分布在细胞核的23对染色体中
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/11443269.html
Copyright © 2011-2022 走看看