小程序网络监控大揭秘:如何实时监听网络变化

小程序网络监控大揭秘:如何实时监听网络变化

前几天写了一篇"5.25秒变0.023秒:小程序图片优化全攻略";介绍了一些小程序图片优化技巧,在文章中提到我们可以借助当前用户的网络状态去加载对应分辨率的图片。下面我们就实现一下这个功能。看之前记得一键三连,先赞后看;月入过万!

需求分析

首先我们需要去写一个下载方法,通过下载来计算请求耗时,然后通过所需耗时来判断网络状态,如果网络状态不好,则进行几次重试,看看是否有更好的网络状态。同时我们还需要使用wx.onNetworkStatusChange这个api来监听网络状态的变化;该api会在用户网络切换时候触发,一旦触发,我们需要重新执行下载方法来判断当前的网络状态。

功能实现

我这里demo使用uni-app开发,所以有些api可能是uni.开头,如果你使用小程序原生开发,换成wx.即可。

新建/utils/networkManager.js,我们先定义一些基本的参数:

js 复制代码
class NetworkManager {
    constructor() {
        // 最大重试次数
        this.MAX_RETRY_COUNT = 3
        // 当前重试次数
        this.retryCount = 0
        // 当前网络状态
        this.currentNetworkStatus = ''
        // 网络状态改变回调
        this.statusChangeCallback = null
        // 图片地址
        this.url = ''
    }
}

然后我们去添加两个函数,用来设置图片地址和网络状态改变的回调函数:

js 复制代码
class NetworkManager {
    constructor() {
        // ...省略
    }
    /**
     * 设置网络状态变化的回调函数
     * @param {*} callback 
     */
    setChangeCallback(callback) {
        this.statusChangeCallback = callback
    }

    // 设置请求的url
    setRequestUrl(url) {
        this.url = url
    }
}

如何判断当前网络到底好不好呢?我们可以通过uni.downloadFile来下载一张1M-2M大小的图片,通过下载时间来判断网络情况。当请求耗时在1000ms以内,则认为网络极好,如果介于1000-1500ms之间,则认为网络好,如果大于1500ms,则认为网络差。如果网络非常差的时候,我们需要多请求几次,来持续判断网络是否有好转,如果超过我们定义的最大重试次数就停止请求。

js 复制代码
class NetworkManager {
    constructor() {
        // ...省略
    }
    // 请求方法
    request() {
        return new Promise((resolve, reject) => {
            // 记录当前时间
            const startTime = Date.now()
            uni.downloadFile({
                url: `${this.url}?timer=${startTime}`,
                success: (res) => {
                    // 记录结束时间
                    const endTime = Date.now()
                    // 时间差
                    const duration = endTime - startTime
                    // 判断网络情况
                    this.checkNetworkStatus(duration)
                    resolve(res)
                },
                fail: (res) => {
                    // 进行重试
                    this.retryCount++
                    if (this.retryCount < this.MAX_RETRY_COUNT) {
                        this.request()
                    } else {
                        console.log('网络状态不佳,已停止')
                        // 重试次数归零
                        this.retryCount = 0
                        reject(res)
                    }
                },
            })
        })
    }

    /**
     * 判断网络状态
     * @param {*} duration 请求耗时ms
     */
    checkNetworkStatus(duration) {
        const previousStatus = this.currentNetworkStatus
        if (duration < 1000) {
            this.currentNetworkStatus = 'veryGood'
        } else if (duration >= 1000 && duration <= 1500) {
            this.currentNetworkStatus = 'good'
        } else {
            this.currentNetworkStatus = 'poor'
            // 请求失败,开始判断
            if (this.retryCount < this.MAX_RETRY_COUNT) {
                this.retryCount++
                this.request()
            } else {
                // 达到最大重试次数,停止递归
                this.retryCount = 0
                console.log('网络状态不佳,已停止')
            }
        }

        // 判断网络状态是否发生变化,如果有变化,就通知回调函数
        if (previousStatus !== this.currentNetworkStatus && this.statusChangeCallback) {
            this.statusChangeCallback(this.currentNetworkStatus)
        }
    }
}

最后我们还需要写一个开启函数,用来启动网络监听,同时使用uni.onNetworkStatusChange来监听用户网络环境变化,如果有变化则进行一次请求。

js 复制代码
class NetworkManager {
    constructor() {
        // ...省略
    }
    /**
     * 开启监听
     * @returns 
     */
    start() {
        if (!this.url) {
            console.error('请设置请求的url')
            return
        }
        // 执行请求
        this.request()
        // 网络环境变换后,重新请求
        uni.onNetworkStatusChange(() => {
            this.request()
        })
    }
}

使用方式

我们来看一下最终的使用方式:

js 复制代码
// 使用示例
const networkManager = new NetworkManager()
// 设置请求的url
networkManager.setRequestUrl('https://lonjin.oss-cn-beijing.aliyuncs.com/weixin-test/wallhaven-o5g125.jpeg')
// 设置网络状态变化的回调函数
networkManager.setChangeCallback((newStatus) => {
    // 这里可以把结果存到全局变量中,在其他页面方便使用
    console.log('网络状态变化:', newStatus)
})
// 启动
networkManager.start()

总结

我们通过uni.downloadFile来下载一张图片,通过下载时间来判断网络情况,然后通过uni.onNetworkStatusChange监听网络环境变化,当网络环境变化时,重新请求;从而去根据网络状态去请求不同大小的资源文件,减少白屏时间,提升用户体验。最后欢迎关注我的专栏前端365,分享前端相关文章,欢迎关注。

往期推荐文章📚

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

🏷️5分钟get:Uni-App网络请求完美封装指南!

🏷️uni-app开发小程序:项目架构以及经验分享

🏷️小程序TabBar创意动画(文末附完整源代码)

⚠️注意

本文首发于我的博客:lonjin,转载请注明出处。

相关推荐
轻口味9 分钟前
【每日学点鸿蒙知识】Web嵌套滚动体验、拷贝传递 ArrayBuffer异常问题、ObjectLink 的属性传递、构建读取参数
前端·华为·harmonyos
lauo9 分钟前
【智体OS】官方上新发布“空钥登陆”--方便访客使用智体操作系统OS和智体应用
前端·javascript·分布式·机器人·开源
哥谭居民000112 分钟前
普通的树形数据primevue的treetable组件的treetable[ ]
前端·javascript·算法
龙少954317 分钟前
【前端实现pdf导出】
前端·pdf
轻口味18 分钟前
【每日学点鸿蒙知识】异步介绍、上传app报错、Web控件接口、应用名称自定义配置、ActionSheetOptions自定义
前端·华为·harmonyos
m0_748247801 小时前
构建 Java Web 应用程序:从 Servlet 到数据库交互(Eclipse使用JDBC连接Mysql数据库)
java·前端·数据库
一枚前端小姐姐1 小时前
Node多版本共存与切换--通过nvm切换
前端·node.js
阿卡基YUAN2 小时前
JavaScript 箭头函数
前端·javascript
轻口味2 小时前
【每日学点鸿蒙知识】Web高度适配、变量声明规范、动画取消、签名文件、包体积优化相关
前端·华为·harmonyos
小刘|2 小时前
深入理解 Cookie 和 Session 在 Java Web 中的应用
java·前端·python