Eu não acho que você esteja fazendo errado. Programar é como ser um caçado de soluções.
É muito mais confortável sentar a bunda e se "preparar" infinitamente. Eu digo isso por experiência própria. Se você não faz isso: Você esta no caminho certo, sem dúvidas.
É frustrante no inicio. Quando encontramos a solução, a solução precisa ser entendida e precisa de mais estudos. Parece a Wikipedia quando abrimos uma página, há diversas citações. No fim não entendemos completamente o que lemos.
Não cai na armadilha de achar que precisa ler todas as citações da Wikipedia. As citações tem mais citações e no fim você vai chegar em perguntas sobre como o universo surgiu. Entendeu o que eu quero dizer?
Respondendo a pergunta: Eu não fico travado. Não mais. Sempre que encontro uma pedra na minha frente, eu tenho várias opções. Se eu preciso de algo pronto agora, eu foco em obter a solução. Se funciona, eu não irei me aprofundar nisso AGORA. No entanto é ESTREITAMENTE IMPORTANTE ENTENDER ISSO DEPOIS. Resumindo, no aperto do tempo, foque em entregar.
Para estudar, ou seja, meu foco é aprender, eu sempre pego um ambiente controlado e testo coisas. Projetos para aprender algo não é grande, e mesmo que seja, é possível quebrar em partes menores, como um kernel. Não precisa de pressa, o foco é aprender. Só coloque na mente que nunca vamos compreender tudo. Esqueça isso, é perca de tempo e de saúde. Sempre há mais para aprender e por isso tecnologia é divertido. Apenas foque em aprendeu o que você começou a estudar.
Um exemplo para ilustrar e real: No momento eu peguei um projeto em Rust. Neste projeto há concorrência pesada. Eu não sabia praticamente nada quando comecei este projeto. Só sabia um pouco sobre o Rust em si. Lidar com concorrência de verdade? Primeira vez. Não estou falando de lidar com abstrações como Promises do JavaScript. Não há aprendizado algum nisso. É útil para entregar rápido. Em Rust precisamos lidar com runtimes externos, tipos anônimos, mutex, handlers, ownership e etc. Exige uma Disciplina. Agorao observe, eu comecei sem saber praticamente nada e o projeto já esta quase concluído. O que eu fiz? Eu sabia que precisava lidar com threads e código assíncrono. Entendi a diferença entre os dois (que não é muita!). Então a partir dai, eu já tinha um calço para dar o initial commit. Quando fiz isso pensei, agora eu preciso fazer um request. Como isso é feito em Rust? Então pesquisei, não por respostas, mas por informações "brutas" e criar um mapa mental das minhas possibilidades. Então cheguei ao reqwest paran não reinventar a roda (apesar de ter interesse!). Agora eu já conseguia fazer um request, agora eu precisava implementar um algortimo que NUNCA VI EM LUGAR ALGUM chamado: Generic cell rate algorithm. Depois eu descobri que isso é usado em redes, telemarketing, e é uma variação de outros dois algoritmos.
Bem, para não fica exaustivo, irei concluir agora. Observe que foi um passo de cada vez. Cada um levou um tempo. Alguns levou dias, outros horas, e outros levou nem segundos. É um processo. Nesse processo, observe que eu me deparei com um monte de coisa que eu não sabia o que era. Eu aprendi o fundamental de cada um. O algoritmo: Generic cell rate algorithm por exemplo, tem uso até em Hardware, mas eu não liguei para isso. Eu busquei o essencial, resolveu o meu problem. Depois no tempo livre dei uma lida, mas não fiquei travado pela a quantidade de informação, eu apenas entendi isso de maneira geral, e no processo eu acabei entendendo muito, mas muito mesmo.
Confie no processo. Não falo em procrastinar ou pedir a resposta, mas caçar as soluções, e saber o momento de cada coisa. Isso você ganha com o tempo. Neste caminho eu acredito que não vá demorar muito para você.
Por fim:
onde pretendo ler e anotar mais e codificar menos.
NÃO FAÇA ISSO! Desenvolvimento é uma habilidade. Toda habilidade precisa ser praticada. Você vai aprender mais codificando que anotado. Novamente, digo por experiência.