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:
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:
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