Por que não os dois ¯ \ _ (ツ) _ / ¯? Scott Hanselman tem um ótimo artigo sobre o uso de uma CDN para obter ganhos de desempenho, mas normalmente retorna a uma cópia local, caso a CDN esteja inativa .
Específico ao bootstrap, você pode fazer o seguinte para carregar de uma CDN com um fallback local :
<head>
<!-- Bootstrap CSS CDN -->
<link rel="stylesheet" href="~https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
<!-- Bootstrap CSS local fallback -->
<script>
var test = document.createElement("div")
test.className = "hidden d-none"
document.head.appendChild(test)
var cssLoaded = window.getComputedStyle(test).display === "none"
document.head.removeChild(test)
if (!cssLoaded) {
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = "lib/bootstrap.min.css";
document.head.appendChild(link);
}
</script>
</head>
<body>
<!-- APP CONTENT -->
<!-- jQuery CDN -->
<script src="~https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<!-- jQuery local fallback -->
<script>window.jQuery || document.write('<script src="lib/jquery.min.js"><\/script>')</script>
<!-- Bootstrap JS CDN -->
<script src="~https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<!-- Bootstrap JS local fallback -->
<script>if(typeof($.fn.modal) === 'undefined') {document.write('<script src="lib/bootstrap.min.js"><\/script>')}</script>
</body>
Atualizações
- você também pode fazer o mesmo teste usando YepNope ou fallback.js
- por comentário do flash e esta solução , atualizados resposta para verificar se há
.visibleclasse em vez de testes parargb(51, 51, 51)
- de acordo com este comentário , atualizado para usar
.hiddene .d-nonepara o Boostrap 3.x ou 4
- ao testar se uma folha de estilo foi carregada , é necessário procurar um estilo que teria sido aplicado, criar um elemento e verificar se ele foi aplicado.
- Atualizada a folha de estilo para carregar imediatamente na cabeça usando vanilla js. Você precisa criar um elemento de teste usando
Document.createElement(), aplicar classes de autoinicialização, usar Window.getComputedStyle()para testar display:nonee, em seguida, inserir condicionalmente uma folha de estilo usando js.
Melhores Práticas
Para sua pergunta sobre Boas Práticas, há muitas boas razões para usar uma CDN em um ambiente de produção :
- Aumenta o paralelismo disponível.
- Aumenta a chance de ocorrer um acerto no cache .
- Isso garante que a carga útil seja a menor possível .
- Reduz a quantidade de largura de banda usada pelo seu servidor.
- Ele garante que o usuário obtenha uma resposta geograficamente próxima .
Para sua preocupação com a versão, qualquer CDN vale seu peso em sal, permitindo que você segmente uma versão específica da biblioteca, para que você não introduza acidentalmente alterações recentes a cada versão.
Usando document.write
De acordo com o MDN em document.write
Nota : à medida que document.writeescreve no fluxo de documentos , a chamada document.writeautomática de um documento fechado (carregado) chama automaticamente document.open, o que limpará o documento .
No entanto, o uso aqui é intencional. O código precisa ser executado antes que o DOM seja totalmente carregado e também na ordem correta. Se o jQuery falhar, precisamos injetá-lo no documento em linha antes de tentarmos carregar o bootstrap, que depende do jQuery.
Saída HTML após o carregamento :

Em ambos os casos, porém, estamos ligando enquanto o documento ainda está aberto, portanto, ele deve alinhar o conteúdo, em vez de substituir o documento inteiro. Se você estiver esperando até o final, precisará substituir por document.body.appendChildpara inserir fontes dinâmicas.
Além : No MVC 6, você pode fazer isso com os auxiliares de tag de link e script
rgb(51, 51, 51)parece arriscada - e se alguém mudar a cor e esquecer de atualizá-la? Existe uma propriedade mais estável que alguém possa usar?