检查每个循环性能的宽度和内部设置宽度 [英] Checking width and setting width inside forEach loop performance

查看:108
本文介绍了检查每个循环性能的宽度和内部设置宽度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我下面有两段代码

代码段1

const doubleWidth = (element) => {
  const width = element.offsetWidth;
  element.style.width = `${width * 2}px`;
};
button.addEventListener('click', (event) => {
  boxes.forEach(doubleWidth);
});

代码段2

button.addEventListener('click', (event) => {
  var widths = boxes.map(item => item.offsetWidth);
  boxes.forEach((element, index) => {
         element.style.width = `${widths[index] * 2}px`;
  });
});

与片段2(仅18.4ms)相比,片段1有48ms的时间.为什么会这样?

Snippet #1 has a lot 48ms compared to snippet #2 which is only 18.4ms. Why is that behaviour?

毕竟,我仍在进行两项计算和设置操作(哪些是强制性的重熔).

After all, I am still doing two operation of calculating and settings ( which forcers reflows ) each.

这是完整的代码- https://codepen .io/kushalmahajan/pen/mjXVqp?editors = 0010

更新-所以,让我多解释一下

Update - So , let me explain a bit more

在代码片段1中,我每次都会看到诸如计算,重置,计算,重置...之类的模式

In Snippet #1, I see each time a pattern like calculate, Reset, Calculate, Reset ...so forth

在代码段2中.事实并非如此.

In Snippet #2. That's not the case.

请根据您的渲染管道为您提供答案

推荐答案

我不确定原因,但显然如果您先存储offsetWidth,则对性能而言是否使用forEach都无关紧要或map:这是一支钢笔来说明这种行为.

I'm not sure about the reason, but apparently if you store offsetWidth first, it doesn't matter performance-wise whether you use forEach or map: here's a pen to illustrate this behavior.

您可以看到我对三个组合进行了计时:

You can see that I timed three combinations:

  1. forEach,并立即获取offsetWidth并设置width
  2. forEach,首先存储offsetWidth和相应的元素,然后在第二个forEach
  3. 中设置其宽度
  4. map并存储offsetWidth,然后在forEach循环中的元素上设置width
  1. forEach with immediately getting offsetWidth and setting width
  2. forEach with storing offsetWidth and the corresponding element first and then setting width it in a second forEach
  3. map with storing offsetWidth and then setting width on the elements in a forEach loop

选项 2. 3.在性能上基本相同.从这一点来看,我要说获得offsetWidth和设置width的组合是一个性能瓶颈.真的不能告诉你更多,对不起!

Option 2. an 3. were basically the same performance wise. Judging from that, I would say that the combination of getting offsetWidth and setting width is a performance bottleneck. Can't really tell you much more than that, sorry!

window.onload = () => {
    const boxes = Array.from(document.querySelectorAll('.box'));

    document.getElementById('double-sizes-forEach')
    .addEventListener('click', (event) => {
        console.time('Double Sizes ForEach');

        boxes.forEach((element, index) => {
        const width = element.offsetWidth;
        element.style.width = `${width * 2}px`;
        });

        console.timeEnd('Double Sizes ForEach');
    });

    document.getElementById('double-sizes-forEach-2')
    .addEventListener('click', (event) => {
        console.time('Double Sizes ForEach 2');

        let a = [];
        boxes.forEach((element, index) => {
        a.push([element, element.offsetWidth]);
        });
        a.forEach(([e, w]) => {
        e.style.width = `${w * 2}px`; 
        });

        console.timeEnd('Double Sizes ForEach 2');
    });

    document.getElementById('double-sizes-map')
    .addEventListener('click', (event) => {
        console.time('Double Sizes Map');

        var widths = boxes.map(item => item.offsetWidth);
        boxes.forEach((element, index) => {
            element.style.width = `${widths[index] * 2}px`;
        });

        console.timeEnd('Double Sizes Map');
    });
};


输出:

Double Sizes ForEach: 12.341064453125ms
Double Sizes ForEach 2: 0.539794921875ms
Double Sizes Map: 0.590087890625ms


注释:

  • what forces layout/reflow
  • article on layout performance issues and layout thrashing

第二篇文章指出,您应始终将更改样式(例如设置width)和进行测量(例如获取offsetWidth)分开,以免布局出现问题.似乎也是代码中的问题.

The second article argues that you should always separate changing style (e.g. setting width) and taking measurements (e.g. getting offsetWidth) to avoid layout thrashing. Seems that's the problem in your code as well.

这篇关于检查每个循环性能的宽度和内部设置宽度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆