百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

5.25秒变0.023秒:小程序图片优化全攻略

liuian 2025-01-20 14:45 12 浏览

本文首发于lonjin个人博客

往期精彩: 如何评价Dooring零代码平台

最近在公司在写微信小程序,该小程序主要展示一些高清图片,所以图片数量非常多,而且图片尺寸也比较大,导致小程序的加载时间非常长。所以这里记录一下如何减少小程序图片的加载时间。

优化前

这里我挑选了一些项目里面比较大的图片,还有我之前保存的一些背景图,共计12张,上传到阿里云oss,然后写了一个demo去渲染图片,这里我们先看看加载时间。

pFpoHTU.png

可以看到,一旦文件大小到了1M以上,加载基本都在1秒以上了,而且加载最慢的一张图片大小为2.4M;加载耗时5.27秒。然而在这个小程序中,有非常多的瀑布流图片展示,需要加载的图片也非常多,这对于这种图片展示类的小程序来说,简直是非常糟糕的体验。下面我们就分析一下,如何提升用户体验,缩短加载时间。

分析优化

这里我总结了一些常见图片优化策略,方法如下:

pFpojp9.png

下面我们就根据总结的优化策略进行优化,具体如下:

优化1:使用webp格式的图片

首先我们知道,在小程序中是支持webp格式的图片的,所以我们可以将图片转换为webp格式,这样可以减少图片体积,提升加载速度。 公司使用的阿里云oss进行图片存储,阿里云oss是支持格式转换的,只需要在图片url后面加一定的参数即可,我们可以给图片后面加上?x-oss-process=image/format,webp即可。

// 原本图片路径:
let url =' https://lonjin.oss-cn-beijing.aliyuncs.com/weixin-test/3%20%282%2917047050403470042.png'

// 转化为webp格式的图片路径:
let url =' https://lonjin.oss-cn-beijing.aliyuncs.com/weixin-test/3%20%282%2917047050403470042.png?x-oss-process=image/format,webp'

清除缓存,刷新页面,再来看加载时间:

pFpoqkF.png

可以看到,加载时间大幅缩短,图片格式转化后,图片大小已经非常小了,最大的一张图片仅仅有730kb;随之加载时间也大幅缩短,最慢的一张图片从之前的5.27秒缩短为1.71秒,加载速度提升了3倍!其他的图片加载基本都在500ms左右,加载速度提升也是比较明显。

这里我们还需要注意一下webp图片格式的支持范围,我这里使用的uni-app做为demo,查了一下文档,支持范围如下:

Android4以上(含)、iOS14以上(含)系统内置支持webp,此时,不管web、小程序、app,也不管vue/nvue/uvue都可以直接使用webp; iOS14以下,app-vue下,iOS不支持;app-nvue/uvue下,iOS支持;微信小程序2.9.0起,配置属性webp为true时iOS支持;

所以如果考虑一些特殊情况,我们可以进行一些特殊情况下的处理。

如果文件是直接放在服务器上的,我们可以借助一些第三方工具来把图片批量转化为webp格式;比如convertio.co

优化2:根据需求设置适当的分辨率

阿里云oss支持在图片后面加上参数来设置图片的分辨率,我这里写的demo中,image标签图片宽度均为小程序图片默认宽度;即为width: 320px;,所以我们可以给图片url后面加上/resize,w_320即可,其中w_320表示图片宽度为320px

// 原本图片路径:
let url =' https://lonjin.oss-cn-beijing.aliyuncs.com/weixin-test/3%20%282%2917047050403470042.png?x-oss-process=image/format,webp'

// 设置宽度后的图片路径:
let url =' https://lonjin.oss-cn-beijing.aliyuncs.com/weixin-test/3%20%282%2917047050403470042.png?x-oss-process=image/format,webp/resize,w_320'

清除缓存,刷新页面,再来看加载时间:

pFpoLY4.jpg

图片大小大幅度减少,最大的一张图片仅仅有15.4 kB;随之加载时间也大幅缩短,最慢的一张图片从之前的1.71秒缩短为316毫秒,加载速度提升了5倍!这时候所有图片的加载速度全部没有超过1秒,最大不超过350ms;基本上算是质的飞跃了。不过需要注意的是,图片分辨率还是需要结合业务需求进行调整的,如果要求必须高清,不建议设置太小的分辨率。不过我们可以写一个检测用户网络状态的方法,在不同的网络环境下加载不同分辨率的图片;后面我会专门来写一篇文章来实现这个功能。

优化3:使用雪碧图

雪碧图,也叫Sprite,是将多个小图片合并成一张大图,然后在页面中使用background-imagebackground-position属性来显示其中的某一张图片。这样可以减少图片的加载次数,减少图片的大小,同时减少图片的加载时间。在项目中难免会有很多小图标,我们就可以使用雪碧图的方式来使用,减少请求次数。这里我就不做展示了。

优化4:合理使用占位图片

通常情况下,为了内容的动态展示,需要通过网络请求从接口中获取图片的url。如果在网络慢的情况下,image加载图片的过程可能会非常慢,在请求完成之前页面都会因为没有数据而呈现一片空白,这是非常差的用户体验,这里我们可以借助小程序image标签上的@error @load事件来实现占位图片的展示。我们可以根据需求去封装一个LoadImage组件统一处理,上面提到的优化1优化2也可以通过定义参数实现批量添加,同时我们也可以给组件加上lazyLoad,减轻小程序加载压力。

组件具体代码如下:

<template>
    <view class="loadImage-wrapper">
        <image v-if="isLoading" :src="defaultImage" :mode="mode" :lazy-load="lazyLoad" />
        <image :class="[isLoading ? 'before-load' : '']" :src="imageUrl" :mode="mode" :lazy-load="lazyLoad"
            @load="imageLoad" />
    </view>
</template>
<script>
export default {
    props: {
        /**
         * 占位图
         * @default /static/images/load-image.png
         */
        defaultImage: {
            type: String,
            default: '/static/load-image.png',
        },
        /**
         * 是否使用webp
         * @default false
         */
        useWebp: {
            type: Boolean,
            default: false,
        },
        /**
         * 图片的显示模式
         * @default scaleToFill
         */
        mode: {
            type: String,
            default: 'scaleToFill',
        },
        /**
         * 图片加载分辨率-宽度
         * @default 
        */
        width: {
            type: String,
            default: '',
        },
        /**
         * 是否懒加载
         * @default true
         */
        lazyLoad: {
            type: Boolean,
            default: true,
        },
        /**
         * 图片地址
         * @default 
        */
        src: {
            type: String,
            default: '',
        },
    },
    data() {
        return {
            isLoading: true,
        }
    },

    methods: {
        imageLoad() {
            this.isLoading = false
        },
    },

    computed: {
        imageUrl() {
            let url = this.src + '?'
            this.useWebp && (url += 'x-oss-process=image/format,webp')
            this.width && (url += '/resize,w_' + this.width)
            return url
        }
    },
}
</script>
<style lang="scss" scoped>
.loadImage-wrapper {
    .before-load {
        width: 0;
        height: 0;
        opacity: 0;
    }
}
</style>

使用方式如下:

<template>
    <view class="list">
        <load-image v-for="(item, index) in list" :src="item" :lazyLoad="false" useWebp :width="320" :key="index" />
    </view>
</template>

优化后效果对比

我们再来看一下优化前后的加载时间对比:

  • 优化前:
  • 优化后:

我们用一张图片来做对比:

图片名称 大小 加载时间 优化前 wallhaven-we3z86.jpeg 2.4MB 5.27s 优化后 wallhaven-we3z86.jpeg 15.3KB 23ms

可以看到相对体积而言,缩小了99.4%;相对加载时间,缩短了5.25秒,在几乎不影响图片质量的情况下,极大的提升了用户体验。

总结

关于小程序的图片优化,我们可以根据业务需求以及技术支持来选择不同的方案,这里我只列出了几个最常用的方案,如果业务需求比较复杂,可以多尝试一些方案。

相关推荐

Flutter——输入部件

上一节介绍了文本部件,用于显示文本。但是在我们进行日常软件开发过程中,经常是需要获取用户键入的内容,比如用户名、密码、性别、喜好等等。Flutter提供了丰富的部件来处理用户输入,本节将主要介绍以下...

flutter系列之:做一个图像滤镜

简介很多时候,我们需要一些特效功能,比如给图片做个滤镜什么的,如果是h5页面,那么我们可以很容易的通过css滤镜来实现这个功能。那么如果在flutter中,如果要实现这样的滤镜功能应该怎么处理呢?一起...

免费好用还高级!3个必须知道的设计网站,让你的PPT好看10倍

哈喽,大家早上好鸭~好久不见,我是三石,今天我又来进行PPT技巧分享啦~诶,这不前几天编辑部的萌萌就来找我约稿,说小叶子们对于神器网站的呼声很高,问我能不能写一篇文章汇总一下,我二话没说就答应了。常言...

flutter软件开发笔记08-容器使用方法

在Flutter3中,容器组件是用于布局、装饰或约束子组件的核心部件,能让程序更加美观,如何学习呢,能快速的应用起来,下面通过例子,来快速理解各种容器组件的使用方法。一程序界面二代码实现imp...

Tauri:下一代桌面应用开发框架?

大厂技术坚持周更精选好文本文为来自教育-智能学习-前端团队成员的文章,已授权ELab发布。智能学习前端团队自创立以来,团队专注于打破大众对教育的刻板印象,突破固有的教学思维,攻破各类...

Google移动开发平台Flutter发布 iOS和Android开发者神器

在昨晚的FlutterLive2018上,Google宣布Flutter1.0正式发布。这是一个基于Dart的移动开发平台,旨在帮助开发者在iOS和Android两个平台上...

Flutter如何内存优化

Flutter是一种流行的跨平台移动应用程序开发框架,它提供了一种高效的方式来构建美观、快速、可靠的应用程序。然而,随着应用程序规模的增加,内存管理成为了一个重要的问题。本文将探讨如何优化Flutte...

阿里卖家 Flutter for Web 工程实践

作者:马坤乐(坤吾)Flutter自2015年初次亮相以来,经过了多年的发展已经相当成熟,在阿里、美团、拼多多等互联网公司都有广泛的应用。在ICBU阿里卖家上90+%的新业务使用Flu...

Flutter——按钮

上一节介绍了输入组件,让我们了解了输入框、单选、多选、进度条等部件。为了响应用户的点击或触摸操作,就需要学习一种新的部件-按钮。Flutter中有多种类型的按钮,用于响应用户的点击或触摸操作。接下来...

Flutter vs React Native 性能测试结果

FluttervsReactNative性能测试结果:谁才是王者?大家好,我是猫哥。今天会去讲一下Flutter和ReactNative的性能比较的情况。首先说一下ReactNative猫哥...

定位Flutter内存问题很难么?

内存水位升高导致的稳定性问题严重影响app用户体验,所以开发者们非常关注Flutter的内存表现。随着Flutter业务越来越多,闲鱼也面临着oom导致的crash率提升的问题,下面我们结合项目中实际...

超详解析Flutter渲染引擎|业务想创新,不了解底层原理怎么行?

作者|万红波(远湖)出品|阿里巴巴新零售淘系技术部前言Flutter作为一个跨平台的应用框架,诞生之后,就被高度关注。它通过自绘UI,解决了之前RN和weex方案难以解决的多端一致性...

flutter软件开发笔记25-内置组件总结

以下是Flutter内置的核心UI组件分类及常用组件列表,方便你系统化学习和掌握:1.基础组件组件名说明Text显示文本,支持样式、换行和富文本(TextSpan)Icon显示Materi...

Flutter CarouselView 3.24版本的一个新组件

Flutter3.24带来了几个令人兴奋的新功能,其中最引人注目的是CarouselView小部件。这个小部件允许开发人员创建可滚动的、动态的项目列表,这些列表可以在进入和退出视图时调整大小,这对于...

详解Flutter如何用思源宋体炫出你的UI

如何实现使用思源宋体字体样式。首先,让我们来了解一下什么是资源素材管理。简单来说,它就是为了方便我们管理各种资源文件,比如图片、字体、音频等。在Flutter中,我们可以使用pubspec.yam...