Is Spread Operator Always a Good Choice(In the Context of Performance) ??

Satish Kumar
3 min readFeb 28, 2020

Everyone is aware that in javascript ES6 we got many new functionalities and features like

  • classes.
  • enhanced object literals.
  • template strings.
  • destructuring.
  • rest + spread operators.
  • let + const.
  • arrows.

which made the developer's life much easier and we can do lots of things very fast and in a very concise and cleaner way.

The spread operator is one of them on which I am going to talk about in this article.

Using a Spread operator seems a very fascinating and very concise way of doing things like combining objects and many other things.

const obj1 = {name:"satish",city:"gurgaon"}
const obj2 = {sirname:"chawala",state:"haryana"}
const obj3 = {…obh1,..obj2}

As a developer, I also use it a lot but recently working on a feature I found something interesting about it. what exactly I was trying to do was converting a very large array of objects to a map like object so I could do lookup very easily.

We had an array of size around 35k something like this example except each object was very large in our case.

const data=[
{
"id":1
"name": "Heather Kent",
"fName": "Kuame",
"lName": "Tashya",
"phone": "(552) 489-3623",
"email": "eget.magna@non.ca",
...
},
{
"id":2
"name": "Xantha Paul",
"fName": "Emmanuel",
"lName": "Francesca",
"phone": "(107) 377-6316",
"email": "eu.turpis.Nulla@turpisNulla.com",
...
},
{
"id":3
"name": "Raya David",
"fName": "Reese",
"lName": "Fatima",
"phone": "(893) 548-3432",
"email": "ac.libero@aenim.net",
...
}
..... 35K MORE
]

And we were converting it to a map using ES6 Array.reduce() method

console.time('measureTime')const dataAsMap = data.reduce((acc,obj)=>{
return { ...acc,[obj.id]:obj }
},{})
console.timeEnd('measureTime')

What we found that this operation was taking lots of time around 7 minutes. At first, we thought it was Array.reduce method so we tried it using normal for-loop and still it was taking the same time.

Then I had a hunch that can it be because of spreading object again and again so I tried it without spread operator like this

console.time('measureTime')const dataAsMap = data.reduce((acc,obj)=>{
acc[obj.id] = obj
return acc
},{})
console.timeEnd('measureTime')

And I was surprised to see the result. it was taking just 27.292ms. It was a very big difference.

So why this was happening? it was happening because of the way spread operator works. It copies key-value pairs from source to target one by one and it takes time if the source object is very large.

For example, take this code

const q= {
"name": "Desiree Mckinney",
"fName": "Brent",
"lName": "Cailin",
"phone": "(316) 914-7448",
"email": "In.condimentum.Donec@ut.com"
}
const p = {...q}

And if we compile it through babel we get this equivalent code

"use strict";function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }var q = {
"name": "Desiree Mckinney",
"fName": "Brent",
"lName": "Cailin",
"phone": "(316) 914-7448",
"email": "In.condimentum.Donec@ut.com"
};
var p = _objectSpread({}, q);

In my personal opinion, it’s better not to use spread operator in such a scenario where the list is very large and the object is increasing constantly in size

If you liked this article then give it a like.

And You might like these articles also

--

--

Satish Kumar

AVP Engineering - frontend Apps at fleetx.io Ex-Aviso Inc. NITian 🎓