Computer memory access is efficient when linear. That is, when the next thing you need is located directly after the last thing you needed, in memory. In JavaScript, arrays are conceptually sequential, but this is only an abstraction for the programmer. In truth, the array elements are scattered around in random memory locations. This means that when you iterate over an array, the CPU cache misses on every iteration, and the CPU has to wait for the next data to load from memory.
In a language where arrays are not sparse, but rather dense, the whole array is allocated as one contiguous stride of memory. Iterating through it is very fast, because the CPU cache hits every time and the next data you need is always ready, as it immediately follows the previous in memory.
Additionally, ECS wants to pack data even further, so that unneeded data is not interleaved within the memory stride at all. Every byte you "skip" is wasted space in the CPU cache, and eventually accumulates into a full cache miss, which stalls program execution.