Yes, it is short. But it is somehow incorrect.
Time Complexity
Array#splice, Array#unshift will need to move all following element in the list. So it runs under \$O(n)\$ in your case. Your algorithm runs in \$O(n^2)\$ then. But a merge sort should be run in \$O(\log n)\$. As you know... You can write a even shorter code if you try to use Bubble sort as long as you don't care about time complexity.
Try to run your code on my laptop*, time usage is show in table below
| Array Size | Time Used (ms) | Time/Size2 | Time/(Size*log(Size)) |
|---|---|---|---|
| 3000 | 9.6 | 1.06e-6 | 0.92e-3 |
| 4000 | 16.97 | 1.06e-6 | 1.17e-3 |
| 5000 | 26.42 | 1.0e-6 | 1.42e-3 |
| 6000 | 37.8 | 1.05e-6 | 1.66e-3 |
| 7000 | 50.66 | 1.03e-6 | 1.88e-3 |
| 8000 | 66.86 | 1.04e-6 | 2.14e-3 |
| 9000 | 83.02 | 1.02e-6 | 2.33e-3 |
You can see that your time usage is \$O(n^2)\$ instead of \$O(\log n)\$.
* I'm using node v16.13.0 just in case.
for (i = 1; i <= 10; ++i) {
const time = []
const size = i * 1e3;
for (let i = 0; i < 11; i++) {
const arr = [...Array(size)].map(_ => Math.random());
const t0 = performance.now();
mergeSort(arr);
const t = performance.now() - t0;
time.push(t);
}
const mid = time.sort((x, y) => x - y)[5];
console.log("%o\t%o", size, +mid.toFixed(2));
}
Sort Stability
Merge sort should be stable. But yours is not.
Your merge function didn't keep the stable order. However this can be fixed by changing lista[0] < listb[0] to lista[0] <= listb[0].
After that, the merge sort is still unstable. Consider 3 elements input [a, b, c]. What you do is actually merge([c], merge([a], [b])). But it should be merge(merge([a], [b]), [c]). The order here is important as otherwise sort stability will not be held any more.
const arr = [1, 1, 1].map(Object)
const ori = [...arr];
const result = mergeSort(arr);
console.log(result.map(x => ori.indexOf(x))) // [1, 0, 2]