游客发表
把js文件塞进html,文件最直接的引入方式就是<script>标签。你写一个<script src="app.js"></script>,文件浏览器就会在解析到这一行时,引入立刻停下手里所有活儿,文件去下载并执行这个js文件。引入这就像你正做饭,文件突然有人敲门,引入你不得不放下菜刀去开门——这就是文件同步加载的代价。
所以后来有了defer和async这两个属性。引入它们就像你给快递员留了句话:“东西放门口就行,文件我忙完再拿。引入”defer的文件意思是,html文档全部解析完,引入再按顺序执行这些脚本;async则是文件下载完就立刻执行,不管html有没有解析完。你要是写<script defer src="app.js"></script>,页面结构就不会被卡住,用户能更快看到内容。
还有一个老派但有效的做法:把<script>标签放在</body>之前。比如:
<body> <h1>页面内容</h1> <script src="app.js"></script> </body> 这样浏览器先把html全解析完,再加载js。虽然不如defer优雅,但在老项目里特别常见——因为改动最小,几乎不破坏原有逻辑。我自己维护过几个2015年前后的系统,里面全是这种写法,你硬改成defer反而可能出问题,因为有的老代码依赖“脚本执行时dom已经完整”这个假设。
如果你的js文件很小,比如就几行配置代码,还可以直接内联,不搞外部文件:
<script> window.myConfig = { theme: 'dark' }; </script> 这种做法适合那种“必须最早执行,且不依赖其他文件”的代码。但别写太多,否则html文件会变得臃肿,维护起来也头疼。我见过有人把整个jquery库内联进页面,结果那个html文件有200多kb,打开慢得像蜗牛爬。
还有个细节容易踩坑:<script>标签里的type="module"。如果你用ES6的import/export,就得写<script type="module" src="main.js"></script>。这种模块默认是延迟执行的,而且有自己独立的作用域,不会污染全局变量。但要注意,本地直接双击打开html文件时,模块加载会报跨域错误——你得起个本地服务器,比如用python -m http.server,否则浏览器会拒绝加载。
说这么多,其实核心就一句话:选哪种方式,取决于你的脚本依赖什么、页面性能要求多高、以及项目本身的年代感。新项目直接用defer放head里,干净利落;老项目就老老实实放body底部,别乱改。
最后提醒一句,不管用哪种方式,<script>标签的位置和属性,都会影响页面加载速度和执行时机。别小看这几行代码,排错的时候,它可能就是那个让你挠头一小时的罪魁祸首。
友情链接