Now one thing which also costs performance but it just is what it is in this app is the fact that we
unshift the array because as you learned in the Arrays and Iterables section, this simply means that Javascript
has to revisit all array elements and push them all to the end of the array because we add a
new element at the very beginning,
so all elements have to be moved but it is just what it is,
if that is what we want to do in this app, well it is what we want to do and that's the part where you
should be careful when you try to optimize everything.
It's easy to think in a super complex way and try to optimize things which really don't need optimization.
Sure, using unshift is slower than using push but unless you're doing this every second on an array
with thousands of items, you probably won't notice a difference because when we talk about performance,
sure we might have a difference of let's say 10 milliseconds but will this matter?
No,
this will not matter.
So you should be careful when you try to optimize everything,
it's often not worth it and you might even break your app or come up with some strange workaround which
offers a bad user experience or which in the worst case is even slower
just because you try to avoid a certain way of doing something which just turns to be out the right
way even though it technically is slower than some other way.
Let's dive a bit deeper into these micro optimizations though,
i told you that you should measure before you optimize. Now
thus far we haven't done too much measurement because the optimizations we did, mostly those regarding
the DOM are no-brainers, they are better,
they're also not micro optimizations, these are really optimizations which can matter.
Now here's an example for a micro optimization where we want to check if it's better. In rendering.js, in
render products here,
I'm using for each.
Now this is not the only way of going through all items in an array as you know,
so let's find out if it's the best one. For that, let's log a start time with performance.now which
is a function that helps you measure performance,
it gives you a timestamp in the end. Then here we have the
end time which is also performance.now
which executes after for each and then we can console log end time minus start time
to get the time difference.
Now let's save that and let's see what the time difference is.
Open the console here and you see here it logs around .33
and if we reload here multiple times, we see there are quite some differences which already shows you
that you have to be careful regarding such optimizations,
you would want to run this a couple of thousand times by writing some extra script which just refreshes
this or executes your script to find out what is better.
So here we see we have a couple of different numbers but we're somewhere around 30-ish but really there
is a lot of deviation. Now let's try a different approach,
let's comment out this approach and instead let's use a regular for loop, not even a for/of loop,
a very traditional for loop where we have i which starts at zero, where we then loop as long as i is
smaller as products.length, where then increment i by 1.
And now let's grab this code here, put it in here
and here of course, we have to access products for index
i and here, it's also products i and yes that should be it.
Now let's save this.
Now when you execute this a couple of times, you most likely will not see a significant difference,
you might see some results which are faster,
you might see less results which are on the higher end as we saw it before
but there really is also a lot of randomness involved,
as I said you would need to run this tens of thousands of times.
Well turns out there are pages which do this for you, jsperf.com is such a site.
Now you need to log in with a github account here to create your own test cases which in the end are comparisons
of different approaches
but you can also go to the popular test cases down here to find comparisons
other people ran and here I'm talking about Javascript code comparisons.
For example here we have a comparison of for and for each
and you see a lot of other comparisons down there as well.
Now this here is in the end of benchmark which in the end has an array with bunch of numbers as you can
tell
and then these different tests are being run, it tests going through all these items with a for loop,
with a for/of loop, with the for each function and also with the reduce function.
Now let's click on run tests and now it runs these tests for a couple of times and then it gives you
an average,
So let's wait for this to finish and what you should see and the exact results will differ,
you can also run this for multiple times but what you should see is that the traditional for loop actually
is fastest and if you google that, if you google for versus for/of Javascript and so on, you will find
a lot of discussions where this is also discussed.
Indeed right now at least, the traditional for loop is faster than the for/of loop is faster than
for each and so on.
Now does this mean you should switch and replace all for/of loops with this loop?
Why did I even teach you for/of
if it's slower? Because when we talk about it being slow here, we have to be really careful. When
we talk about a difference, like here in my browser of 11%,
that's not a lot,
you might not be running across an array with that thousands of items multiple times every second, if
you do that,
the difference might matter. Most of the time,
99% of all applications, you're not going to do that because if you would do that, even
with the fastest approach, it would probably be slow at some point.
So when we talk about differences here, we really have to be careful that we don't go for the fastest
result just because it shows it here and totally forget that this doesn't matter
in most cases. So when you're comparing results, if you're benchmarking and you're checking whether approach
A is faster than approach B, for example with benchmarking web sites like jsperf.com, you have
to interpret the results with caution because of what I just said that you might not be running thousands
of operations and the performance difference therefore really will not make a difference
and then you should go for the code which is more readable and shorter and not for the most complex
code which theoretically might run a bit faster
and in addition, keep in mind that performance is not a fixed thing.
It might differ from browser to browser,
thus far we only tested in Chrome, in Firefox it might be a bit different
and it will change over time. Of course if approach A is slower than B at the moment,
this does not mean it's slower in a year or in six months especially the newer Javascript engine features
which were added one or two years ago will most likely become faster over time and they might overtake
the existing, the older approaches then.
So of course you can then always go back to your code and reimplement it with the then best approach or
you
keep in mind that you're not running this operation thousands of times and therefore this micro optimization
really doesn't matter.
So back in our code, this means we can of course run this loop like this
and it's nice to do that,
it's also good to know how you can measure performance with performance.now but you shouldn't overdo
it and here, because it's a bit shorter,
I will go back to my old for each approach which isn't horrible, which is a bit slower
but again we won't really feel that here and therefore, this is the approach I will use here and that is
what you should keep in mind about benchmarking and micro optimizations like this one, where you try
to optimize everything and you might therefore end up with longer or less readable code or an approach
which isn't the best anymore in a year or half a year.