JS网页repaint与reflow 的区别及优化方式

JS网页repaint与reflow 的区别及优化方式

repaint和reflow的概念

当DOM树中的元素发生改变时,浏览器需要重新计算元素的位置和大小,这个过程称为reflow;当元素的外观改变,但不影响布局时,浏览器只需要重新绘制元素,这个过程称为repaint。

repaint和reflow的区别

reflow是一项非常昂贵的操作,因为浏览器需要重新计算和布局所有的元素。而repaint的代价相对较小,因为浏览器只需要重新绘制某个元素或者部分元素就可以了。

repaint和reflow的优化方式

减少对DOM的操作

reflow的发生和DOM的改变直接相关。减少对DOM的操作可以避免reflow的发生。因此,在使用JavaScript动态操作DOM时,应该尽可能地减少对DOM节点的操作,可以考虑使用字符串拼接、documentFragment等方式来批量插入DOM。

减少访问样式信息

在进行DOM操作的时候,浏览器需要获取样式信息进行重排。因此频繁访问样式信息,会导致reflow的发生。为了减少reflow的发生,可以将需要访问的样式信息提前存储到变量中,然后一次性读取。

// bad
for (let i = 0; i < 1000; i++) {
  document.querySelector("#app").style.left = i + "px";
  document.querySelector("#app").style.top = i + "px";
}

// good
const app = document.querySelector("#app");
for (let i = 0; i < 1000; i++) {
  app.style.left = i + "px";
  app.style.top = i + "px";
}

减少无用的重排和重绘

一些无用的DOM操作会导致reflow和repaint的发生,这些操作可能不会改变DOM树结构和样式信息。因此,需要尽可能减少无用的操作。

// bad
for (let i = 0; i < 1000; i++) {
  document.querySelector("#app").style.left = i + "px";
  document.querySelector("#app").style.top = i + "px";
}

// good
const app = document.querySelector("#app");
const leftValue = app.style.left;
const topValue = app.style.top;
for (let i = 0; i < 1000; i++) {
  app.style.left = parseInt(leftValue) + i + "px";
  app.style.top = parseInt(topValue) + i + "px";
}

示例说明

示例一

<div id="container">
  <div class="item">
    <img src="" alt="image">
    <h3>Title</h3>
    <p>Content</p>
  </div>
  <div class="item">
    <img src="" alt="image">
    <h3>Title</h3>
    <p>Content</p>
  </div>
  <div class="item">
    <img src="" alt="image">
    <h3>Title</h3>
    <p>Content</p>
  </div>
  ...
</div>

上述代码中,我们需要动态地向容器中添加元素。如果我们使用以下的方式进行操作:

const container = document.querySelector("#container");
for (let i = 0; i < 100; i++) {
  const item = document.createElement("div");
  item.classList.add("item");

  const img = document.createElement("img");
  img.src = "https://...";

  const h3 = document.createElement("h3");
  h3.textContent = "Title";

  const p = document.createElement("p");
  p.textContent = "Content";

  item.appendChild(img);
  item.appendChild(h3);
  item.appendChild(p);

  container.appendChild(item);
}

每次添加一个元素会触发一次reflow,增加计算开销。而我们可以使用以下的方式进行操作:

const container = document.querySelector("#container");
const items = [];
for (let i = 0; i < 100; i++) {
  const item = document.createElement("div");
  item.classList.add("item");

  const img = document.createElement("img");
  img.src = "https://...";

  const h3 = document.createElement("h3");
  h3.textContent = "Title";

  const p = document.createElement("p");
  p.textContent = "Content";

  item.appendChild(img);
  item.appendChild(h3);
  item.appendChild(p);

  items.push(item);
}

items.forEach(item => {
  container.appendChild(item);
});

这样可以将100次reflow减少到1次。

示例二

<div id="container">
  <div class="item">
    <img src="" alt="image">
    <h3>Title</h3>
    <p>Content</p>
  </div>
  <div class="item">
    <img src="" alt="image">
    <h3>Title</h3>
    <p>Content</p>
  </div>
  <div class="item">
    <img src="" alt="image">
    <h3>Title</h3>
    <p>Content</p>
  </div>
  ...
</div>

我们需要实现一个动画,将所有.item元素横向移动。以下是一个可能的实现方式:

const items = document.querySelectorAll(".item");
let leftValue = 0;
setInterval(() => {
  items.forEach(item => {
    item.style.left = leftValue + "px";
  });
  leftValue++;
}, 16);

在上述代码实现过程中,每次设置left值都会触发reflow,增加计算开销。而我们可以将left值提前存储,批量修改元素位置。以下是优化后的代码:

const items = document.querySelectorAll(".item");
const styleLefts = [];
for (let i = 0; i < items.length; i++) {
  styleLefts[i] = items[i].style.left;
}

let leftValue = 0;
setInterval(() => {
  styleLefts.forEach((left, index) => {
    items[index].style.left = parseInt(left) + leftValue + "px";
  });
  leftValue++;
}, 16);

这样可以将100次reflow减少到1次。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS网页repaint与reflow 的区别及优化方式 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • CSS样式去除input和textarea点击选中框

    要去除input和textarea在点击时出现的选中框,可以通过CSS样式来实现。以下是实现的方法: 方法一:使用outline 可以使用CSS属性outline:none来清除input和textarea在点击时出现的选中框。 例如,我们可以设置一个class为text-input,然后用CSS样式去掉选中框: .text-input:focus { ou…

    css 2023年6月10日
    00
  • Vscode 基础使用教程大全

    Vscode 基础使用教程大全 简介 本篇文章将详细讲解 Vscode 的基础使用,其中包括以下内容: Vscode 的安装及配置 Vscode 基础操作 Vscode 插件的安装和使用 Vscode 调试功能的使用 Vscode 常用快捷键 安装及配置 想要使用 Vscode,首先需要进行安装。可以通过 Vscode 官网直接下载安装包进行安装。 下载并安…

    css 2023年6月10日
    00
  • jQuery选择器querySelector的使用指南

    jQuery选择器querySelector是jQuery中最常用的功能之一,它允许开发者通过CSS样式选择器来获取元素,非常方便快捷。在这里,我们将为大家提供一份简要的jQuery选择器使用指南。 基础选择器 以下是一些最基本的jQuery选择器: 选择器 描述 * 匹配所有元素 #id 匹配ID为”id”的元素 .class 匹配class为”class…

    css 2023年6月9日
    00
  • css实现气泡框效果(实例加图解)

    CSS实现气泡框效果 气泡框效果是一种常见的CSS效果,可以为元素添加一个类似于气泡的框,用于强调或提示内容。本攻略将详细讲解如何使用CSS实现气泡框效果,包括基本原理、制作方法和示例说明。 1. 基本原理 气泡框效果的基本原理是使用CSS的伪元素:before和:after来模拟气泡和箭头,然后使用position和z-index属性将伪元素放置在元素的上…

    css 2023年5月18日
    00
  • HTML+CSS项目开发经验总结(推荐)

    当我们进行HTML+CSS项目开发时,需要注意以下几点。建议采取以下攻略: 1. 确定开发需求和设计稿 在开始项目开发之前,我们需要对项目需求进行明确和详细的了解,并获取对应的设计稿。根据设计稿制定项目开发计划和排期。 示例1:例如,我们需要开发一个电商网站,我们可以先了解网站需要提供哪些商品,商品的种类和分类,用户注册和登录等需求,并获取电商网站对应的设计…

    css 2023年6月9日
    00
  • css3动画鼠标放上图片逐渐变大鼠标离开图片逐渐缩小效果

    下面是“CSS3动画鼠标放上图片逐渐变大鼠标离开图片逐渐缩小效果”的完整攻略。 实现方式 这个效果可以通过CSS3的transform属性和过渡动画来实现。当鼠标悬浮在图片上时,通过scale函数将图片进行缩放,并设置transition属性实现动画效果;当鼠标离开时,将scale的值设为1,再次使用过渡动画使得图片缓慢恢复原来的尺寸。 具体实现 使用下面的…

    css 2023年6月10日
    00
  • IE8下CSS3选择器nth-child() 不兼容问题的解决方法

    下面是针对“IE8下CSS3选择器nth-child() 不兼容问题的解决方法”的完整攻略: 问题描述 在IE8及以下版本的浏览器中,使用CSS3选择器nth-child()时会出现兼容性问题。该选择器无法达到预期效果或者根本不起作用。 解决方法 为了解决该问题,可以考虑使用JavaScript来实现nth-child()的效果。具体方法如下: 方法一:jQ…

    css 2023年6月9日
    00
  • vue中渐进过渡效果实现

    下面是关于Vue中渐进过渡效果实现的完整攻略。 简介 在Vue中,过渡效果是一个非常重要的特性。可以用来创建动态的交互,使用户界面更加优雅、平滑。渐进效果是过渡效果中一种常见的类型。在渐进效果中,页面元素的出现或消失不是瞬间完成的,而是平滑地、逐渐地完成的。在这里,我们将介绍如何在Vue中实现渐进效果。 步骤 1. 安装Vue 首先,我们需要安装Vue。在命…

    css 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部