1

前言

我就想随便找个地方放东西不行吗?

看别人写的代码,<head>中写原生js无一例外加了window.onload, jquery示例中无一例外的加了 $(function(){}) But why? 从此这两尊神秘的大佛让我畏惧了很久,今天写的博文,就是为了崇尚科学破除迷信,撕下'规则' 的神秘面纱. 而这神秘的面纱,本质就是浏览器加载js的方式

总的来说,浏览器加载js通常就这么几种方式:

  • 阻塞加载

  • 异步加载

  • 延迟加载


阻塞加载

<head>
    ...
    <script src=xx.js ></script>  
    ...
</head>

阻塞加载是浏览器最常见的加载js的方式,不管这条语句出现在页面中的什么位置, 浏览器解析到该标签时, 会堵塞下载(即串行)xx.js,  同时位于该标签之后的资源下载和解析全部挂起. xx.js下载完成之后立刻执行,执行完毕之后,才开始后续资源的下载和解析


异步加载

<script src=xx.js async=”async”></script> 

不管这条语句出现在页面中的什么位置, 浏览器解析到该标签时, 会非堵塞下载(即并行)xx.js, (非堵塞下载即该资源在下载的过程中不影响后续资源的下载和解析), 下载完成之后立即执行


延迟加载

<script src=xx.js defer="defer"></script>  

不管这条语句出现在页面中的什么位置, 浏览器解析到该标签时, 会非堵塞下载(即并行)xx.js, (非堵塞下载即该资源在下载的过程中不影响后续资源的下载和解析), 下载完成之后挂起,等到DOMContentLoaded事件完成之后再执行


动态插入Script节点

同异步加载


结语

通过了解了常见的几种加载js的方法,前言中提出的问题相信大家已经有了答案

为什么如果在<head>中写内联js一般会如此开头:

window.onload=function(){...}

因为$(function(){})是DOMContentLoaded回调,表示DOM树已经构建完成.window.onload 是整个页面资源加载完成的回调。总而言之,只有先构建了对应的DOM,你才能用脚本去操作它.所以这就是如果在<head>中写内联js不加window.onload经常报错的原因,通常因为找不到对应的DOM

这也是我们为什么通常把外链Js放在底部进行加载:

  • 确保了CSS和HTML加载完毕,主要内容已经呈现给用户

  • 确保了CSS和HTML加载完毕,所有DOM处于可操作状态


大切图崽
379 声望95 粉丝

一只切图崽