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

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

前几天写了一篇"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,转载请注明出处。

相关推荐
编程零零七1 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
(⊙o⊙)~哦3 小时前
JavaScript substring() 方法
前端
无心使然云中漫步4 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者4 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_4 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js
麒麟而非淇淋5 小时前
AJAX 入门 day1
前端·javascript·ajax
2401_858120535 小时前
深入理解MATLAB中的事件处理机制
前端·javascript·matlab
阿树梢5 小时前
【Vue】VueRouter路由
前端·javascript·vue.js
随笔写7 小时前
vue使用关于speak-tss插件的详细介绍
前端·javascript·vue.js
史努比.7 小时前
redis群集三种模式:主从复制、哨兵、集群
前端·bootstrap·html