导读:本期聚焦于小伙伴创作的《JS如何实现页面骨架屏?3种骨架屏方案优化加载用户体验》,敬请观看详情。首屏白屏常常让用户误以为页面崩溃,骨架屏正是解决这一感知问题的有效手段。其本质是在数据返回前用灰块占位模拟页面结构,降低等待焦虑。原生CSS绘制适合静态布局,通过伪元素与渐变动画即可实现轻量占位;组件化方案如Vue或React的封装组件,能随路由动态生成结构,便于维护;请求拦截式骨架则在接口层判断加载态,自动切换显隐。三种方式在侵入性、复用性和性能开销上差异明显,小型活动页用CSS最省事,中后台系统推荐组件化,而对加载时序复杂的场景,拦截式更能保证体验一致。

页面在获取数据之前通常会有一段空白期,用户面对纯白界面很容易产生卡顿或加载失败的错觉。骨架屏的作用就是在真实内容到达前,先渲染出与最终布局结构相似的灰色占位块,并配合微妙的闪烁动画,让用户感知到页面正在加载。借助JavaScript,我们可以灵活控制骨架屏的显示时机、生成方式和销毁逻辑,从而在不同规模的项目中优化加载体验。

JS如何实现页面骨架屏?3种骨架屏方案优化加载用户体验

一、纯CSS配合JS控制显隐的骨架屏

最基础的方案是利用CSS画出占位块,再用JavaScript控制一个容器在加载前后切换内容。这种方式不依赖任何框架,适合结构固定的静态页或活动页。我们通常把骨架结构的HTML写成普通节点,默认显示,当数据渲染完成后将其隐藏。

核心思路是:后端或前端模板先输出骨架DOM,JS监听数据请求状态,成功后再替换或隐藏骨架节点。下面是一段简单的实现,用setTimeout模拟请求,展示如何通过class控制显隐。

<div id="app">
  <div class="skeleton" id="skeleton">
    <div class="sk-line"></div>
    <div class="sk-block"></div>
  </div>
  <div class="real-content" id="content" style="display:none;">
    <h3>文章标题</h3>
    <p>这是真实加载完成的内容</p>
  </div>
</div>
// 模拟数据请求
function fetchData() {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve({ title: '文章标题', text: '这是真实加载完成的内容' });
    }, 1500);
  });
}

fetchData().then(function(data) {
  var sk = document.getElementById('skeleton');
  var ct = document.getElementById('content');
  ct.querySelector('h3').innerText = data.title;
  ct.querySelector('p').innerText = data.text;
  sk.style.display = 'none';
  ct.style.display = 'block';
});

对应的CSS只需要定义灰色背景与闪烁动画,代码量极小,也不会影响首屏渲染速度。这种方案的优点是零依赖、易理解;缺点也很明显,当页面结构复杂或需要多处复用时,手写大量骨架DOM会变得繁琐,且难以与真实布局保持完全一致。

二、组件化骨架屏方案

在Vue或React项目中,更推荐将骨架屏封装为组件,通过props控制显示状态,并结合路由或接口状态自动渲染。组件化让骨架结构可以跟随业务布局变化,也方便在多个页面之间复用。

以Vue为例,我们可以定义一个Skeleton组件,接收loading参数。父组件在created或onMounted阶段发起请求,将loading置为false时切换为真实内容。这样骨架屏与业务代码解耦,维护成本更低。

<template>
  <div>
    <Skeleton v-if="loading" :rows="3" />
    <div v-else>
      <h3>{{ article.title }}</h3>
      <p>{{ article.text }}</p>
    </div>
  </div>
</template>
import Skeleton from './Skeleton.vue';
export default {
  components: { Skeleton },
  data() {
    return { loading: true, article: {} };
  },
  mounted() {
    setTimeout(() => {
      this.article = { title: '组件化骨架屏', text: '内容加载完毕' };
      this.loading = false;
    }, 1200);
  }
};

组件内部可以用循环生成占位行,并支持不同形状,例如圆形头像、矩形卡片等。相比纯CSS写法,组件化方案在多人协作的项目中优势突出:设计师调整布局后,只需同步修改Skeleton组件,不必在每个页面重复改动。

不过要注意,组件化骨架屏仍会在JS加载完成后才渲染,如果首屏JS包过大,用户依然会先看到白屏。因此常配合服务端渲染或预渲染,将骨架HTML直出到页面中,进一步缩短白屏时间。

三、请求拦截式自动骨架屏

对于加载时序复杂、接口众多的中后台系统,手动在每个页面写骨架状态很费力。请求拦截式方案是在全局HTTP层做文章:当某个页面的接口处于pending状态时,自动展示该页面对应的骨架屏,所有请求完成后自动消失。

实现上可以利用axios拦截器或fetch包装函数,维护一个正在请求的接口计数。配合路由钩子,在切换页面时根据接口状态决定显隐。下面用axios示意如何标记加载状态。

let pendingCount = 0;
const showSkeleton = () => {
  document.getElementById('global-skeleton').style.display = 'block';
};
const hideSkeleton = () => {
  if (pendingCount === 0) {
    document.getElementById('global-skeleton').style.display = 'none';
  }
};

axios.interceptors.request.use(config => {
  pendingCount++;
  showSkeleton();
  return config;
});
axios.interceptors.response.use(res => {
  pendingCount--;
  hideSkeleton();
  return res;
});

这种方案对业务侵入最小,不必在每个组件里写loading变量。但它要求骨架结构相对通用,难以针对每个页面精细定制。通常做法是为不同路由配置不同的全局骨架模板,在路由切换时替换对应DOM。

从性能角度看,拦截式骨架屏避免了重复的逻辑判断,也减少了组件级状态管理负担。在接口响应慢且串行请求多的场景下,它能稳定保证用户始终看到占位界面,而不是中途闪现空白。

四、三种方案的选择建议

小型营销页或一次性活动页,结构固定、上线周期短,用纯CSS加JS显隐最经济;团队使用Vue或React且页面复用度高,组件化骨架屏在可维护性上表现最好;如果系统接口繁杂、页面众多且希望统一加载体验,请求拦截式更适合。

实际项目中也可以组合使用,例如首屏用服务端直出的CSS骨架保证极速感知,进入路由后再由组件接管局部加载态。关键在于衡量开发成本与用户体验收益,避免为了骨架屏而引入过重逻辑。

方案侵入性复用性适用场景
纯CSS+JS高(需手写DOM)静态页、活动页
组件化中(组件解耦)框架项目中后台
请求拦截式低(全局处理)多接口复杂系统

无论选择哪种方式,骨架屏的目标都是缩短用户感知上的等待时间。配合合理的动画时长与占位精度,才能真的让加载过程变得平滑而不突兀。

skeleton_screenJavaScriptloading_optimization修改时间:2026-08-04 22:09:41

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。