As noted in the accepted answer the only way to assure the compare function results in expected sort order is to return a number other than 0.
The reasoning for this though is important and should be noted for reference purposes. ECMA standards allow for browser implementations to be unstable. As such there can be no expectation that a function returning 0 will result in the original sort order.
http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.11
The sort is not necessarily stable (that is, elements that compare equal do not necessarily remain in their original order). If comparefn is not undefined, it should be a function that accepts two arguments x and y and returns a negative value if x < y, zero if x = y, or a positive value if x > y.
Now for Chrome (and others). Browsers can use whatever sort algorithms they want based on whatever criteria they choose. Since certain algorithms are more efficient based on array size the vendor can choose to change the underlying algo dynamically based on the array size. This is why you're seeing this behavior.
At the time of writing the Chromium source uses length <= 10
as the deciding factor.
https://cs.chromium.org/chromium/src/v8/src/js/array.js?l=707&rcl=9c7cccf55126353a101f194bcf1f8826bc263804
function InnerArraySort(array, length, comparefn) {
// In-place QuickSort algorithm.
// For short (length <= 10) arrays, insertion sort is used for efficiency.
...
if (to - from <= 10) {
InsertionSort(a, from, to);
return;
}
...