微信小程序弱网监控

前言

在真实的项目中,我们为了良好的用户体验,会根据用户当前的网络状态提供最优的资源,例如图片或视频等比较大的资源,当网络较差时,可以提供分辨率更低的资源,能够让用户尽可能快的看到有效信息,而不是一直白屏等待。

那如何设计一个生产环境可用的小程序当前网络状态监测系统。主要考虑以下几个方面:

  • 首先我们可以粗略的用getNetworkType来获取当前的网络连接类型,当获取到2g或3g等类型时,可以判定当前处于弱网状态。
  • 当处于4g,5g或wifi下,我们的网络也是会有波动的,这个时候就需要我们根据真实的网络下载情况来判断网络状态,
  • 当判断处于弱网时,这个时候我们要持续的来获取当前网络状况,当网络状况好转或设置一个最长检测的时间,当规定时间内,网络依然没有好转,则停止获取网络状况。
  • 通过全局的eventBus系统,将网络状态发射出去,供业务功能处使用。

实现

细节步骤

  • 划定网络的判定标准,也就是什么情况处于弱网,什么时候处于好的网络。

    • 网络类型上2g和3g直接判定为弱网
    • 通过真实请求一张图片,来实际获取当前的网络请求状况,可以有两种方式:
      • 一种是通过耗时,这里选择一个阈值范围1000, 1500,低于1000的为极好网,中间的为好网,超过1500则为
      • 一种是通过,request/download接口回调中提供的profile信息,其中throughputKbps表示当前网络的实际下载kbps。
  • 判断弱网后的处理。判断弱网后,我们不能就直接让我们的资源加载都处于一种弱网的情况,而是判断弱网后,我们要递归的去持续判断网络状态,直至网络状况好转,或有一个最大的重试次数,很长一段时间网络状态都不好,就不用在尝试去判断了,用户也不可能一直在这等待网络好转。

  • 持续监控。也就是判断网络的时机:

    • 一种是监听网络类型的切换,通过wx.onNetworkStatusChange。网络类型切换时,进行网络判断
    • 每一次接口请求的时候,都进行一次网络状态判断,因此,这里我们要封装一个自己的request方法,将通用的逻辑都封装在一处。

代码展示

js

javascript 复制代码
// import eventBus from './eventBus';
const NETWORK_STATUS = {
    OFFLINE: 'offline',
    POOR: 'poor',
    GOOD: 'good',
    WONDERFUL: 'wonderful'
}
// 小于1000表示网络极好,1000至1500则表示good 超过1500表明是弱网。
const DOWNLOAD_TIME = [1000, 1500];
const MAX_COUNT = 10;
let count = 0;
function getNetworkType() {
    return new Promise((resolve) => {
        wx.getNetworkType({
            success(res) {
                resolve(res);
            },
            fail(err) {
                resolve(err);
            }
        })
    })
}
const getNetworkStatus =  (opt) => {
    return new Promise((resolve) => {
        try {
            let networkType = opt && opt.networkType;
            let networkStatus = NETWORK_STATUS.WONDERFUL;
            if (!networkType) {
                networkType = getNetworkType().then(({networkType}) => {
                    if (['unknown', 'none'].includes(networkType)) {
                        emitNetworkStatus(NETWORK_STATUS.OFFLINE);
                        return resolve(NETWORK_STATUS.OFFLINE);
                    }
                    if (['2g', '3g'].includes(networkType)) {
                        emitNetworkStatus(NETWORK_STATUS.POOR);
                        return resolve(NETWORK_STATUS);
                    }
                    const startTime = +new Date();
                    requestImage().then((result) => {
                        const requestTime = +new Date() - startTime;
                        
                        if (requestTime < DOWNLOAD_TIME[0]) {
                            networkStatus = NETWORK_STATUS.WONDERFUL;
                        } else if (requestTime > DOWNLOAD_TIME[1]) {
                            networkStatus = NETWORK_STATUS.POOR;
                        } else {
                            networkStatus = NETWORK_STATUS.GOOD;
                        }
                        emitNetworkStatus(networkStatus);
                        return resolve(networkStatus);
                    })
                   
                });
            }
        } catch (error) {
            resolve(NETWORK_STATUS.WONDERFUL);
        }
    })
   
}

function run() {
    if (count >= MAX_COUNT) {
        return;
    }
    const timer = setTimeout( () => {
        getNetworkStatus().then(networkStatus => {
            count += 1;
            if ([NETWORK_STATUS.POOR, NETWORK_STATUS.GOOD].includes(networkStatus)){
                run();
            }
        })
        clearTimeout(timer);
    }, 5000)
}
function start(opt) {
    const timer = setTimeout( () => {
        getNetworkStatus(opt).then(networkStatus => {
            if ([NETWORK_STATUS.POOR, NETWORK_STATUS.GOOD].includes(networkStatus)) {
                run();
            }
        })
        
        clearTimeout(timer);
    }, 1000)
}
function requestImage() {
    return new Promise((resolve) => {
        wx.request({
            url: 'https://dss0.bdstatic.com/-0U0bnSm1A5BphGlnYG/tam-ogel/-146383143_-1016538910_80_80.png',
            data: {
                time: +new Date(),
            },
            success(res) {
                resolve(res);
            },
            fail() {
                resolve()
            }
        })
    })
}
function emitNetworkStatus(networkStatus) {
    const app = getApp();
    const oldNetwordStatus  = app.globalData.networkStatus;
    // 只有本次状态与上一次存储的不一致才会对外发送。
    if (oldNetwordStatus !== networkStatus) {
        app.globalData.networkStatus = networkStatus;
        // 通过全局的事件系统,将结果发送出去
        // eventBus.emit('networkChange', networkStatus, oldNetwordStatus);    
    }
}

export const networkController = {
    start,
};

eventBus功能可以根据自己的项目自行封装,这里不再多述。

调用时机

  • app.js中的onLaunch钩子中,监听wx.onNetworkStatusChange。在其中调用我们的方法

js

javascript 复制代码
 wx.onNetworkStatusChange((res) => {
      networkController.start(res);
    })
  • 另一种就是在我们封装的request函数内,每次请求接口时调用一次。这样能够保证我们可以不那么频繁但有效的去判断是否去判断当前网络状态

总结

作为一个c端产品,针对弱网的优化是必不可少的。用户体验问题要一直放在最重要的位置,作为开发人员要时刻关注这些点,以免给用户造成不好的体验。

如果有更好的意见,辛苦评论区指出,共同学习,共同提高。

相关推荐
LBuffer1 分钟前
破解入门学习笔记题二十五
服务器·前端·microsoft
richxu2025100123 分钟前
Linux本地部署deepseek大模型之 6. Windows本地连接远程云服务器中的MySQL常见错误的解决办法
linux·服务器·windows
Ryan ZX26 分钟前
Ubuntu 升级OpenSSH10.2p1与OpenSSL3.5.4版本避坑实践
linux·运维·服务器·ubuntu
唐兴通个人2 小时前
新品上市咨询顾问新药上市顾问培训讲师唐兴通讲PMF从0到1天使用户种子用户冷启动问题
运维·服务器
serve the people2 小时前
Partial Prompt Templates in LangChain
服务器·langchain·prompt
七夜zippoe2 小时前
高性能网络编程实战:用Tokio构建自定义协议服务器
linux·服务器·网络·rust·tokio
桃子不吃李子2 小时前
简单搭建express服务器
运维·服务器·express
owCode2 小时前
Linux中的管道
linux·运维·服务器
北亚数据恢复2 小时前
服务器数据恢复—raid5阵列硬盘离线搞崩溃,分区数据恢复案例来袭
运维·服务器
neo_will_mvp2 小时前
服务器bmc功能
linux·运维·服务器