经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » 微信小程序 » 查看文章
小程序优化:第三方SDK过大解决方案
来源:cnblogs  作者:一杯龙井解千愁  时间:2023/12/26 9:51:09  对本文有异议

【前言】

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

 

 

【云资源】

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

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

  1. request请求

  2. fileSystemManager文件管理器

 

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

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

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

 

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

 

 

【前期准备】

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

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

 

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

 

 

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

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

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

 

 

【方案思考】

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

原文地址:FileSystemManager

 

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

首次:下载 + 保存 + 读取,非首次:直接读取

流程图如下:

 

 

 

【方法封装】

我这里提供了两种封装写法:

  1. 链式写法,方便回调处理,不需要回调可以采用写法2
  2. 解耦式写法,降低了函数颗粒度,每个方法独立,更加灵活,可以单独使用某一个函数

 

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

链式写法

  1. /**
  2. * 读取静态资源,如果没有该资源,则触发下载,并保存至用户本地
  3. * 注意:此方法为链式调用,如果需要单独的方法,可选择下面拆分过的独立方法
  4. * @param {String} name 文件名 -必传
  5. * @param {String} url 文件路径 -必传
  6. * @param {Function} callback 是否需回调操作 -非必传
  7. */
  8. export async function getSystemFileInfoToChain(name = 'jn', url, callback = null) {
  9. if (!url) {
  10. return;
  11. }
  12. const fileManager = uni.getFileSystemManager();
  13. // 用户文件路径
  14. let filePath = `${uni.env.USER_DATA_PATH}/${name}`;
  15. // 读取静态资源,如果没有该资源,则触发下载
  16. try {
  17. let res = await fileManager.readFileSync(filePath, 'utf-8');
  18. const resData = res && JSON.parse(res);
  19. let resFile = await fileManager.readFileSync(url, 'utf-8');
  20. console.log('?? fileManager 111', resData, name, url, resFile);
  21. if (callback && typeof callback === 'function') {
  22. callback(resData);
  23. }
  24. // 暴露出文件内容
  25. return resData;
  26. } catch (err) {
  27. console.log('getSystemFileInfoToChain err', err);
  28. // 下载文件至本地
  29. try {
  30. const res = await uni.downloadFile({
  31. url
  32. });
  33. let tempFilePath = res?.[1]?.tempFilePath;
  34. console.log('?? fileManager 222', tempFilePath);
  35. if (!tempFilePath) {
  36. return;
  37. }
  38. // 保存文件至本地
  39. try {
  40. await fileManager.saveFileSync(tempFilePath, filePath);
  41. console.log('?? fileManager 333', url);
  42. // 再次触发,获得需要的数据
  43. getSystemFileInfoToChain(name, url, callback);
  44. } catch (err) {
  45. console.log('saveFileSync err', err);
  46. }
  47. } catch (err) {
  48. console.log('downloadFile err', err);
  49. }
  50. }
  51. }

  

解耦式写法

  1. /**
  2. * 读取静态资源,如果没有该资源,则触发下载,并保存至用户本地
  3. * @param {String} name 文件名 -必传
  4. * @param {String} url 文件路径 -必传
  5. * @param {Boolean} next 是否下一步(如果读取失败,则下载文件至本地) -非必传
  6. */
  7. export async function getSystemFileInfo(name = 'jn', url, next = false) {
  8. const fileManager = uni.getFileSystemManager();
  9. // 用户文件路径
  10. let filePath = `${uni.env.USER_DATA_PATH}/${name}`;
  11. try {
  12. let res = await fileManager.readFileSync(filePath, 'utf-8');
  13. const resData = res && JSON.parse(res);
  14. console.log('?? fileManager 111', resData);
  15. // 暴露出文件内容
  16. return resData;
  17. } catch (err) {
  18. // 允许下一步(下载文件),且有url,进行下载保存
  19. next && url && onDownloadFile(name, url, next);
  20. console.log('readFileSync err', err);
  21. }
  22. // console.log('?? fileManager', fileManager, uni.env.USER_DATA_PATH);
  23. }
  24. /**
  25. * 下载文件至本地
  26. * @param {String} name 文件名 -必传
  27. * @param {String} url 文件路径 -必传
  28. * @param {Boolean} next 是否下一步(文件内容读取) -非必传
  29. */
  30. export async function onDownloadFile(name = 'jn', url, next = false) {
  31. if (!url) {
  32. return;
  33. }
  34. try {
  35. const res = await uni.downloadFile({
  36. url
  37. });
  38. let tempFilePath = res?.[1]?.tempFilePath;
  39. console.log('?? fileManager 222', tempFilePath);
  40. onSaveFile({ name, url }, tempFilePath, next);
  41. } catch (err) {
  42. console.log('downloadFile err', err);
  43. }
  44. }
  45. /**
  46. * 保存文件至本地
  47. * @param {String} params[0].name 文件名 -必传
  48. * @param {String} params[0].url 文件路径 -非必传
  49. * @param {String} tempFilePath 临时文件路径 -必传
  50. * @param {Boolean} next 是否下一步(文件内容读取) -非必传
  51. */
  52. export async function onSaveFile({
  53. name = 'jn',
  54. url
  55. }, tempFilePath, next = false) {
  56. if (!tempFilePath) {
  57. return;
  58. }
  59. const fileManager = uni.getFileSystemManager();
  60. // 用户文件路径
  61. let filePath = `${uni.env.USER_DATA_PATH}/${name}`;
  62. try {
  63. await fileManager.saveFileSync(tempFilePath, filePath);
  64. // 允许下一步(文件内容读取),且有url,进行文件内容读取
  65. next && url && getSystemFileInfo(name, url, false);
  66. console.log('?? fileManager 333', url);
  67. } catch (err) {
  68. console.log('saveFileSync err', err);
  69. }
  70. }

 

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

原文链接:https://www.cnblogs.com/wx3091/p/17925976.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号