📝 场景需求

在日常的小程序开发中,我们经常会遇到这样的需求:用户进入某个页面时,先播放一段全屏的欢迎动画(GIF),动画播放结束后自动隐藏,展示真实的页面内容。

这个需求听起来很简单,就是贴一张图的事,但在实际开发特别是微信小程序环境下,往往会遇到 “GIF不从第一帧播放”“低端机内存溢出闪退” 等各种坑。

本文将为你提供一份可以直接 Copy 的完整代码,并详细复盘其中的避坑指南。


💻 核心实现思路

核心思路非常简单粗暴:

  1. 使用一个 position: fixed 的全屏遮罩层包裹 <image> 标签。

  2. 设置超高的 z-index 盖住原本的页面。

  3. 利用 onShow (或 onLoad) 生命周期触发播放,并开启一个 setTimeout 定时器。

  4. 定时器时间设置为 GIF 的总时长,时间一到,使用 v-if 销毁该层,露出主页面。

🚀 完整代码示例 (可直接CV)

创建一个 .vue 页面,直接粘贴以下代码即可看效果:

<template>
  <view class="container">
    <view class="main-content">
      <text class="title">这是页面的主要内容加载出来了!</text>
    </view>

    <view class="gif-overlay" v-if="showGif">
      <image 
        class="full-gif" 
        :src="gifUrl" 
        mode="aspectFill" 
      />
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      showGif: true, // 控制GIF的显示与销毁
      gifDuration: 3000, // 假设你的GIF动图总时长是 3秒 (3000毫秒)
      
      // 强烈建议使用网络地址,尽量不要用本地 /static/ 下的超大gif
      gifUrl: 'https://your-domain.com/path/to/your-animation.gif' 
    };
  },
  onShow() {
    // 每次进入页面时触发播放
    this.playGif();
  },
  methods: {
    playGif() {
      this.showGif = true;
      
      // 【防缓存黑科技】:添加时间戳,强制每次从第一帧开始播放!
      this.gifUrl = `https://your-domain.com/path/to/your-animation.gif?t=${new Date().getTime()}`;

      // 设置定时器,在GIF播放结束后销毁该图层
      setTimeout(() => {
        this.showGif = false;
      }, this.gifDuration);
    }
  }
}
</script>

<style scoped>
/* 保证底层页面正常布局 */
.container {
  position: relative;
  min-height: 100vh;
  padding: 20px;
}

/* 核心:全屏遮罩层样式 */
.gif-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 99999; /* 层级拉满,挡住一切 */
  background-color: #FFFFFF; /* 建议底色和你的GIF背景色一致,防闪烁 */
  display: flex;
  justify-content: center;
  align-items: center;
}

.full-gif {
  width: 100%;
  height: 100%;
  /* aspectFill 会铺满全屏但可能裁剪边缘。若想保证画面完整不怕留白,改用 aspectFit */
}
</style>

⚠️ 避坑指南(非常重要!)

如果你要在生产环境上这个功能,请务必看完以下三点:

1. 缓存导致 GIF 永远停在最后一帧?

问题现象: 用户第一次进页面播放正常,退出再进,发现 GIF 没动静了,直接停在最后一帧,或者从中间开始播。 原因分析: 微信小程序的 <image> 组件缓存机制非常激进,同一个 URL 的 GIF 不会重新渲染播放。 解决方案: 如上述代码所示,在图片 URL 后面拼接动态时间戳 ?t=时间戳。这会让小程序认为这是一张全新的图片,从而强制从第一帧开始加载播放。

2. 低端安卓机直接 OOM 闪退崩溃?

问题现象: 某些安卓手机一进这个页面,小程序直接黑屏、闪退。 原因分析: 全屏 GIF 如果帧率高、尺寸大,解压到手机内存里会极其庞大。微信小程序对单个页面的内存限制非常严格(一般几百M就会告警)。 解决方案: * 严格控制 GIF 体积,务必压缩到 1MB 以内

  • 降低 GIF 帧率,砍掉不必要的颜色。

  • 不要把大 GIF 放在项目包的 static 目录下,占用宝贵的 2MB 包体积,一定要传到服务器或 OSS 上使用网络路径

3. 生命周期选择 onLoad 还是 onShow
  • 如果你想让用户每次切换到这个页面(哪怕是从后台切回来)都看一遍动画 -> 选 onShow

  • 如果你只想让用户在第一次打开这个页面时看一次,后面路由返回不看 -> 选 onLoad


💡 进阶推荐:比 GIF 更好的方案

虽然 GIF 实现简单,但性能和内存消耗极大。如果你的团队对体验要求很高,强烈建议弃用 GIF,改用以下两种方案:

  1. Lottie 动画 (极力推荐): 让 UI 设计师用 AE 导出 JSON 文件,使用微信官方提供的 lottie-miniprogram 插件渲染。体积不到 GIF 的十分之一,全屏矢量放大不模糊,且完美支持播放完成的回调事件,无需再手动写 setTimeout 估算时间!

  2. 无声 MP4 视频: 使用 <video> 标签,设置 autoplay loop="false" controls="false"。在同等画质下,MP4 的体积和内存消耗远小于 GIF,且可以监听 @ended 结束事件。

更多推荐