Saya mencoba menghilangkan 2 file CSS yang membuat pemblokiran di situs saya - file tersebut muncul di Google Page Speed Insights. Saya telah mengikuti metode yang berbeda, tidak satupun yang berhasil. Tapi, baru-baru ini, saya menemukan sebuah posting tentang Thinking Async dan ketika saya menerapkan kode ini: <script async src="https://third-party.com/resource.js"></script>
itu menghilangkan masalah.
Namun, setelah dipublikasikan, halaman kehilangan gaya. Saya tidak terlalu yakin dengan apa yang terjadi karena kodenya berfungsi tetapi gaya setelah unggahan yang tidak berfungsi. Akan sangat menghargai bantuan Anda dalam hal ini. Terima kasih
html
css
asynchronous
Paulina994
sumber
sumber
Jawaban:
Trik untuk memicu unduhan stylesheet asinkron adalah dengan menggunakan
<link>
elemen dan menyetel nilai yang tidak valid untuk atribut media (saya menggunakan media = "none", tetapi nilai apa pun bisa digunakan). Saat kueri media bernilai false, browser akan tetap mendownload stylesheet, tetapi tidak akan menunggu konten tersedia sebelum merender halaman.<link rel="stylesheet" href="css.css" media="none">
Setelah stylesheet selesai mengunduh atribut media harus disetel ke nilai yang valid sehingga aturan gaya akan diterapkan ke dokumen. Peristiwa onload digunakan untuk mengalihkan properti media ke semua:
<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'">
Metode pemuatan CSS ini akan memberikan konten yang dapat digunakan kepada pengunjung lebih cepat daripada pendekatan standar. CSS kritis masih dapat disajikan dengan pendekatan pemblokiran biasa (atau Anda dapat menyebariskannya untuk performa terbaik) dan gaya non-kritis dapat diunduh dan diterapkan secara progresif nanti dalam proses parsing / rendering.
Teknik ini menggunakan JavaScript, tetapi Anda dapat melayani browser non-JavaScript dengan membungkus
<link>
elemen pemblokiran yang setara dalam sebuah<noscript>
elemen:<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'"><noscript><link rel="stylesheet" href="css.css"></noscript>
Anda dapat melihat operasinya di www.itcha.edu.sv
Sumber di http://keithclark.co.uk/
sumber
preload
di Firefox dan di browser lama - lihat tautan di komentar pertama jawaban itu].Pembaruan 2020
Jawaban sederhana (dukungan browser lengkap):
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">
Jawaban yang didokumentasikan (dengan pramuat opsional dan fallback skrip nonaktif):
<!-- 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>
Pra-pemuatan dan gabungan asinkron:
Jika Anda membutuhkan CSS pramuat dan asinkron, solusi ini hanya menggabungkan dua baris dari jawaban yang didokumentasikan di atas, membuatnya sedikit lebih bersih. Tetapi ini tidak akan berfungsi di Firefox sampai mereka mendukung kata kunci pramuat . Dan sekali lagi, seperti yang dijelaskan dalam jawaban yang didokumentasikan di atas, pramuat sebenarnya tidak bermanfaat.
<link href="style.css" rel="preload" as="style" onload="this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="style.css"></noscript>
Pertimbangan tambahan:
Perhatikan bahwa, secara umum, jika Anda akan memuat CSS secara asinkron, umumnya disarankan agar Anda memasukkan CSS kritis sebaris , karena CSS adalah sumber daya yang memblokir perenderan karena suatu alasan .
Penghargaan untuk grup filamen untuk banyak solusi CSS asinkron mereka.
sumber
onload="this.rel='stylesheet'; this.onload = null"
. Ini perlu diaturthis.onload
untuknull
menghindari ini dipanggil dua kali di beberapa browser, tampaknya.Menggunakan
media="print"
danonload
Grup filamen baru-baru ini (Juli 2019) menerbitkan sebuah artikel yang memberikan rekomendasi terbaru mereka tentang cara memuat CSS secara asinkron. Meskipun mereka adalah pengembang pustaka Javascript loadCSS yang populer , mereka sebenarnya merekomendasikan solusi ini yang tidak memerlukan pustaka Javascript:
<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'; this.onload = null" >
Menggunakan
media="print"
akan menunjukkan kepada browser untuk tidak menggunakan stylesheet ini pada layar, tetapi pada cetakan. Peramban sebenarnya mengunduh lembar gaya cetak ini, tetapi secara asinkron, itulah yang kami inginkan. Kami juga ingin stylesheet digunakan setelah diunduh, dan untuk itu kami tetapkanonload="this.media='all'; this.onload = null"
. (Beberapa browser akan menelepononload
dua kali, untuk mengatasinya, kami perlu menyetelnyathis.onload = null
.) Jika mau, Anda dapat menambahkan<noscript>
fallback untuk pengguna langka yang tidak mengaktifkan Javascript.The artikel asli bernilai membaca, karena masuk ke detail lebih dari saya di sini. Artikel di csswizardry.com ini juga patut untuk dibaca.
sumber
Anda dapat mencoba mendapatkannya dengan banyak cara:
1. menggunakan
media="bogus"
dan<link>
di kaki<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. Memasukkan DOM dengan cara lama
<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. Jika Anda dapat mencoba plugin, Anda dapat mencoba loadCSS
<script> // include loadCSS here... function loadCSS( href, before, media ){ ... } // load a file loadCSS( "path/to/mystylesheet.css" ); </script>
sumber
<script>
menjadi<style rel=stylesheet>
? (Hanya ingin tahu. Saya akan menggunakanloadCSS
(contoh 3 Anda) sebagai gantinya, jika saya perlu memuat CSS nanti.)Fungsi di bawah ini akan membuat dan menambahkan ke dokumen semua stylesheet yang ingin Anda muat secara asinkron. (Namun, berkat
Event Listener
, itu hanya akan melakukannya setelah semua sumber daya jendela lainnya dimuat.)Lihat berikut ini:
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);
sumber
var newStyle = document.createElement("link"); newStyle.rel = "stylesheet"; newStyle.href = "stylesheet.css"; document.getElementsByTagName("head")[0].appendChild(newStyle);
di dalam<script>
tag di badan halaman bekerja dengan sangat baik - bahkan di browser lama seperti MSIE8.window.load
acara. Jadi, unduhan dimulai saat semuanya diunduh. Tidak beruntung di sana. Anda memerlukan pemuatan tanpa pemblokiran secepat mungkin untuk memulai.Pendekatan Pemuatan Asinkron CSS
Ada beberapa cara untuk membuat browser memuat CSS secara asinkron, meskipun tidak ada yang sesederhana yang Anda duga.
<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">
sumber
Jika Anda perlu memuat tautan CSS secara terprogram dan asinkron:
// 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); }
sumber
Jika Anda memiliki kebijakan keamanan konten yang ketat yang tidak memungkinkan @ vladimir-Salguero 's jawaban , Anda dapat menggunakan ini (silakan membuat catatan dari 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>
Cukup tambahkan berikut ini untuk referensi stylesheet Anda:
media="none" data-async="true"
. Berikut contohnya:<link rel="stylesheet" href="../path/script.js" media="none" data-async="true" />
Contoh untuk 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>
sumber
async
atribut ini diabaikan, karena tag skrip tidak memilikisrc
untuk memuat secara asinkron ... atau benar-benar berguna di sini? Juga dapatkah Anda menguraikan lebih banyak tentang nilai mana yang akan digunakan sebagainonce
?Harap berhati-hati untuk memperbarui jawaban karena semua hal di atas gagal mengesankan wawasan google pagespeed sekarang.
Menurut Google, ini adalah bagaimana Anda harus mengimplementasikan pemuatan asinkron dari 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>
sumber
Saya telah mencoba menggunakan:
<link rel="preload stylesheet" href="mystyles.css" as="style">
Ini berfungsi dengan baik, tetapi juga meningkatkan pergeseran tata letak kumulatif karena ketika kita menggunakan rel = "preload", itu hanya mengunduh css, tidak langsung diterapkan.
Contoh ketika DOM memuat daftar berisi ul, tag li, ada peluru sebelum tag li secara default, lalu CSS diterapkan sehingga saya menghapus peluru ini ke gaya khusus untuk daftar. Sehingga, terjadi pergeseran tata letak kumulatif di sini.
Apakah ada solusi untuk itu?
sumber
Gunakan
rel="preload"
untuk membuatnya mendownload secara mandiri, lalu gunakanonload="this.rel='stylesheet'"
untuk menerapkannya ke stylesheet (as="style"
perlu untuk menerapkannya ke stylesheet jikaonload
tidak, tidak akan berfungsi)<link rel="preload" as="style" type="text/css" href="mystyles.css" onload="this.rel='stylesheet'">
sumber