No passado, quando os navegadores eram muito menos capazes do que hoje e o desempenho do JavaScript era ruim, todas as páginas vinham de um servidor. Sempre que você clicava em algo, uma nova solicitação era feita ao servidor e o navegador carregava a nova página posteriormente.
Somente produtos muito inovadores funcionaram de maneira diferente e experimentaram novas abordagens.
Hoje, popularizado pelos modernos frameworks de JavaScript, como o React, um aplicativo geralmente é criado como uma single page aplication: você carrega o código do aplicativo (HTML, CSS, JavaScript) apenas uma vez e, quando você interage com ele, o que geralmente acontece é que o JavaScript intercepta os eventos do navegador e, em vez de fazer uma nova solicitação ao servidor, o qual retornaria um novo documento, o cliente solicita algum JSON ou executa uma ação no servidor, mas a página que o usuário vê não é completamente apagada e se comporta como um aplicativo de desktop. Ou quase isso.
Single page aplications são desenvolvidas em JavaScript (ou pelo menos compiladas para JavaScript) e funcionam no browser.
A tecnologia é sempre a mesma, mas alguns pontos sobre como a aplicação funciona são diferentes.
Por isso, as single page applications dependem muito do JavaScript. Isso pode tornar o uso de um aplicativo executado em dispositivos de baixa potência uma experiência ruim em termos de velocidade. Além disso, alguns de seus visitantes podem ter o JavaScript desabilitado, e você não deve deixar a acessibilidade de lado.
Como você se livra da navegação padrão do navegador, os URLs devem ser gerenciadas manualmente.
Essa parte de um aplicativo é chamada de roteador. Algumas estruturas já cuidam delas para você (como o Ember), enquanto outras exigem bibliotecas que farão esse trabalho (como o React Router).
Qual é o problema? No começo, isso era uma reflexão tardia para os desenvolvedores que criam SPAs. Isso causou o problema comum de "botão quebrado": ao navegar no aplicativo, a URL não foi alterada (desde que a navegação padrão do navegador foi invadida) e ao pressionar o botão voltar, você pode ser redirecionado para um site que visitou há muito tempo.
Agora, esse problema pode ser resolvido usando a History API, oferecida pelos navegadores, mas na maioria das vezes você usa uma biblioteca que usa internamente essa API, como o React Router.
Por hoje é isso galera, espero que tenham curtido o assunto.
Se vocês tiverem quaisquer dúvidas relacionadas a SPA's, ou algo a adicionar, deixem aqui nos comentários.