Panduan Render-Blocking Resources

Apa render-blocking resources adalah, bagaimana CSS dan synchronous JavaScript delay critical rendering path, mengapa itu hurts Core Web Vitals (dan indirectly SEO), cara temukan them, dan cara perbaiki them dengan async, defer, critical CSS, dan media kueri.

Pertama kali diterbitkan: 26 Jun 2026 · Terakhir diperbarui: 3 Agu 2026 · Lanjutan

Render-blocking resources adalah CSS dan synchronous JavaScript files sebuah browser harus download dan proses sebelum ini dapat paint apa pun. sebuah applicable stylesheet di head adalah render-blocking oleh default; sebuah <script> di head tanpa async atau defer adalah parser-blocking oleh default (sebuah related tetapi formally distinct mechanism dari HTML spec's jelas blocking="render" _(terjemahan)_ “render” attribute). async memuat di parallel dan berjalan ketika ready (unordered); defer memuat di parallel dan berjalan setelah parsing, di order; module scripts defer oleh default. mereka dapat delay pertama Contentful Paint dan Largest Contentful Paint, dan LCP adalah digunakan oleh Google's Core Web Vitals peringkat sistem — sebuah tiebreaker, tidak sebuah terdokumentasi dominant peringkat factor. semua eligible 200-status halaman enter Google's rendering queue regardless dari apakah JavaScript adalah present; Google fetches di sebagian besar 2 MB per non-PDF URL (including headers), secara terpisah untuk setiap referenced file, yang adalah sebuah fetch limit, tidak sebuah render-blocking-spesifik penalty. temukan them dengan saat ini Lighthouse 13 'Render blocking permintaan' Insight dan Chrome DevTools Coverage tab; perbaiki oleh deferring non-critical JS, inlining hanya critical CSS di mana sebuah trace menampilkan ini adalah bottleneck, dan menggunakan media attributes untuk conditional stylesheets — lalu re-test pada sebuah repeated trace.

TL;DR — Render-blocking resources delay sebuah halaman’s pertama paint. sebuah applicable CSS stylesheet di <head> blocks oleh default (non-matching media, disabled, atau dynamic insertion dengan Tidak jelas blocking="render" jangan). sebuah parser-inserted classic <script> tanpa async/defer adalah parser-blocking oleh default — pausing HTML parsing — yang adalah sebuah related tetapi distinct mechanism dari formal “render-blocking” (terjemahan) “render-blocking” attribute model. async memuat di parallel dan executes ketika downloaded (unordered, dapat interrupt parsing); defer memuat di parallel dan executes setelah HTML adalah parsed (di order); module scripts defer oleh default. ini delays dapat push back FCP dan LCP, dan LCP adalah digunakan oleh Google’s peringkat sistem — tetapi ini adalah sebuah tiebreaker, tidak sebuah dominant factor, dan Google documents Tidak direct render-blocking peringkat weight. Google fetches di sebagian besar 2 MB per non-PDF URL (including headers), secara terpisah untuk setiap referenced JS/CSS file — sebuah truncation boundary, tidak sebuah render-blocking-spesifik penalty — dan semua eligible 200-status halaman enter Google’s rendering queue apakah atau tidak mereka gunakan JavaScript. temukan blockers dengan saat ini Lighthouse 13 “Render-blocking requests” (terjemahan) “Render-blocking permintaan” Insight dan DevTools Coverage tab; perbaiki dengan defer, critical CSS hanya di mana sebuah trace menampilkan ini adalah bottleneck, media attributes, dan menghapus unused code — lalu re-test dengan sebuah repeated, cocok trace.

Bukti untuk klaim ini Stylesheets participate in the critical rendering path and can block first render until CSS is processed. Cakupan: Current official or standards documentation. Tingkat keyakinan: tinggi · Diverifikasi: web.dev: Critical rendering path Bukti untuk klaim ini Classic scripts without async or defer can block HTML parsing while fetched and executed. Cakupan: Current official or standards documentation. Tingkat keyakinan: tinggi · Diverifikasi: MDN: script element

critical rendering path

untuk draw sebuah halaman, sebuah browser berjalan sebuah fixed sequence: parse HTML ke DOM, parse CSS ke CSSOM, combine them ke sebuah render tree, lay ini out, dan paint. itu sequence adalah critical rendering path, dan apa pun itu stalls ini delays pertama pixel. sebagai Google’s Ilya Grigorik dibingkai ini, “optimizing itu critical rendering path refers untuk prioritizing itu display dari konten itu relates untuk itu saat ini user action.” (terjemahan) “optimizing critical rendering path refers untuk prioritizing display dari konten itu relates untuk saat ini pengguna tindakan.” Render-blocking resources adalah hal sitting di itu path dengan mereka hand up, membuat browser tunggu.

CSS adalah render-blocking oleh default — ketika ini adalah applicable

browser akan tidak paint styled konten until ini memiliki CSSOM dibangun dari setiap applicable blocking stylesheet, dan MDN’s <link> reference adalah jelas tentang cakupan: “hanya link elements di itu document’s <head> dapat possibly block rendering. Oleh default, a link element dengan rel="stylesheet" di itu <head> blocks rendering ketika itu browser discovers it during parsing.” (terjemahan) “hanya tidak terdefinisi elements di document’s tidak terdefinisi dapat possibly block rendering. oleh default, sebuah tidak terdefinisi element dengan tidak terdefinisi di tidak terdefinisi blocks rendering ketika browser discovers ini selama parsing.” dari web.dev’s mengoptimalkan LCP guide: “Style sheets loaded from the HTML markup will block rendering of all content that follows them.” (terjemahan) “Style sheets dimuat dari HTML markup akan block rendering dari semua konten itu mengikuti them.” ini adalah intentional — painting unstyled HTML pertama dan re-styling ini produces sebuah ugly flash — tetapi “oleh default” (terjemahan) “oleh default” memiliki nyata edges:

  • sebuah stylesheet dengan sebuah non-matching media attribute (e.g. media="print" pada sebuah screen visit) adalah fetched tetapi tidak block.
  • sebuah stylesheet dengan disabled set tidak dimuat atau applied until Anda jelas attribute.
  • sebuah stylesheet ditambahkan dynamically melalui script tidak render-blocking unless Anda juga set blocking="render" pada ini explicitly — dynamic insertion opts out dari default.

di dalam -nya applicable cakupan, sebuah bloated blocking stylesheet dapat masih hold seluruh halaman hostage: ketika ini takes lebih lama untuk muat daripada Anda LCP image itself, LCP element dapat’t render bahkan setelah -nya own resource memiliki finished downloading.

Scripts: parser-blocking oleh default, formally render-blocking pada permintaan

sebuah parser-inserted classic <script> di <head> tanpa async atau defer adalah parser-blocking oleh default: browser berhenti membangun DOM, fetches script, executes ini, dan hanya lalu resumes. Google’s legacy PageSpeed docs spell out cost: “setiap kali itu parser encounters a script it memiliki untuk berhenti dan execute it sebelum it dapat continue parsing itu HTML. Di itu case dari an external script itu parser adalah juga forced untuk tunggu untuk itu resource untuk download, yang mungkin incur satu atau lebih network roundtrips dan delay itu time untuk pertama render dari itu halaman.” (terjemahan) “setiap kali parser encounters sebuah script ini memiliki untuk berhenti dan execute ini sebelum ini dapat continue parsing HTML. di case dari sebuah external script parser adalah juga forced untuk tunggu untuk resource untuk download, yang dapat incur satu atau lebih network roundtrips dan delay time untuk pertama render dari halaman.” sebagai mengoptimalkan LCP guide puts ini bluntly, “it adalah hampir never necessary untuk add synchronous scripts… untuk itu <head> dari Anda halaman.” (terjemahan) “ini adalah hampir tidak pernah necessary untuk tambahkan synchronous scripts… untuk tidak terdefinisi dari Anda halaman.”

Worth menjadi precise di sini: parser-blocking dan HTML spec’s formal render-blocking attribute model adalah related tetapi distinct mechanisms. Per MDN’s <script> reference, blocking="render" token “explicitly indicates that certain operations should be blocked until the script has executed,” (terjemahan) “explicitly indicates itu certain operations seharusnya menjadi blocked until script memiliki executed,” dan “hanya script elements di itu document’s <head> dapat possibly block rendering” (terjemahan) “hanya tidak terdefinisi elements di document’s tidak terdefinisi dapat possibly block rendering” ini cara — “jika such a script element adalah added dynamically melalui script, Anda harus set blocking = "render" untuk it untuk block rendering.” (terjemahan) “jika such sebuah tidak terdefinisi element adalah ditambahkan dynamically melalui script, Anda harus set tidak terdefinisi untuk ini untuk block rendering.” dalam praktik, sebuah default parser-blocking <head> script sudah stalls pipeline cukup itu pembedaan rarely perubahan apa Anda melakukan tentang ini; ini penting mainly untuk dynamically inserted scripts, yang perlu jelas attribute untuk participate, dan browser mendukung untuk blocking="render" adalah masih limited dan worth memeriksa sebelum Anda rely pada ini.

Satu lebih default worth knowing: type="module" scripts defer oleh default (Tidak defer attribute needed) unless async adalah ditambahkan untuk perubahan itu scheduling.

async vs defer — mereka adalah tidak yang sama

ini adalah single sebagian besar berguna pembedaan untuk memperbaiki render-blocking JS. Keduanya download script di parallel dengan HTML parsing, so neither adalah parser-blocking selama download. mereka differ di execution:

  • async — executes immediately ketika download finishes, yang dapat interrupt parsing, dan berjalan di Tidak guaranteed order. baik untuk truly independent ketiga-party scripts (analytics, ads) itu jangan touch Anda DOM atau bergantung pada setiap lainnya.
  • defer — executes setelah HTML adalah fully parsed, di document order. baik untuk scripts itu bergantung pada DOM atau pada setiap lainnya (sebagian besar dari Anda own code).
  • Module scripts (type="module") — deferred oleh default; tambahkan async jika Anda secara khusus ingin module-ready-order execution alih-alih.

jika Anda remember satu aturan: defer untuk apa pun ordered atau DOM-dependent, async hanya untuk fire-dan-forget ketiga-party scripts.

Bagaimana ini memengaruhi SEO

chain adalah nyata tetapi memiliki nyata boundaries. jangan overstate ini di either direction:

«1. Render-blocking resources delay First Contentful Paint — when any content first appears. 2. They can delay Largest Contentful Paint — Google’s primary loading metric — though a flagged resource isn’t proof it’s the dominant field bottleneck, and removing it doesn’t guarantee a better LCP; the Lighthouse Insight reports a potential delay from one observed trace, not a guaranteed field effect. 3. LCP is a Core Web Vitals metric, measured at the 75th percentile of real field data over 28 days, and Google says Core Web Vitals “are used by our ranking systems.” The “good” LCP threshold is ≤2.5 s. 4. Google’s page-experience documentation doesn’t define a direct render-blocking ranking weight, chain, or tiebreaker, and gives no ranking guarantee from removing blockers — it says relevance still wins, but “having a great page experience can contribute to success in Search” when there’s lots of similarly helpful content to choose from. » (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian tiga puluh lima, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)

pertahankan weighting honest. Martin Splitt’s line adalah right calibration: “a fast website adalah a little lebih helpful daripada a slow website,” (terjemahan) “sebuah fast situs web adalah sebuah little lebih helpful daripada sebuah slow situs web,” tetapi “content is still the king.” (terjemahan) “konten adalah masih king.” Memperbaiki sebuah resource itu’s genuinely delaying Anda LCP adalah worth melakukan untuk UX dan sebagai satu input among banyak Google’s sistem weigh — ini adalah tidak sebuah lever dengan sebuah terdokumentasi, dedicated peringkat multiplier.

crawl-efficiency angle — corrected

«I previously framed heavy render-blocking JavaScript as something that “pushes” or “forces” pages into Google’s rendering queue. That’s not accurate, and it’s worth correcting plainly: Google’s current JavaScript SEO documentation states that “all pages with a 200 HTTP status code are sent to the rendering queue, no matter whether JavaScript is present on the page.” Every eligible page goes through that queue — render-blocking resources don’t create a special on-ramp into it.

Bukti untuk klaim ini Google's current guidance says all eligible pages returning HTTP 200 enter its rendering queue regardless of whether JavaScript is present, so render-blocking JavaScript should not be claimed to force a page into that queue. Cakupan: crawling, rendering, indexing Tingkat keyakinan: tinggi · Diverifikasi: Understand the JavaScript SEO basics

» (Terjemahan) (Ringkasan bahasa Indonesia untuk bagian tiga puluh delapan, bagian kecil satu: teks sumber dipertahankan agar dapat diperiksa dalam tinjauan penutur asli.)

Apa resource jenis melakukan perubahan adalah bagaimana banyak berfungsi happens setelah sebuah halaman reaches rendering. Onely’s experiment ditemukan Google needed 9× lebih lama untuk fully crawl JavaScript-dirender halaman daripada identical HTML halaman (313 hours vs. 36 hours) di mereka test setup, karena “halaman itu require rendering memiliki untuk tunggu di a rendering queue selain itu untuk itu crawl queue yang applies untuk all halaman.” (terjemahan) “halaman itu memerlukan rendering memiliki untuk tunggu di sebuah rendering queue di addition untuk crawl queue yang applies untuk semua halaman.” Treat itu sebagai evidence itu konten requiring rendering sisi klien carries sebuah nyata time-untuk-indeks cost di itu study — tidak sebagai proof itu sebuah spesifik render-blocking CSS atau JS file adalah apa triggers queueing.

pada file size: Google’s crawling documentation mendeskripsikan sebuah 2 MB fetch limit per non-PDF URL, including header HTTP, applied secara terpisah untuk setiap individual resource ini permintaan — so sebuah besar <head> script atau stylesheet mendapatkan -nya own 2 MB counter, tidak sebuah shared budget dengan HTML. itu’s sebuah fetch/truncation boundary, tidak sebuah “processing limit,” (terjemahan) “processing limit,” dan Google tidak document sebuah special crawl atau pengindeksan penalty tied secara khusus untuk render-blocking resources beyond itu umum truncation risk.

Bukti untuk klaim ini Google currently fetches up to 2 MB, including HTTP headers, for each individual non-PDF URL; referenced resources such as JavaScript and CSS have separate per-URL counters and the same 2 MB fetch limit. This supports a per-resource fetch boundary, but not the article's 'processing limit' wording or a special crawl/indexing penalty for render-blocking resources. Cakupan: fetching and WRS Tingkat keyakinan: tinggi · Diverifikasi: Inside Googlebot: crawling 101

Worth debunking sementara kami’re di sini: Google’s renderer memiliki Tidak fixed timeout. sebagai I’ve terdokumentasi di my JavaScript SEO guide, “di sana adalah Tidak fixed timeout untuk itu renderer. It berjalan dengan a sped-up timer untuk see jika apa pun adalah added di a kemudian time.” (terjemahan) “tidak ada fixed timeout untuk renderer. ini berjalan dengan sebuah sped-up timer untuk see jika apa pun adalah ditambahkan di sebuah kemudian time.” concern tidak sebuah 5-kedua cutoff — ini adalah queueing delay sebelum rendering bahkan begins.

ini bahkan reaches AI crawler now. Gary Illyes argued di 2026 itu “jika sites digunakan relatively good HTML dan Tidak JavaScript (atau SSR), keduanya base model training, dan web dan agentic RAG akan menjadi a piece dari cake dari mentah data processing perspective.” (terjemahan) “jika situs digunakan relatively baik HTML dan Tidak JavaScript (atau SSR), keduanya base model training, dan web dan agentic RAG akan menjadi sebuah piece dari cake dari mentah data processing perspective.” Berat client-side JS adalah sebuah masalah well beyond Googlebot.

cara temukan them

  • Chrome DevTools performa panel / Lighthouse 13 — saat ini “Render blocking requests” (terjemahan) “Render blocking permintaan” Insight (yang, sebagai dari Lighthouse 13, adalah di mana older “Eliminate render-blocking resources” (terjemahan) “Eliminate render-blocking resources” audit moved) flags scripts di <head> missing async/defer dan stylesheets tanpa sebuah disabled atau non-matching media attribute, dan estimates ms Anda’d save dari satu observed trace. Connor Clark’s tulis-up puts ini plainly: “render-blocking requests adalah network requests itu cegah a halaman’s awal render, potentially delaying Largest Contentful Paint.” (terjemahan) “render-blocking permintaan adalah network permintaan itu mencegah sebuah halaman’s awal render, potentially delaying Largest Contentful Paint.” jika Anda’re reading older PageSpeed Insights output itu masih says “Eliminate render-blocking resources,” (terjemahan) “Eliminate render-blocking resources,” ini adalah yang sama underlying sinyal di bawah pre-Lighthouse-13 name.
  • Chrome DevTools Coverage tab — marks bytes green (critical — digunakan untuk pertama paint) atau red (unused di pertama paint). Lots dari red CSS/JS adalah Anda candidate list.
  • WebPageTest waterfall — lihat semuanya sebelum Mulai Render line.
  • Jalankan ini lebih daripada setelah — sebuah single trace reflects itu jalankan’s consent-manager state, ketiga-party tag muat, cache state, dan CSP perilaku. Repeat trace (cold dan warm) sebelum treating satu flagged resource sebagai sebuah fixed fact.
Baca sebuah waterfall dari left untuk right: pertama paint cannot cross boundary until setiap diperlukan blocking permintaan memiliki finished.

sebuah illustrative navigation berisi HTML dari 0 untuk 180 milliseconds, blocking CSS dari 120 untuk 420 milliseconds, synchronous JavaScript dari 210 untuk 610 milliseconds, sebuah non-blocking analytics permintaan dari 250 untuk 500 milliseconds, dan font memuat dari 420 untuk 610 milliseconds. pertama paint occurs di 610 milliseconds. contoh menjelaskan timing mechanics; ini adalah tidak sebuah langsung trace.

cara perbaiki them

JavaScript

  • defer non-critical scripts — <script src="app.js" defer></script>. Parallel download, ordered execution setelah parse. safe default untuk Anda own JS.
  • async untuk independent ketiga-party scripts — <script src="analytics.js" async></script>. hanya ketika order dan DOM-readiness genuinely jangan penting.
  • Move scripts untuk end dari <body> — older fallback ketika Anda dapat’t tambahkan attributes; parser reaches them terakhir.

CSS — sebagai conditional decisions, tidak blanket patterns

  • Inline critical CSS hanya ketika sebuah trace menampilkan CSS adalah sebenarnya bottleneck — extract styles needed untuk di atas—fold konten ke sebuah inline <style> block so pertama paint perlu Tidak round-trip. Google’s own caution applies: “inlining CSS adalah an advanced performance technique itu dapat improve performance, tetapi dapat juga lead untuk bugs jika tidak implemented properly.” (terjemahan) “inlining CSS adalah sebuah advanced performa technique itu dapat meningkatkan performa, tetapi dapat juga lead untuk bugs jika tidak implemented properly.” Inline hanya critical subset, name sebuah owner untuk regenerating ini ketika templates perubahan, dan periksa untuk drift di seluruh halaman status — sebuah critical-CSS snapshot itu goes stale silently reintroduces flashes dari unstyled konten atau missing styles.
  • Defer rest, matching permintaan persis — muat penuh stylesheet dengan <link rel="preload" as="style" onload="this.rel='stylesheet'"> pattern. sebuah preload hanya mendapatkan reused untuk eventual permintaan jika URL, as, type, dan crossorigin/CORS mode match — sebuah mismatched hint penyebab browser untuk fetch resource twice alih-alih skipping round-trip.
  • media attributes — media="print" atau media="(min-width: 900px)" lets browser download sebuah stylesheet tanpa blocking render ketika kueri tidak match.
  • hapus unused CSS dan minify — lebih sedikit untuk block pada, lebih cepat downloads.
  • Verify sebelum shipping — re-periksa untuk duplicate/unused fetches, FOUC, dan baru layout shift setelah apa pun critical-CSS atau preload perubahan, pada sebuah repeated trace, tidak sebuah single lucky jalankan.

Platform-spesifik (WordPress) — WP Rocket (delay/defer JS, mengoptimalkan CSS pengiriman), Autoptimize (async/defer JS, inline critical CSS), dan Async JavaScript implement semua dari di atas melalui plugin UI. mereka’re applying yang sama async/defer/critical-CSS techniques — knowing apa setiap setting melakukan adalah bagaimana Anda hindari breaking Anda theme.

Tambahkan catatan pakar

Sematkan kutipan pakar

Orang baru? Buat profilnya yang belum diklaim di /admin/experts/ → Sematkan kutipan pakar terlebih dahulu.