问题

  今天组长跟我们讨论了个问题,说是文章存储占用有点大,消耗宽带流量费,让我看看能不能找个方法解决一下(文章存储的是html字符串)。第一反应是没什么头绪,能想到的就是将相同的字符串替换成一个标识之类的,小程序再通过标识替换回原本的字符(感觉就不是很靠谱...)。

  后来发现真的不靠谱,首先每篇文章样式可能都不一样,需要很多对应的字典,即使是这样大概预估了下,也减少不过10多k左右。唉,还是面向百度编程吧,看看有没有什么别人写好的模块可以用一下。

  然后就找到了pako.js,具体实现是本地gzip压缩成base64。我在pc端稍微测试了下,原本150k左右的文章,能够压缩到14k,压缩率90%。嗯,不错,开始搞一下。可后面的路并没有我想的那么顺畅...

准备工作

  要是用第三方模块,肯定需要npm包管理工具是吧。npm init,然后npm i pako,一顿操作,引入文件测试。哦豁,报错找不到这个包。因为在公司一直都是用的原生小程序语法开发,没使用过三方模块,所以这方面一直没去了解,还以为和web端的差不多。没事嘛,面向百度编程。百度了一堆乱七八糟的,都没什么作用,还是乖乖的看官方文档吧,没想到几分钟的事就解决了(有时候还是文档靠谱)。

  1. npm init  创建package.json
  2. npm i pako
  3. 开发者工具左上角 -> 工具 -> 构建npm
  4. 开发者工具右上角 -> 勾选使用npm模块
  5. 文件中引入模块使用

  附上文档链接:https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html

开始踩坑

  数据库存储的文章已经压缩过,现在要做的就是在小程序解压缩还原成html字符串并渲染出来。

  压缩文章代码:

  1. function zip(str){
  2. let binaryString = pako.gzip(encodeURIComponent(str), { to: 'string' }),
  3. res = btoa(binaryString);
  4. return res
  5. }

  封装一个解压缩的函数(里面用到的方法都是pako写好的,直接调用),代码:

  1. var pako = require('pako');
  2.  
  3. page({
  4. ...
  5. unzip(b64Data){
  6. let strData = atob(b64Data),
  7. charData = strData.split('').map(function(x){return x.charCodeAt(0);}),
  8. binData = new Uint8Array(charData),
  9. data = pako.inflate(binData);
  10. strData = String.fromCharCode.apply(null, new Uint16Array(data));
  11. return decodeURIComponent(strData)
  12. }
  13. })

  然后将接口拿到的文章传入到 unzip 中就可以解压出来了。当然这只是我预期的结果(因为web端这样的操作确实可行)

  真机调试后小程序报错,找不到atob

  

  原因是pako方法中使用到window.atob,而小程序不支持这个方法,所以导致报错。

  解决方法:引入atob的polyfill,就是在小程序实现一个atob方法

  atob polyfill 下载地址:https://github.com/davidchambers/Base64.js ( 该polyfill实现了atob和btoa)

  1. const polyfill = require('../../utils/base64')
  2. const {atob btoa} = polyfill;

  引入atob后,再跑一遍真机测试,诶,舒服了,完美的展示出来,而且响应速度和原本的没有什么差别

  然后我以为完成任务了,在测试一篇稍微大点的文章时(260k左右),小程序再次报错

  

  而且居然是调用栈内存溢出。wtf?!初步我还以为自己逻辑写错,导致出现递归死循环之类的。检查几遍后,并没有发现错误。只能再次求助百度...

  得到的原因是因为数据量过大,导致在进行 String.fromCharCode.apply(null, new Uint16Array(data)) 时,出现栈内存溢出的问题,用以下的函数代替这步即可:

  1. function handleCodePoints(array) {
  2. var CHUNK_SIZE = 0x8000; // arbitrary number here, not too small, not too big
  3. var index = 0;
  4. var length = array.length;
  5. var result = '';
  6. var slice;
  7. var arr = [];
  8. for (var i = 0, _i = array.length; i < _i; i++) {
  9. arr[i] = array[i];
  10. }
  11. while (index < length) {
  12. slice = arr.slice(index, Math.min(index + CHUNK_SIZE, length)); // `Math.min` is not really necessary here I think
  13. result += String.fromCharCode.apply(null, slice);
  14. index += CHUNK_SIZE;
  15. }
  16. return result;
  17. }

写在最后

  后面测试过程中并未出现其他问题,测试了更大的数据量后也没什么问题。至此,我在小程序使用pako.js之路告一段落。之后如果还有存在问题,我会继续更新这篇文章。若你在使用过程中发现其他问题,请告诉我。

微信小程序使用pako.js的踩坑笔记的更多相关文章

  1. 微信小程序使用weui扩展组件踩坑

    最近在做微信小程序,引入weui的时候踩坑了好久,这里记录一下遇到的问题. 微信官方文档给了两种weui引入方式: 通过 useExtendedLib 扩展库 的方式引入,这种方式引入的组件将不会计入 ...

  2. 微信小程序 请求签名接口超时 踩坑路。。

    我们公司一般做开发都是先用测试机的接口调试功能,等功能都调试的差不多了,再换成线上的正式接口,因为正式接口要验证签名. 这几个功能都调试的差不多了,准备换成线上正式接口了,结果却出了问题,提示请求超时 ...

  3. 从微信小程序到鸿蒙js开发【12】——storage缓存&自动登录

    鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 正文: 在应用开发时,我们常需要将一些数据缓存到本地,以提升用户体验.比如在一个电商的app中,如果希望用户登录成功后,下次打 ...

  4. 微信小程序引入md5.js

    今天给大家安利一下微信小程序引入md5.js的方法,不多说 md5.js在下面 直接复制到项目的utils/md5.js即可 /* * A JavaScript implementation of t ...

  5. 从微信小程序到鸿蒙js开发【11】——页面路由

    目录: 1.router.push()&wx.navigateTo() 2.router.replace()&wx.redirectTo() 3.router.back()&w ...

  6. 从微信小程序到鸿蒙js开发【13】——list加载更多&回到顶部

    鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 目录: 1.list加载更多 2.list回到顶部 3.<从微信小程序到鸿蒙js开发>系列文章合集 1.list加 ...

  7. 从微信小程序到鸿蒙js开发【15】——JS调用Java

    鸿蒙入门指南,小白速来!0基础学习路线分享,高效学习方法,重点答疑解惑--->[课程入口] 目录:1.新建一个Service Ability2.完善代码逻辑3.JS端远程调用4.<从微信小 ...

  8. 微信小程序结合原生JS实现电商模板(二)

    接 <微信小程序结合原生JS实现电商模板(一)>,在首页列表加入购物车到购物和模块增删数量,动态计算商品价格实现后,本次提交主要实现了商品详情(还不完善)简单页面,从商品详情页跳转到购物车 ...

  9. 微信小程序中scroll-view的几个坑

    微信小程序中scroll-view的几个坑 1:设置scroll-x时,却不能横向滚动,因为view是block组件,但是这里用了flex就不能滚动了(想用flex布局,请开启属性enable-fle ...

随机推荐

  1. 【Swift】UNNotificationServiceExtension

    一.简介 An object that modifies the content of a remote notification before it's delivered to the user. ...

  2. Android Debug 之 Log 最佳实践

    本文微信公众号「AndroidTraveler」首发. 背景 在开发过程中,调试是必不可少的一项工作. 当我们要确定项目的逻辑时,当我们要了解界面的生命周期时,当我们发现新写的逻辑与期望效果不一致时, ...

  3. Zabbix安装部署实践

    操作系统: [root@mysql ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) Mysql :     版本5.7 ...

  4. Vue_声明周期

    Vue生命周期 在vue2.0的时候,声明钩子发生了改变,具体有八个 <!-- HTML部分 --> <div id="app"> <div>{ ...

  5. Java中的工具类究竟如何命名?

    先来几个例子 JDK自带工具类 Arrays.asList(); Objects.equals(); Collections.sort(); Spring框架工具类 StringUtils.isEmp ...

  6. Vue学习笔记:Vuex

    为什么需要Vuex 管理共享状态 解决一份数据在多个组件中试用的困难 系统化的状态管理,区别于小型状态过来 底层设计模式: 全局单例模式 应用场景 适合中大型项目: 小项目反而会因为引入更多概念和框架 ...

  7. VSCode, Django, and Anaconda开发环境集成配置[Windows]

    之前一直是在Ubuntu下进行Python和Django开发,最近换了电脑,把在Virtual Box 下跑的Ubuntu开发机挪过来总是频繁崩溃,索性就尝试把开发环境挪到Windows主力机了. 不 ...

  8. Laravel 菜鸟的晋级之路

    第一阶段:简单的增删改查 这是最开始接触Laravel的一个阶段.如果有PHP经验,那么应该能很快找到MVC的路径,然后驾轻就熟的开始写起来.虽然还显得有些笨拙,不过很快就能做出一些内容了.如果没有P ...

  9. 作业要求20191107-6 beta week 2/2 Scrum立会报告+燃尽图 05

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/9958 一.小组情况 队名:扛把子 组长:孙晓宇 组员:宋晓丽 梁梦瑶 韩 ...

  10. 2 JAVA语言的基本规则

    1. 类名 类名需使用字母开头,使用驼峰命名法,如HelloWorld,对应的文件为 HelloWorld.java,与类名保持一致.编译好的字节码文件为 HelloWord.class. 2. 区分 ...