5

Note: This question can be considered as extension of Array.find and Array.findIndex has worst performance in LWC Lightning Locker BUT it is not duplicate - check at the end of this question why there is no proper alternate work-around. It seems like all latest Array functions have worst performance in locker service.

According to documentation:

enter image description here

But basic functions like Array.includes (and find, findIndex, etc) from latest Ecmascript (includes is from ecma 2016) are failing in LWC locker.

Below is the example:

parent.html:

<template>
    <div class="slds-theme_default slds-box">
        Parent
        <lightning-button label="test" onclick={test}></lightning-button>
        <c-child arr={arr}></c-child>
    </div>
</template>

parent.js

export default class Parent extends LightningElement {
    @track arr = [];
    test() {
        this.arr.length = 0;
        for (let i = 1; i <= 1000; i++) {
            this.arr.push('a' + i);
        }
        console.log('Parent array ', this.arr.length);

        const t1 = new Date().getTime();
        const c1 = this.arr.includes('a422');
        const t2 = new Date().getTime();
        const c2 = this.arr.includes('a42222');

        const t3 = new Date().getTime();

        const c3 = this.arr.indexOf('a4222') > -1;
        const t4 = new Date().getTime();
        const c4 = this.arr.indexOf('a42222') > -1;
        const t5 = new Date().getTime();

        console.log(c1, c2, c3, c4);
        console.log('includes => ', t2 - t1, t3 - t2, t3 - t1);
        console.log('indexOf => ', t4 - t3, t5 - t4, t5 - t3);
    }
}

child.html:

<template>
    Child
    <lightning-button label="test" onclick={test}></lightning-button>
</template>

child.js

export default class Child extends LightningElement {
    @api arr;

    test() {
        console.log('child array ', this.arr.length);

        const t1 = new Date().getTime();
        const c1 = this.arr.includes('a422');
        const t2 = new Date().getTime();
        const c2 = this.arr.includes('a42222');

        const t3 = new Date().getTime();

        const c3 = this.arr.indexOf('a4222') > -1;
        const t4 = new Date().getTime();
        const c4 = this.arr.indexOf('a42222') > -1;
        const t5 = new Date().getTime();

        console.log(c1, c2, c3, c4);
        console.log('includes => ', t2 - t1, t3 - t2, t3 - t1);
        console.log('indexOf => ', t4 - t3, t5 - t4, t5 - t3);
    }
}

Below is the output:

enter image description here

Although below is potential solution (as mentioned in other question),

child.js:

    @api
    get arr() {
        return this._arr;
    }
    set arr(value) {
        this._arr = JSON.parse(JSON.stringify(value));
    }

But

This will remove the reactivity from api valiable arr. And we end up creating one more duplicate tracked variable which just keeps bloating the code as nested components increase and thereby increasing technical debt. So, we would need a proper solution such that LWC by itself handles these functions properly

8
  • Includes isn't really failing in this example, right? it's just slow performance?
    – Zerkz
    Commented Aug 20, 2020 at 17:25
  • slow like 400 times is like failing.. you go 1 level deep to grand-child, it will not finish and probably freeze your browser Commented Aug 20, 2020 at 17:27
  • 2
    You've already asked this. What additional insight to do hope to gain from another question? If anything, what should be done is opening a bug with Salesforce.
    – sfdcfox
    Commented Aug 20, 2020 at 17:53
  • 1
    I'm going to ping some people over on social media. Stay tuned.
    – sfdcfox
    Commented Aug 20, 2020 at 17:57
  • @sfdcfox just hoping some core LWC dev would give some pointers whether they have this on roadmap and so I mentioned as this question is extension of other question. Just surprizing that many functions are affected - never noticed includes before as dataset was small Commented Aug 20, 2020 at 18:10

0

Browse other questions tagged .