Aqui estão algumas otimizações que você pode aplicar para acelerar as coisas. Apenas pensando em voz alta.
Como o número de linhas pode estar na casa dos milhões, você desejará um sistema de armazenamento em cache apenas para os dados JSON do servidor. Não consigo imaginar alguém querendo baixar todos os X milhões de itens, mas se o fizessem, seria um problema. Este pequeno teste no Chrome para uma matriz com mais de 20 milhões de números inteiros trava na minha máquina constantemente.
var data = [];
for(var i = 0; i < 20000000; i++) {
data.push(i);
}
console.log(data.length);
Você pode usar LRU ou algum outro algoritmo de cache e ter um limite superior para a quantidade de dados que deseja armazenar em cache.
Para as próprias células da tabela, acho que construir / destruir nós DOM pode ser caro. Em vez disso, você pode predefinir o número X de células e sempre que o usuário rolar para uma nova posição, injetar os dados JSON nessas células. A barra de rolagem praticamente não teria relação direta com a quantidade de espaço (altura) necessária para representar o conjunto de dados inteiro. Você pode definir arbitrariamente a altura do contêiner da tabela, por exemplo, 5000 px e mapear isso para o número total de linhas. Por exemplo, se a altura do contêiner for 5000px e houver um total de 10 milhões de linhas, o starting row ≈ (scroll.top/5000) * 10M
where scroll.top
representa a distância de rolagem da parte superior do contêiner. Pequena demonstração aqui .
Para detectar quando solicitar mais dados, o ideal é que um objeto atue como um mediador que escute os eventos de rolagem. Esse objeto controla a rapidez com que o usuário está rolando e, quando parece que o usuário está mais lento ou parou completamente, faz uma solicitação de dados para as linhas correspondentes. A recuperação de dados dessa maneira significa que seus dados serão fragmentados; portanto, o cache deve ser projetado com isso em mente.
Além disso, os limites do navegador para o máximo de conexões de saída podem desempenhar um papel importante. Um usuário pode rolar para uma determinada posição que acionará uma solicitação AJAX, mas antes que isso termine, o usuário pode rolar para outra parte. Se o servidor não for responsivo o suficiente, as solicitações serão colocadas na fila e o aplicativo parecerá não responder. Você pode usar um gerenciador de solicitações através do qual todas as solicitações são roteadas e pode cancelar solicitações pendentes para liberar espaço.