How browsers schedule and execute scripts can impact the performance of web pages. While techniques like <script defer>
, <link rel=preload>
(and others) influence script loading, knowing how browsers interpret them can also be helpful. Thanks to Kouhei Ueno, we now have an up to date summary of script scheduling in Chrome.
|
Loading priority
(network/Blink)
|
Execution priority
|
Where should this be used?
|
<script> in <head>
|
Medium/High
|
VeryHigh -
Blocks parser
|
- Scripts that affect layout of First Meaningful Paint (FMP) / First Contentful Paint (FCP) content
- Scripts that must be run before other scripts
Examples:
- Framework runtime (if not static-rendered)
- Polyfills
- A/B testing that affects DOM structure of the entire page
</ul>
</ul>
</td>
</tr>
<link rel=preload> +
<script async> hack
or
<script type=module async>
</td>
| Medium/High
|
High -
Interrupts parser
|
- Scripts that generate critical content (needed for FMP)
- But shouldn't affect above-the-fold layout of the page
- Scripts that trigger network fetches of dynamically inserted content
- Scripts that need to execute as soon as their imports are fetched, use
<script async type=module>
Examples:
- Draw something on
<canvas> </ul>
</ul>
</td>
</tr>
<script async>
|
Lowest/Low
|
High -
Interrupts parser
|
Be careful when considering <script async> . Today it is often used to indicate non-critical scripts, but is inconsistent in being loaded at low priority and executed at high priority.
|
<script defer>
|
Lowest/Low
|
VeryLow -
Runs after <script> s at end of <body>
|
- Scripts that generate non-critical content
- Scripts that provide key interactive features that >50% of page view sessions would use
Examples:
</td>
</tr>
|
<script> at the end of <body>
|
Medium/High
|
Low -
Waits parser end
|
Be careful when using <script> at the end of <body> when you think they are low priority. These scripts are scheduled at Medium/High priority.
|
<script defer> at the end of <body>
|
Lowest/Low -
end of the queue
|
VeryLow -
Runs after <script> s at end of <body>
|
- Scripts that provide interactive features that may be used occasionally
Examples:
- Load "Related articles"
- "Give feedback" feature
</ul>
</td>
</tr>
|
<link rel=prefetch> + <script> in a next-page navigation
|
Idle / Lowest
|
Depends on when and how the script is consumed.
|
Scripts very likely to provide important functionality to a next-page navigation.
Examples:
- JavaScript bundle for a future route
|
</table>
Note: Loading priorities are not guaranteed to be consistent cross-browser so use this knowledge wisely and measure when unsure. Ideally, aim to delivery a great experience to the widest number of users possible.
If you're a web developer wondering where you can see the "Loading Priority", Chrome DevTools has an optional "Priority" column available in the Network panel. Right-click the column headers and you can switch it on:
This above priorities [summary](/../assets/images/tweet-priorities@3x.png) is still true as of February 2019. I would personally love to get a better understanding of loading priorities in other browsers too. Hopefully this overview is useful to someone out there!
_Thanks to Kouhei, Dom Faralino, Pat Meenan, Kenji Baheux and Yoav Weiss for their contributions helping better explain Chrome's network stack._
## Further reading
- [Scheduling Scripts Intuitively and Performantly](https://bit.ly/script-scheduling)
- [Chrome Resource Priorities and Scheduling](https://docs.google.com/document/d/1bCDuq9H1ih9iNjgzyAL0gpwNFiEP4TZS-YLRp_RuMlc/edit#)
- [Preload, Prefetch And Priorities in Chrome](https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf)
- [Priorities for rel=preload in Chrome and WebKit](https://twitter.com/yoavweiss/status/1096075414697639936)
| |