微信小程序弱网监控

前言

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

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

  • 首先我们可以粗略的用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端产品,针对弱网的优化是必不可少的。用户体验问题要一直放在最重要的位置,作为开发人员要时刻关注这些点,以免给用户造成不好的体验。

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

相关推荐
sun0077003 小时前
ubuntu dpkg 删除安装包
运维·服务器·ubuntu
oi773 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
学Linux的语莫5 小时前
Ansible使用简介和基础使用
linux·运维·服务器·nginx·云计算·ansible
Onlooker1295 小时前
云服务器部署WebSocket项目
服务器
学Linux的语莫5 小时前
搭建服务器VPN,Linux客户端连接WireGuard,Windows客户端连接WireGuard
linux·运维·服务器
legend_jz5 小时前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
黑牛先生5 小时前
【Linux】进程-PCB
linux·运维·服务器
Karoku0665 小时前
【企业级分布式系统】ELK优化
运维·服务器·数据库·elk·elasticsearch
安迁岚6 小时前
【SQL Server】华中农业大学空间数据库实验报告 实验三 数据操作
运维·服务器·数据库·sql·mysql