回流与重绘理解,助攻CSS

摘要:
回流和重画是HTML渲染中的重要概念,但浏览器回流似乎不会以人眼的感官速度改变。事实上,每次回流都会清空页面,触发浏览器回流并重新生成渲染树。回流意味着节点的几何属性发生变化。回流重画实际上与浏览器的事件周期有关。浏览器刷新频率为60Hz。

HTML渲染过程中回流和重绘是比较重要的概念,了解他们有助于编写性能更好的css代

回流:指几何属性需改变的渲染,将整个网页填白,对内容重新渲染,只不过以人眼的感官速度看上去浏览器回流是不会有任何变化的
实质上每次回流都会将页面清空,再从左上角第一个像素点从左往右从上往下一一渲染。
渲染树的节点发生改变,影响该节点的几何属性,导致该节点位置发生变化,就会触发浏览器回流并重新生成渲染树。
回流意味着节点的几何属性发生改变,需浏览器重新计算并生成渲染树,渲染树会发生全部或者局部变化。

:重绘是指外观属性而不影响集合属性的渲染。重绘较回流相对温和些。
渲染树节点改变,但不影响该节点的几何属性,回流较重绘消耗性能要高些,并且回流一定伴随重绘,重绘不一定有回流。

上面有讲几何属性和外观属性,可能有些童鞋不清楚

  • 几何属性:包括布局、尺寸等可用数学几何衡量的属性
    • 布局:displayfloatpositionlisttableflexcolumnsgrid
    • 尺寸:marginpaddingborderwidthheight
  • 外观属性:包括界面、文字等可用状态向量描述的属性
    • 界面:appearanceoutlinebackgroundmaskbox-shadowbox-reflectfilteropacityclip
    • 文字:textfontword

给一个比较好记忆的理解吧:大家喜欢喝奶茶吧,我最喜欢的是一点点奶茶茶,相信很多人喜欢,不然怎么生意好到爆,排队排的老长了,

突然又问素质较低的小伙子,插队了,引起后面的小哥强烈不满,两人你推我搡的快打起来了,幸好店长劝和,大家有重新排队,这个过程就跟回流差不多,

大家重新排队影响了大家的时间,怨声载道的,然后又来了一个帅帅的小哥哥,心疼女朋友排队站的太久脚痛,替她排队买,这样皆大欢喜,他女朋友也高兴,大家也不用重新排队

这个过程除了妹纸,其余人的位置和顺序都无发生变化,跟重绘差不多。

这样我们得出了个性能优化法则:回流必定引发重绘,重绘不一定引发回流

很多童鞋可能不知,回流重绘其实与浏览器的事件循环有关

  • 浏览器刷新频率为60Hz,即每16.6ms更新一次
  • 事件循环执行完成微任务
  • 判断document是否需更新
  • 判断resize/scroll事件是否存在,存在则触发事件
  • 判断Media Query是否触发
  • 更新动作并发送事件
  • 判断document.isFullScreen是否为true(全屏)
  • 执行requestAnimationFrame回调
  • 执行IntersectionObserver回调
  • 更新界面

 上述就是浏览器每一帧中可能会做到的事情,若在一帧中有空闲时间,就会执行requestIdleCallback回调。

 回到正题,通过定向法则回流必定引发重绘,重绘不一定引发回流可知道,尽量减少回流重绘,就是CSS性能优化中一个很好的指标。

如何减少和避免回流重绘?

  1. 使用visibility:hidden替换display:none;
  2. 使用transform代替top;top是几何属性,操作top会改变节点位置从而引发回流,使用transform:translate3d(x,0,0)代替top,只会引发图层重绘,还会间接启动GPU加速,该情况在第12章变换与动画中会详细讲解。

  3. 避免使用Table布局
  4. 避免规则层级过多。浏览器的CSS解析器解析css文件时,对CSS规则是从右到左匹配查找,样式层级过多会影响回流重绘效率,建议保持CSS规则在3层左右。
  5. 避免节点属性值放在循环里当成循环变量

  6. 动态改变类而不改变样式。不要尝试每次操作DOM去改变节点样式,这样会频繁触发回流。
  7. 将频繁回流重绘的节点设置为图层

CSS编码排序推荐:

根据回流和重绘原理。涉及到几何属性和外观属性,结合盒模型规范和从外到里进行属性排序,将一些回流的几何属性排在最前面,决定布局尺寸相关的
状态,在添加外观属性,布局》尺寸》界面》文字》交互 的方式定义顺序,交互的属性放在最后,如transform混入animation会让节点重新生成图层,
图层不会对其他图层造成影响。
如建楼一样:从无到有,从打(存在)、搭(布局)、主(尺寸)、砌体(界面)、装修(文字)、装潢(交互)到验收(生成一个完整的节点),
每一步都基于前一步作为基础才能继续下去,符合我们正常的逻辑思维。
借鉴太极哲学思想:太极生两仪,两仪生四象,四象生八卦,从无极生太极开始,一直通过物质派生而构筑一个完整的立体结构,
这一过程是一个立体并包含位次顺序的四维关系。

布局属性

  • 显示:displayvisibility
  • 溢出:overflowoverflow-xoverflow-y
  • 浮动:floatclear
  • 定位:positionleftrighttopbottomz-index
  • 列表:list-stylelist-style-typelist-style-positionlist-style-image
  • 表格:table-layoutborder-collapseborder-spacingcaption-sideempty-cells
  • 弹性:flex-flowflex-directionflex-wrapjustify-contentalign-contentalign-itemsalign-selfflexflex-growflex-shrinkflex-basisorder
  • 多列:columnscolumn-widthcolumn-countcolumn-gapcolumn-rulecolumn-rule-widthcolumn-rule-stylecolumn-rule-colorcolumn-spancolumn-fillcolumn-break-beforecolumn-break-aftercolumn-break-inside
  • 格栅:grid-columnsgrid-rows

尺寸属性

  • 模型:box-sizing
  • 边距:marginmargin-leftmargin-rightmargin-topmargin-bottom
  • 填充:paddingpadding-leftpadding-rightpadding-toppadding-bottom
  • 边框:borderborder-widthborder-styleborder-colorborder-colorsborder-[direction]-<param>
  • 圆角:border-radiusborder-top-left-radiusborder-top-right-radiusborder-bottom-left-radiusborder-bottom-right-radius
  • 框图:border-imageborder-image-sourceborder-image-sliceborder-image-widthborder-image-outsetborder-image-repeat
  • 大小:widthmin-widthmax-widthheightmin-heightmax-height

界面属性

  • 外观:appearance
  • 轮廓:outlineoutline-widthoutline-styleoutline-coloroutline-offsetoutline-radiusoutline-radius-[direction]
  • 背景:background
  • 遮罩:maskmask-modemask-imagemask-repeatmask-repeat-xmask-repeat-ymask-positionmask-position-xmask-position-ymask-sizemask-originmask-clipmask-attachmentmask-compositemask-box-imagemask-box-image-sourcemask-box-image-widthmask-box-image-outsetmask-box-image-repeatmask-box-image-slice
  • 滤镜:box-shadow box-reflect filter mix-blend-mode opacity,
  • 裁剪:object-fit clip
  • 事件:resize  zoomcursor  pointer-events  touch-callout user-modify  user-focus user-input user-select user-drag

文字属性

  • 模式:line-heightline-clampvertical-aligndirectionunicode-bidiwriting-modeime-mode
  • 文本:text-overflowtext-decorationtext-decoration-linetext-decoration-styletext-decoration-colortext-decoration-skiptext-underline-positiontext-aligntext-align-lasttext-justifytext-indenttext-stroketext-stroke-widthtext-stroke-colortext-shadowtext-transformtext-size-adjust
  • 字体:srcfontfont-familyfont-stylefont-stretchfont-weightfont-variantfont-sizefont-size-adjustcolor
  • 内容:overflow-wrapword-wrapword-breakword-spacingletter-spacingwhite-spacecaret-colortab-sizecontentcounter-incrementcounter-resetquotespagepage-break-beforepage-break-afterpage-break-inside

交互属性

  • 模式:will-changeperspectiveperspective-originbackface-visibility
  • 变换:transformtransform-origintransform-style
  • 过渡:transitiontransition-propertytransition-durationtransition-timing-functiontransition-delay
  • 动画:animationanimation-nameanimation-durationanimation-timing-functionanimation-delayanimation-iteration-countanimation-directionanimation-play-stateanimation-fill-mode

在此已经整合了大部分的属性,可满足大部分的属性排序。其他未列入的属性,可根据自身使用习惯添加。分类只提供参考

文章仅为学习笔记,无写作艺术,仅供大家参考。

免责声明:文章转载自《回流与重绘理解,助攻CSS》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ORACLE ROWNUM解析[转]Java Web基础 --- Servlet 综述(理论篇)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SSIS 处理错误的方法

Package在执行过程中,不可避免地会发生错误,如果处理错误?简单粗暴的做法,是Package直接停止运行。对于一个成熟的ETL工具,这显然不是唯一的错误处理方法。如果在数据流中出现错误,那么数据流组件可以把错误行输出,这只需要在组件的ErrorOutput中进行简单地配置。跟数据流相比,控制流中包含错误处理程序OnError,对错误事件的处理更加复杂和...

iOS开发之使用Runtime给Model类赋值

  本篇博客算是给网络缓存打个基础吧,本篇博客先给出简单也是最容易使用的把字典转成实体类的方法,然后在给出如何使用Runtime来给Model实体类赋值。本篇博客会介绍一部分,主要是字典的key与Model的属性名相同时,使用Runtime来进行赋值,下篇博客会给出字典key的值和Model的名字不同时的解决方案,并给出使用Runtime打印实体类属性值的...

html声明charset="utf-8"后,浏览器访问中文依旧乱码(绝对有效)

    1.情景展示   html文件已经声明字符集为UTF-8,但是浏览器访问依旧乱码。   标题和页面内容都是乱码,这是怎么回事? 2.原因分析    charset="UTF-8"是让浏览器要用utf-8来解释,而文档的编码格式,是保存时的选择决定的。   也就是说:这个HTML文件保存时的字符集不是UTF-8!   所以,HTML的编码格式不...

Gluster的搭建和使用

Gluster的搭建和使用 序言我们为什么要去使用分布式存储,在一家大型公司或者大规模的集群中,大家可能会经常遇到一个问题,我的数据怎么存放,放在那,数据空间不够了怎么办,这些问题经常困扰着我们。 笔者是在电信的一个部门工作的,我们的环境比较复杂。环境有NAS,各种NFS,还有为了高可用搭建的HA上面跑的共享目录,每次我们遇到的一个最大的问题就是,哪哪哪的...

kubernetes的headless service介绍

headless service是一个特殊的ClusterIP类service,这种service创建时不指定clusterIP(--cluster-ip=None),因为这点,kube-proxy不会管这种service,于是node上不会有相关的iptables规则。 当headless service有配置selector时,其对应的所有后端节点,会...

在Prism 框架中,实现主程序与模块间 UI 的通信

背景:    在模块的UI中包含 TreeView 控件,在该树形控件的每一节点前面定义了一个复选框,如图 需求:    在两个不同的应用程序中使用该控件,而它在不同应用程序中的外观则并不一致,按照本例,即一个显示复选框,一个不显示。 问题:     解决该问题的一个难处在于,Prism框架本身的设计原则——此 View 会被添加到主程序的 Shell...