• reflow-回流 和 repaint-重绘


    简要:整个在浏览器的渲染过程中(页面初始化,用户行为改变界面样式,动画改变界面样式等)reflow(回流)和repaint(重绘) 会大大影响web性能,尤其是手机页面。因此我们在页面设计的时候要尽量减少reflow和repaint。
    reflow:例如某个子元素样式发生改变,直接影响到了其父元素以及往上追溯很多祖先元素(包括兄弟元素),这个时候浏览器要重新去渲染这个子元素相关联的所有元素的过程称为回流。
    reflow:几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。通常我们都无法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。
    repaint:如果只是改变某个元素的背景色、文 字颜色、边框颜色等等不影响它周围或内部布局的属性,将只会引起浏览器 repaint(重绘)。repaint 的速度明显快于reflow

    下面情况会导致reflow发生
    1:改变窗口大小
    2:改变文字大小
    3:内容的改变,如用户在输入框中敲字
    4:激活伪类,如:hover
    5:操作class属性
    6:脚本操作DOM
    7:计算offsetWidth和offsetHeight
    8:设置style属性
    那么为了减少回流要注意哪些方式呢?
    1:不要通过父级来改变子元素样式,最好直接改变子元素样式,改变子元素样式尽可能不要影响父元素和兄弟元素的大小和尺寸
    2:尽量通过class来设计元素样式,切忌用style

    var bstyle = document.body.style; // cache
    bstyle.padding = “20px”; // reflow, repaint
    bstyle.border = “10px solid red”; // 再一次的 reflow 和 repaint
    bstyle.color = “blue”; // repaint
    bstyle.backgroundColor = “#fad”; // repaint
    bstyle.fontSize = “2em”; // reflow, repaint
    // new DOM element - reflow, repaint
    document.body.appendChild(document.createTextNode(‘dude!’));
    对上面代码优化:
    .b-class{
      padding:20px;
      color:blue;
      border:10px solid red;
      background-color:#fad;
      font-size:2em;
    }
    $div.addClass(“b-class”);

    3:实现元素的动画,对于经常要进行回流的组件,要抽离出来,它的position属性应当设为fixed或absolute
    4:权衡速度的平滑。比如实现一个动画,以1个像素为单位移动这样最平滑,但reflow就会过于频繁,CPU很快就会被完全占用。如果以3个像素为单位移动就会好很多。
    5:不要用tables布局的另一个原因就是tables中某个元素一旦触发reflow就会导致table里所有的其它元素reflow。在适合用table的场合,可以设置table-layout为auto或fixed,
    6:这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。
    7:css里不要有表达式expression
    8:减少不必要的 DOM 层级(DOM depth)。改变 DOM 树中的一级会导致所有层级的改变,上至根部,下至被改变节点的子节点。这导致大量时间耗费在执行 reflow 上面。
    9:避免不必要的复杂的 CSS 选择器,尤其是后代选择器(descendant selectors),因为为了匹配选择器将耗费更多的 CPU。
    10: 尽量不要过多的频繁的去增加,修改,删除元素,因为这可能会频繁的导致页面reflow,可以先把该dom节点抽离到内存中进行复杂的操作然后再display到页面上。

    在div.first里面加入div.second,在div.second里面加入div.third:
    $divS = $(“

    ”);
    ( d i v . f i r s t ) . a p p e n d ( (div.first).append( (div.first).append(divS));//reflow
    $divT = $(“
    ”);
    d i v S . a p p e n d ( divS.append( divS.append(divT);//reflow
    优化代码:
    $divS = $(“
    ”);
    $divT = $(“
    ”);
    d i v S . a p p e n d ( divS.append( divS.append(divT);
    ( d i v . f i r s t ) . a p p e n d ( (div.first).append( (div.first).append(divS));//reflow
    或者:
    var $divF = $(div.first);
    $divS = $(“
    ”);
    $divS.hide();
    ( d i v . f i r s t ) . a p p e n d ( (div.first).append( (div.first).append(divS));
    $divT = $(“
    ”);
    d i v S . a p p e n d ( divS.append( divS.append(divT);
    $divS.show();//reflow

    11:请求如下值offsetTop, offsetLeft, offsetWidth, offsetHeight,
    scrollTop/Left/Width/Height,clientTop/Left/Width/Height,浏览器会发生reflow,建议将他们合并到一起操作,可以减少回流的次数。如果我们要经常去获取和操作这些值,则可以先将这些值缓存起来例如:
    var windowHeight = window.innerHeight;//reflow
    for(i=0;i<10;i++){
      $body.height(windowHeight++);
      一系列关于windowHeight的操作…
    }

  • 相关阅读:
    Apk安装后不显示桌面图标问题
    Linux内核源码分析 (B.x)Linux内存布局
    SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池
    Kafka之Broker原理
    Kubernetes 介绍
    BL200OPC UA分布式IO系统接线方式
    YOLOv5 分类模型 数据集加载 3
    使用 SwiftUI 构建可搜索列表,为您的 iOS 应用程序创建具有自动完成功能的可搜索列表(教程含源码)
    java计算机毕业设计-中小学教育机构培训系统-源代码+系统+数据库+lw文档
    【300+精选大厂面试题持续分享】大数据运维尖刀面试题专栏(三)
  • 原文地址:https://blog.csdn.net/u013400314/article/details/126965426