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定义字体、颜色、背景等属性

    详解CSS定义字体、颜色、背景等属性 字体属性 在CSS中,我们可以使用font-family属性来定义文字的字体,可以输入一个字体的名称或者是多个字体的名称,例如: p { font-family: Arial, Helvetica, sans-serif; } 上面的例子中,字体设置为Arial,如果用户的浏览器没有安装Arial字体,可以尝试安装Hel…

    css 2023年6月9日
    00
  • vue+webpack 更换主题N种方案优劣分析

    下面我将详细讲解“vue+webpack 更换主题N种方案优劣分析”的完整攻略。 一、前言 在前端开发中,为了提升网站的用户体验,很多网站都会提供多种主题供用户选择,以满足用户不同的喜好和需求。Vue框架作为当下流行的前端框架之一,为了实现更换主题,存在着多种不同的方案,例如利用CSS变量、使用CSS预处理器的变量、使用CSS Modules等。其中,本文将…

    css 2023年6月10日
    00
  • BAT及各大互联网公司2014前端笔试面试题(Html,Css篇)

    BAT及各大互联网公司2014前端笔试面试题(Html,Css篇)是一份经典的前端笔试面试题目集,包含了许多常见的 HTML 和 CSS 技术问题。本文将提供一份完整攻略,包括题目解析、示例说明和代码实现。 题目解析 1. 如何实现一个三角形? 可以使用 CSS 的 border 属性来实现一个三角形。具体方法是将元素的宽度和高度设为 0,然后设置 bord…

    css 2023年5月18日
    00
  • 使用jquery+CSS3实现仿windows10开始菜单的下拉导航菜单特效

    下面是使用jquery+CSS3实现仿windows10开始菜单的下拉导航菜单特效的完整攻略: 1. 准备工作 在开始编写代码之前,首先需要准备好以下内容: 一个文本编辑器,比如Sublime Text或者VS Code 最新版的jQuery库和FontAwesome图标库 一些图片和文本内容 2. 编写 HTML 结构 下拉导航菜单的 HTML 结构如下:…

    css 2023年6月10日
    00
  • CSS中的滑动门技术

    那么我们就来详细讲解一下“CSS中的滑动门技术”的攻略。 一、滑动门技术介绍 滑动门是 CSS 中常见的一种技术,用于制作具有拉伸自适应功能的按钮、导航菜单等等。 滑动门技术的实现原理是通过 CSS 的重叠背景技术,在按钮或菜单项上同时设置两个背景图片,一个用于左侧,一个用于右侧。同时还需设置一个中间区域用于填充按钮或菜单项的文本内容,以及设置一个额外的 &…

    css 2023年6月9日
    00
  • img图片下面莫名的出现下边距的快速解决方法推荐

    下面是针对“img图片下面莫名的出现下边距的快速解决方法推荐”的完整攻略: 问题背景 在网页设计过程中,我们常常使用img标签来插入图片。但是有时会发现图片下方会出现一个意料之外的下边距,使得整个页面看起来不够美观。 解决方法 方法1 第一种方法是使用CSS的display:block;属性。我们可以将img标签的display属性设置为block,这样它就…

    css 2023年6月9日
    00
  • 纯css 圆角实现代码

    纯 CSS 圆角实现是一种常见的技术,可以用来创建各种形状的元素,如圆形、椭圆形、三角形等。下面是一个完整攻略,包含了如何使用纯 CSS 实现圆角的过程和两个示例说明。 纯 CSS 圆角实现 步骤一:使用 border-radius 属性 要使用纯 CSS 实现圆角,我们可以使用 border-radius 属性。该属性可以用来设置元素的圆角半径。例如: d…

    css 2023年5月18日
    00
  • 教你做个可爱的css滑动导航条

    下面我将详细讲解“教你做个可爱的CSS滑动导航条”的完整攻略。 1. 前言 在此教程中,我们将会通过CSS来创建一个可爱的滑动导航条。我们将使用CSS中的transition属性和定位属性来实现这个效果。 2. 实现步骤 2.1 HTML结构 首先,在HTML中,我们需要创建一个容器元素 <nav>,用来包含导航菜单条目。每个条目都是一个<…

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