Estou tentando eliminar 2 arquivos CSS que estão bloqueando a renderização em meu site - eles aparecem no Google Page Speed Insights. Tenho seguido métodos diferentes, nenhum dos quais foi um sucesso. Mas, recentemente, eu encontrei um post sobre Thinking Async e quando apliquei esse código: <script async src="https://third-party.com/resource.js"></script>
ele eliminou o problema.
No entanto, após a publicação, a página perdeu o estilo. Não tenho certeza do que está acontecendo porque o código funciona, mas é o estilo após o upload que não funciona. Agradeceria sua ajuda com isso. obrigado
html
css
asynchronous
Paulina994
fonte
fonte
Respostas:
O truque para acionar um download de folha de estilo assíncrono é usar um
<link>
elemento e definir um valor inválido para o atributo media (estou usando media = "none", mas qualquer valor servirá). Quando uma consulta de mídia é avaliada como falsa, o navegador ainda baixa a folha de estilo, mas não espera que o conteúdo esteja disponível antes de renderizar a página.<link rel="stylesheet" href="css.css" media="none">
Assim que o download da folha de estilo terminar, o atributo de mídia deve ser definido com um valor válido para que as regras de estilo sejam aplicadas ao documento. O evento onload é usado para mudar a propriedade de mídia para todos:
<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'">
Este método de carregamento de CSS entregará conteúdo utilizável aos visitantes muito mais rápido do que a abordagem padrão. CSS crítico ainda pode ser servido com a abordagem usual de bloqueio (ou você pode embuti-lo para melhor desempenho) e estilos não críticos podem ser baixados progressivamente e aplicados posteriormente no processo de análise / renderização.
Essa técnica usa JavaScript, mas você pode atender a navegadores não JavaScript envolvendo os
<link>
elementos de bloqueio equivalentes em um<noscript>
elemento:<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'"><noscript><link rel="stylesheet" href="css.css"></noscript>
Você pode ver a operação em www.itcha.edu.sv
Fonte em http://keithclark.co.uk/
fonte
preload
no Firefox e em navegadores mais antigos - veja o link no primeiro comentário dessa resposta].Atualização de 2020
A resposta simples (suporte completo ao navegador):
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">
A resposta documentada (com pré-carregamento opcional e fallback desativado por script):
<!-- Optional, if we want the stylesheet to get preloaded. Note that this line causes stylesheet to get downloaded, but not applied to the page. Use strategically — while preloading will push this resource up the priority list, it may cause more important resources to be pushed down the priority list. This may not be the desired effect for non-critical CSS, depending on other resources your app needs. --> <link rel="preload" href="style.css" as="style"> <!-- Media type (print) doesn't match the current environment, so browser decides it's not that important and loads the stylesheet asynchronously (without delaying page rendering). On load, we change media type so that the stylesheet gets applied to screens. --> <link rel="stylesheet" href="style.css" media="print" onload="this.media='all'"> <!-- Fallback that only gets inserted when JavaScript is disabled, in which case we can't load CSS asynchronously. --> <noscript><link rel="stylesheet" href="style.css"></noscript>
Pré-carregamento e assíncrono combinados:
Se você precisa de CSS pré-carregado e assíncrono, esta solução simplesmente combina duas linhas da resposta documentada acima, tornando-a um pouco mais limpa. Mas isso não funcionará no Firefox até que eles suportem a palavra-chave preload . E, novamente, conforme detalhado na resposta documentada acima, o pré-carregamento pode não ser benéfico.
<link href="style.css" rel="preload" as="style" onload="this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="style.css"></noscript>
Considerações adicionais:
Observe que, em geral, se você for carregar CSS de forma assíncrona, é geralmente recomendado que você inline CSS crítico , já que CSS é um recurso de bloqueio de renderização por um motivo .
Crédito ao grupo de filamentos por suas muitas soluções CSS assíncronas.
fonte
onload="this.rel='stylesheet'; this.onload = null"
. É necessário configurarthis.onload
paranull
evitar que isso seja chamado duas vezes em alguns navegadores, aparentemente.Usando
media="print"
eonload
O grupo de filamentos publicou recentemente (julho de 2019) um artigo com sua recomendação mais recente sobre como carregar CSS de forma assíncrona. Mesmo sendo eles os desenvolvedores da popular biblioteca Javascript loadCSS , eles realmente recomendam esta solução que não requer uma biblioteca Javascript:
<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'; this.onload = null" >
Usar
media="print"
indicará ao navegador para não usar esta folha de estilo nas telas, mas na impressão. Os navegadores realmente baixam essas folhas de estilo de impressão, mas de forma assíncrona, que é o que queremos. Também queremos que a folha de estilo seja usada assim que for baixada, e para isso definimosonload="this.media='all'; this.onload = null"
. (Alguns navegadores chamarãoonload
duas vezes; para contornar isso, precisamos definirthis.onload = null
.) Se desejar, você pode adicionar um<noscript>
substituto para os raros usuários que não têm o Javascript habilitado.O artigo original vale a pena ler, pois ele entra em mais detalhes do que eu estou aqui. Este artigo em csswizardry.com também vale a pena ler.
fonte
você pode tentar obtê-lo de várias maneiras:
1. Usando
media="bogus"
e<link>
ao pé<head> <!-- unimportant nonsense --> <link rel="stylesheet" href="style.css" media="bogus"> </head> <body> <!-- other unimportant nonsense, such as content --> <link rel="stylesheet" href="style.css"> </body>
2. Inserindo DOM da maneira antiga
<script type="text/javascript"> (function(){ var bsa = document.createElement('script'); bsa.type = 'text/javascript'; bsa.async = true; bsa.src = 'https://s3.buysellads.com/ac/bsa.js'; (document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(bsa); })(); </script>
3.se você pode tentar plugins, você pode tentar loadCSS
<script> // include loadCSS here... function loadCSS( href, before, media ){ ... } // load a file loadCSS( "path/to/mystylesheet.css" ); </script>
fonte
<script>
para<style rel=stylesheet>
? (Só por curiosidade. Vou usarloadCSS
(ou seja, seu exemplo 3) em vez disso, se precisar carregar o CSS mais tarde.)A função abaixo irá criar e adicionar ao documento todas as folhas de estilo que você deseja carregar de forma assíncrona. (Mas, graças ao
Event Listener
, isso só acontecerá depois que todos os outros recursos da janela forem carregados.)Veja o seguinte:
function loadAsyncStyleSheets() { var asyncStyleSheets = [ '/stylesheets/async-stylesheet-1.css', '/stylesheets/async-stylesheet-2.css' ]; for (var i = 0; i < asyncStyleSheets.length; i++) { var link = document.createElement('link'); link.setAttribute('rel', 'stylesheet'); link.setAttribute('href', asyncStyleSheets[i]); document.head.appendChild(link); } } window.addEventListener('load', loadAsyncStyleSheets, false);
fonte
var newStyle = document.createElement("link"); newStyle.rel = "stylesheet"; newStyle.href = "stylesheet.css"; document.getElementsByTagName("head")[0].appendChild(newStyle);
dentro da<script>
tag no corpo da página faz seu trabalho de maneira excelente - mesmo em navegadores antigos como o MSIE8.window.load
evento. Portanto, o download começa quando tudo é baixado. Sem sorte aí. Você precisa não bloquear o carregamento o mais rápido possível para começar.Abordagens de carregamento assíncrono de CSS
Existem várias maneiras de fazer um navegador carregar CSS de forma assíncrona, embora nenhuma seja tão simples quanto você pode esperar.
<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">
fonte
Se você precisar carregar um link CSS de maneira programática e assíncrona:
// https://www.filamentgroup.com/lab/load-css-simpler/ function loadCSS(href, position) { const link = document.createElement('link'); link.media = 'print'; link.rel = 'stylesheet'; link.href = href; link.onload = () => { link.media = 'all'; }; position.parentNode.insertBefore(link, position); }
fonte
Se você tem uma política de segurança de conteúdo rígida que não permite a resposta de @vladimir-salguero , você pode usar isto (observe o script ):
nonce
<script nonce="(your nonce)" async> $(document).ready(function() { $('link[media="none"]').each(function(a, t) { var n = $(this).attr("data-async"), i = $(this); void 0 !== n && !1 !== n && ("true" == n || n) && i.attr("media", "all") }) }); </script>
Basta adicionar o seguinte para sua referência de estilo:
media="none" data-async="true"
. Aqui está um exemplo:<link rel="stylesheet" href="../path/script.js" media="none" data-async="true" />
Exemplo para jQuery:
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css" type="text/css" media="none" data-async="true" crossorigin="anonymous" /><noscript><link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css" type="text/css" /></noscript>
fonte
async
atributo é ignorado, pois a tag de script não tem umsrc
para carregar de forma assíncrona ... ou é realmente útil aqui? Além disso, você pode elaborar um pouco mais sobre qual valor usar como umnonce
?Por favor, atualize a resposta, pois todas as opções acima não impressionam os insights do google pagepeed agora.
De acordo com o Google, é assim que você deve implementar o carregamento assíncrono de Css
< noscript id="deferred-styles" > < link rel="stylesheet" type="text/css" href="small.css"/ > < /noscript > <script> var loadDeferredStyles = function() { var addStylesNode = document.getElementById("deferred-styles"); var replacement = document.createElement("div"); replacement.innerHTML = addStylesNode.textContent; document.body.appendChild(replacement) addStylesNode.parentElement.removeChild(addStylesNode); }; var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; if (raf) raf(function() { window.setTimeout(loadDeferredStyles, 0); }); else window.addEventListener('load', loadDeferredStyles); </script>
fonte
Eu tentei usar:
<link rel="preload stylesheet" href="mystyles.css" as="style">
Funciona muito bem, mas também aumenta a mudança cumulativa de layout porque quando usamos rel = "preload", ele apenas baixa o css, não aplica imediatamente.
Exemplo quando o DOM carrega uma lista que contém as tags ul, li, há marcadores antes das tags li por padrão, então o CSS aplica que eu remova esses marcadores para estilos personalizados para listagem. Portanto, a mudança cumulativa de layout está acontecendo aqui.
Há alguma solução para isso?
fonte
Use
rel="preload"
para fazer o download independentemente e, em seguida, useonload="this.rel='stylesheet'"
para aplicá-lo à folha de estilo (as="style"
é necessário aplicá-lo à folha de estilo, caso contrárioonload
, não funcionará)<link rel="preload" as="style" type="text/css" href="mystyles.css" onload="this.rel='stylesheet'">
fonte