小程序优化:第三方SDK过大解决方案

本文涉及的产品
.cn 域名,1个 12个月
简介: 小程序开发中,项目目录中存放过大的js包,会被警告影响手机端性能,同时让开发编译启动变得很慢。慢是其次,单是影响性能这一点,就需要解决一下。

【前言】

小程序开发中,有时会遇到下面这种情况,项目目录中存放过大的js包,会被警告影响手机端性能,同时让开发编译启动变得很慢。慢是其次,单是影响性能这一点,就需要解决一下。

1821793-20231225103446209-185837392.png

【云资源】

将项目js包放入公司的oss、obs之类的云存储上,通过https链接来访问。

https链接不能使用node的require加载,会抛错,但是可以通过其他两种方式进行访问:

  1. request请求
  2. fileSystemManager文件管理器

方法1简单,但是不可取,原因如下:

1) 获得的文件信息,没有较好的保存方法,既不能存在store中,也不能存在local中,不仅是数据存储格式问题,更重要的同样会造成性能缺点,总不能解决了一个问题,又创造新的问题;

2) 由于1)描述的那样,如果不能存储文件,那么每次需要依赖这个文件时,就需要每次请求接口,这就造成了资源浪费。

故此,基于以上两点,只能负重前行,选择较为麻烦和让人头疼的方案2(fileSystemManager文件管理器),虽然麻烦,但是却可以一劳永逸,并且可以抽离逻辑封装成一套方法,可以在以后复用。

【前期准备】

实现方案前,有几个注意事项:

1、首先要将存放云资源的oss或obs的域名配置在白名单中,这里就需要配置request合法域名和downloadFile合法域名。

1821793-20231225104031681-2095693289.png

2、需要勾选“不校验合法域名...”,不勾选的话,真机会遇到意想不到的问题。

1821793-20231225104331363-1290077724.png

3、将js文件转成json文件,如果没办法,就自行抽离js包,拆出一个json文件,因为微信fileSystemManager不支持读取js文件,js文件会变成string文本,但是支持json。

当然,如果你觉得可以使用JavaScript 解释器来破这个局,那么你又一次要碰壁了,微信官方对此做了限制,禁止eval5、estime、evil-eval等动态执行代码的js解释器。

1821793-20231225104449146-1270363565.png

原文地址:关于禁止小程序JavaScript解释器使用规范要求

【方案思考】

fileSystemManager,它是getFileSystemManager返回的对象,给我们暴露出了多个方法,下面为部分截图:

1821793-20231225140229869-495781978.png

原文地址:FileSystemManager

为保证性能和可靠性,这里我们采用下面这种方案:

首次:下载 + 保存 + 读取,非首次:直接读取
流程图如下:

1821793-20231225140245946-681514229.png

【方法封装】

我这里提供了两种封装写法:
链式写法,方便回调处理,不需要回调可以采用写法2
解耦式写法,降低了函数颗粒度,每个方法独立,更加灵活,可以单独使用某一个函数

千言万语,前面的铺垫已完成,直接上代码:
链式写法

/**
 * 读取静态资源,如果没有该资源,则触发下载,并保存至用户本地
 * 注意:此方法为链式调用,如果需要单独的方法,可选择下面拆分过的独立方法
 * @param {String} name 文件名 -必传
 * @param {String} url 文件路径 -必传
 * @param {Function} callback 是否需回调操作 -非必传
 */
export async function getSystemFileInfoToChain(name = 'jn', url, callback = null) {
  if (!url) {
    return;
  }
  const fileManager = uni.getFileSystemManager();
  // 用户文件路径
  let filePath = `${uni.env.USER_DATA_PATH}/${name}`;
  // 读取静态资源,如果没有该资源,则触发下载
  try {
    let res = await fileManager.readFileSync(filePath, 'utf-8');
    const resData = res && JSON.parse(res);
    let resFile = await fileManager.readFileSync(url, 'utf-8');
    console.log('🆒 fileManager 111', resData, name, url, resFile);
    if (callback && typeof callback === 'function') {
      callback(resData);
    }
    // 暴露出文件内容
    return resData;
  } catch (err) {
    console.log('getSystemFileInfoToChain err', err);
    // 下载文件至本地
    try {
      const res = await uni.downloadFile({
        url
      });
      let tempFilePath = res?.[1]?.tempFilePath;
      console.log('🆒 fileManager 222', tempFilePath);
      if (!tempFilePath) {
        return;
      }
      // 保存文件至本地
      try {
        await fileManager.saveFileSync(tempFilePath, filePath);
        console.log('🆒 fileManager 333', url);
        // 再次触发,获得需要的数据
        getSystemFileInfoToChain(name, url, callback);
      } catch (err) {
        console.log('saveFileSync err', err);
      }
    } catch (err) {
      console.log('downloadFile err', err);
    }
  }
}

解耦式写法

/**
 * 读取静态资源,如果没有该资源,则触发下载,并保存至用户本地
 * @param {String} name 文件名 -必传
 * @param {String} url 文件路径 -必传
 * @param {Boolean} next 是否下一步(如果读取失败,则下载文件至本地) -非必传
 */
export async function getSystemFileInfo(name = 'jn', url, next = false) {
  const fileManager = uni.getFileSystemManager();
  // 用户文件路径
  let filePath = `${uni.env.USER_DATA_PATH}/${name}`;
  try {
    let res = await fileManager.readFileSync(filePath, 'utf-8');
    const resData = res && JSON.parse(res);
    console.log('🆒 fileManager 111', resData);
    // 暴露出文件内容
    return resData;
  } catch (err) {
    // 允许下一步(下载文件),且有url,进行下载保存
    next && url && onDownloadFile(name, url, next);
    console.log('readFileSync err', err);
  }
  // console.log('🆒 fileManager', fileManager, uni.env.USER_DATA_PATH);
}

/** 
 * 下载文件至本地
 * @param {String} name 文件名 -必传
 * @param {String} url 文件路径 -必传
 * @param {Boolean} next 是否下一步(文件内容读取) -非必传
 */
export async function onDownloadFile(name = 'jn', url, next = false) {
  if (!url) {
    return;
  }
  try {
    const res = await uni.downloadFile({
      url
    });
    let tempFilePath = res?.[1]?.tempFilePath;
    console.log('🆒 fileManager 222', tempFilePath);
    onSaveFile({ name, url }, tempFilePath, next);
  } catch (err) {
    console.log('downloadFile err', err);
  }
}

/**
 * 保存文件至本地
 * @param {String} params[0].name 文件名 -必传
 * @param {String} params[0].url 文件路径 -非必传
 * @param {String} tempFilePath 临时文件路径 -必传
 * @param {Boolean} next 是否下一步(文件内容读取) -非必传
 */
export async function onSaveFile({
  name = 'jn',
  url
}, tempFilePath, next = false) {
  if (!tempFilePath) {
    return;
  }
  const fileManager = uni.getFileSystemManager();
  // 用户文件路径
  let filePath = `${uni.env.USER_DATA_PATH}/${name}`;
  try {
    await fileManager.saveFileSync(tempFilePath, filePath);
    // 允许下一步(文件内容读取),且有url,进行文件内容读取
    next && url && getSystemFileInfo(name, url, false);
    console.log('🆒 fileManager 333', url);
  } catch (err) {
    console.log('saveFileSync err', err);
  }
}

到此,就封装完成了,后面使用看具体场景,来选择链式、解耦式写法。

相关文章
|
27天前
|
小程序 JavaScript 前端开发
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
466 1
|
5天前
|
小程序 机器人 开发者
QQ 小程序已发布,但无法被搜索的解决方案
我的 QQ 小程序在 2024 年 8 月就已经审核通过,上架后却一直无法被搜索到。打开后,再在 QQ 上下拉查看 “最近使用”,发现他出现一下又马上消失。
13 2
|
1月前
|
缓存 小程序 索引
uni-app开发微信小程序时vant组件van-tabs的使用陷阱及解决方案
uni-app开发微信小程序时vant组件van-tabs的使用陷阱及解决方案
170 1
|
1月前
|
机器学习/深度学习 人工智能 JSON
微信小程序原生AI运动(动作)检测识别解决方案
近年来,疫情限制了人们的出行,却推动了“AI运动”概念的兴起。AI运动已在运动锻炼、体育教学、线上主题活动等多个场景中广泛应用,受到互联网用户的欢迎。通过AI技术,用户可以在家中进行有效锻炼,学校也能远程监督学生的体育活动,同时,云上健身活动形式多样,适合单位组织。该方案成本低、易于集成和扩展,已成功应用于微信小程序。
|
1月前
|
小程序 Java
小程序访问java后台失败解决方案
小程序访问java后台失败解决方案
43 2
|
1月前
|
机器学习/深度学习 人工智能 小程序
做AI运动小程序有哪些解决方案,如何进行选型?
随着深度学习技术的发展,AI运动应用如“天天跳绳”和“百分运动”变得流行。本文探讨了将AI运动功能引入微信小程序的可行性,并介绍了几种解决方案。实现AI运动计数的关键技术包括视频抽帧、人体检测、姿态识别等。文中详细描述了离线方案(全离线和半离线)和原生方案(自研AI引擎和成熟插件)的不同实现方式,并对各种方案进行了对比,建议优先选择成本低、体验佳的AI运动识别插件方案。
|
1月前
|
JSON 小程序 前端开发
微信小程序-人脸核身解决方案
微信小程序-人脸核身解决方案
153 0
|
1月前
|
云安全 存储 小程序
PHP微信小程序解决方案PhpMall
PHP微信小程序解决方案PhpMall
37 0
|
1月前
|
小程序
微信小程序之weui.wxss不能引用查找的解决方案
微信小程序之weui.wxss不能引用查找的解决方案
50 0
|
2月前
|
小程序 前端开发 API
微信小程序 - 调用微信 API 回调函数内拿不到 this 问题(解决方案)
本文讨论了在微信小程序中调用API回调函数时无法获取到`this`上下文的问题,并提供了解决方案。在回调函数中,使用一个变量(如`that`)来保存当前的`this`引用,然后在回调内部使用这个变量来访问当前页面的数据和方法。

热门文章

最新文章