Optimize your JS code in 10 seconds
Arthur Kh
Posted on November 21, 2023
Performance is the heartbeat of any JavaScript application, wielding a profound impact on user experience and overall success. It's not just about speed: it's about responsiveness, fluidity and efficiency. A well-performing JS app increases load speed, provides smoother interactions and more engaged user base. Users expect seamless experience, and optimizing performance ensures that your app meets the expectations. Improved performance leads to better SEO rankings, higher conversion rates and increased user retention. It's the cornerstone of user satisfaction, which makes it imperative to prioritize and continually optimize performance in your JavaScript applications.
Let's go to the problems!
Problem #1 - Combination of Array Functions
I've already reviewed numerous PRs (Pull Requests) in my life, and there is an issue I've seen a lot of times. It happens when someone combines .map with .filter or .reduce in any order like this:
arr.map(e => f(e)).filter(e => test(e)).reduce(...)
When you combine these methods, they go through all of the elements for a couple of times. For a small amount of data it doesn't really make any difference, but when the array gets bigger the computations take longer.
The easy solution
Use only reduce
method. reduce
is the ultimate solution when you need mapping and filtering at the same time. It'll go through the array only once and do both operations simultaneously, saving time and iterations count.
For example, this:
arr.map(e => f(e)).filter(e => test(e))
will transform into:
arr.reduce((result, element) => {
const mappedElement = f(element)
if(test(mappedElement)) result.push(mappedElement)
return result
}, [])
Problem #2 - Useless Reference Update
This problem shows up if you're using React.js or any other library where immutability is important for reactivity and re-renders. Creating a new reference using spreading is quite a common action to do when you update the state/property of the component:
...
const [arrState, setArrayState] = useState()
...
...
setArrayState([...newArrayState])
...
However, spreading the results of .map,.filter and other functions into a new array for new references is useless, because you'll just create an array with new reference to the result which is a new array with new result:
...
const [arrState, setArrayState] = useState()
...
...
setArrayState([...arrState.map(e => f(e))])
...
The solution
Just remove useless spread operator when you use:
- .map
- .filter
- .reduce - with new array accumulator-result
- .reduceRight - with new array accumulator-result
- .flat
- .flatMap
- .concat
- .toReversed
- .toSorted
- .toSpliced
You are welcome to share other JS antipatterns you know in the comments, I'll add them all in the post!
Be sure to follow my dev.to blog and Telegram channel; there will be even more content soon.
Posted on November 21, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 14, 2024
October 21, 2024