首屏优化之资源加载顺序与def/async运用

前端 潘老师 1个月前 (03-20) 20 ℃ (0) 扫码查看

在前端开发里,首屏优化是绕不开的,其中资源加载顺序和<script>标签的deferasync属性运用,对页面性能有着关键影响。今天咱们就深入聊聊这俩知识点。

一、资源加载顺序和阻塞机制详解

(一)DOM构建的关键阶段

在网页加载过程中,DOM构建有几个关键阶段:

  • domLoading:这个阶段就是浏览器开始解析收到的HTML字节流,相当于开工干活的第一步。
  • domInteractive:到这个时候,HTML解析完成,DOM树也构建好了,网页的基本结构算是搭起来了。
  • domContentLoaded:不仅DOM树准备好,CSSOM(层叠样式表对象模型)也就绪了,这时候就会触发一个事件,意味着页面的基本样式和结构都可以展示了。
  • domComplete:所有像图片、脚本这类资源都加载完成,整个网页就完整了。

(二)CSS和JS的阻塞特性

CSS和JS在资源加载时,有着不同的阻塞行为,对页面渲染影响很大,具体看下面这个表格:

资源类型 阻塞行为 影响范围
CSS 会阻塞渲染树构建,可能导致页面空白,但不影响DOM解析 会阻塞后续JS的执行
JS 会阻塞DOM构建和渲染,而且一旦加载到就立即执行 会让后续HTML解析暂停

举个典型场景,如果CSS文件在JS前面声明了,但是加载延迟了,就算JS先下载好了,也得等着CSS解析完才能执行。这就好比JS在排队等CSS,CSS没处理完,JS就只能干等着。

二、<script>标签加载模式对比

<script>标签不同的属性,会让脚本的加载和执行方式大不一样,详细情况看下面表格:

属性 加载行为 执行时机 顺序保证
无属性 同步加载,会阻塞HTML解析 立即执行 按照文档顺序
defer 异步加载,不会阻塞HTML解析 在DOMContentLoaded事件触发前按顺序执行 按照加载顺序
async 异步加载,同样不阻塞HTML解析 加载完成后立即执行 没有顺序保证

还有一种特殊场景是动态脚本,比如下面这段代码:

// 创建一个script元素
const script = document.createElement('script');  
// 设置script的src属性为a.js
script.src = 'a.js';  
// 将async属性设为false,强制按文档顺序执行
script.async = false;  
// 将script元素添加到页面的body中
document.body.appendChild(script);  

这段代码就是手动创建一个脚本元素,并且设置它按文档顺序执行。

三、开发实践中的场景选择

(一)使用defer的场景

  • 当需要操作DOM元素时,比如初始化表单,就适合用defer。因为它能保证在DOM解析完成后再执行脚本,这样操作DOM就不会出错。
  • 如果脚本之间存在依赖关系,像先加载库文件,再加载业务逻辑文件,defer就能保证按顺序执行。例如:
<script src="vue.js" defer></script>  
<script src="app.js" defer></script>  <!-- 保证vue.js先执行 -->  

(二)使用async的场景

  • 对于独立且没有依赖关系的脚本,比如数据分析的SDK,用async就很合适。它不会阻塞页面渲染,能让页面快速展示出来。
  • 像错误日志上报这种优先级较低的后台任务,也可以用async,在不影响页面主要功能的前提下完成任务。例如:
<script src="analytics.js" async></script>  <!-- 不阻塞页面渲染 -->  

四、首屏性能优化实用建议

(一)关键路径优化

对于首屏展示必不可少的JS,可以选择内联的方式,或者使用无属性的<script>标签加载。而那些不是关键的脚本,就用deferasync属性,这样能合理安排脚本加载顺序,提升首屏加载速度。

(二)资源优先级控制

通过<link rel="preload">这个属性,可以提前加载核心的CSS和JS文件。这就好比提前把要用的东西准备好,等需要的时候就能直接用,减少等待时间。

掌握好资源加载顺序和deferasync的使用,对前端开发的首屏优化很重要,希望大家都能吃透!


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/front/16070.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】