图片优化

167 阅读2分钟

文章来源

背景

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

使用webp格式图片

  • 在小程序中是支持webp格式的图片的,所以我们可以将图片转换为webp格式,
  • webp可以减少图片体积,提升加载速度。
  • 公司使用的阿里云oss进行图片存储
  • 只需要在图片url后面加一定的参数即可
// 原本图片路径:
let url =' https://.../50403470042.png'

// 转化为webp格式的图片路径:
let url =' https://.../50403470042.png?x-oss-process=image/format,webp'

根据需求设置适当的分辨率

  • 阿里云oss支持在图片后面加上参数来设置图片的分辨率,
  • 我们可以给图片url后面加上/resize,w_320即可,
  • 其中w_320表示图片宽度为320px
// 原本图片路径:
let url =' https://.../3%20%282%2.png?x-oss-process=image/format,webp'

// 设置宽度后的图片路径:
let url =' https://.../3%20%282%2.png?x-oss-process=image/format,webp/resize,w_320'

合理使用占位图片

  • 如果在网络慢的情况下,image加载图片的过程可能会非常慢,
  • 在请求完成之前页面都会因为没有数据而呈现一片空白,这是非常差的用户体验,
  • 这里我们可以借助小程序image标签上的@error @load事件来实现占位图片的展示。
  • 我们可以根据需求去封装一个LoadImage组件统一处理
<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>

雪碧图

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

CDN

生产环境下我们不会直接用 OSS 的 URL 访问,而是会开启 CDN,用网站域名访问,最终回源到 OSS 服务:

image.png

image.png