How to sort and search in JavaScript large set
The following function sort of agrees with your function. Except that for example your function given
scores = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] and alice = [ 0, 0, 0, -1 ] gets 1,1,1,5, while I think it should be 1,1,1,2.
Anyway, it easily handles scores arrays of sizes 10^7 for scores and 10^5 for alice.
The idea is, we already know scores is sorted as per your comment. We can then go through the scores array. We sort the alices array while remembering the original order. Then we go through the scores array, we first look at the largest alice, once we hit an element &gt;= it, it is time to note that down, we remember the score and whether it was a tie and the position it happened at. We continue traversing scores, now looking at the next biggest alice, etc.
At the end of this we know where each alice would be ranked in the original array. Now we just need to account for the rank increases that come from prior alices, basically the rule is, if you are alice 7, then you look at the previous scores from alices 1 to 6 which resulted in a rank increase, and count 1 each time their score was larger than yours. We can do this fairly quickly by maintaining a sorted array of the previous scores using a binary search to find where to insert the next element. Remembering to account for ties amongst Alices scores.
function binarySearch(array, targetValue) {
    if (array.length === 0) {
        return 0;
    }
    let min = 0;
    let max = array.length;
    let guess;

    while (max - min &gt; 1) {
        guess = Math.floor((max + min) / 2);

        if (array[guess] &gt; targetValue) {
            min = guess;
        } else {
            max = guess;
        }
    }

    return array[min] &lt; targetValue ? min : min + 1;
}


function climbingLeaderboard(scores, alice) {
    if (alice.length === 0) {
        return [];
    }
    const sortedAliceWithIndex = alice.map((s, i) =&gt; [s, i]).sort(([a], [b]) =&gt; b - a);

    let aliceInd = 0;
    let currAlice = sortedAliceWithIndex[aliceInd][0];
    const ranks = [];
    let i = 0;
    let effectiveCount = 0;
    while (true) {
        const currScore = scores[i];
        if (currScore !== undefined &amp;&amp; currScore &gt; currAlice) {
            i++;
            if (!(scores[i] === scores[i - 1])) {
                effectiveCount++;
            }
            continue;
        }

        ranks.push([
            effectiveCount,
            sortedAliceWithIndex[aliceInd][1],
            currAlice === currScore,
            currAlice
        ]);
        aliceInd++;

        if (aliceInd &gt;= alice.length) {
            break;
        }
        currAlice = sortedAliceWithIndex[aliceInd][0];
    }

    const inOriginalAliceOrder = ranks.sort(([, i1], [, i2]) =&gt; i1 - i2);

    const accountingForRanks = [];
    let rankIncreases = [];
    for (let [i, _, tie, score] of inOriginalAliceOrder) {
        let rankUp = binarySearch(rankIncreases, score);

        if (rankIncreases[rankUp - 1] === score) {
            accountingForRanks.push(i + rankUp);
        } else {
            accountingForRanks.push(i + rankUp + 1);
            if (!tie) {
                rankIncreases.splice(rankUp, 0, score);
            }
        }
    }
    return accountingForRanks;
}

The following runs in a couple of seconds for me.
function main() {
    let scores = new Array(10 ** 6);
    for (let i = 0; i &lt; scores.length; i++) {
        scores[i] = 1 * Math.random();
    }
    scores.sort((a, b) =&gt; b - a);
    let alice = new Array(10 ** 5);
    for (let i = 0; i &lt; alice.length; i++) {
        alice[i] = 2 * Math.random() - 1;
    }

    let result1 = climbingLeaderboard(scores, alice);

    console.log(result1);
}