为了让大家更好的理解小程序的一些限制和做一些优化,下面从小程序的基础架构讲起,如有不对的地方,望指正,请轻喷 ?

一. 页面栈限制最多10层

首先,我们看看下图,小程序的架构如下:

我们可以看到,一个页面使用一个 WebView 线程进行渲染。 如果于页面栈有 10 层,则会开启 10 个 WebView 线程,占多一点内存,所以对页面栈进行了限制。

那如果在10层页面栈的限制内,由于页面的内容过于复杂,内存爆了怎么办? 小程序内部有一个回收机制,如果内存紧张时,会回收掉一部分 WebView 。

很多人可能会觉得, 10 层页面栈基本已经够用了,无须关注这方面的限制了。

但是如果出现循环引用的话,用户反复点击,则很容易出现爆栈的情况。 如下图:

所以,在开发之前,提前梳理好页面之间的跳转,合理使用 navigator ,redirectTo, navigateBack …… 是非常重要的。

当然,作为一个程序员,我并不想在跳转的时候去时时刻刻的关注我有没有正确引用,有没有超出10层页面栈。 完全可以对小程序的跳转做一个封装。

因为只有 wx.navigateTo 才会使页面栈 + 1 ,那我们只要对这个方法做一层兜底处理即可。 如下代码:

const PAGE_LIMIT = 10
const pages = getCurrentPages()
if(pages.length >= PAGE_LIMIT) {// 使用 wx.redirectTo 方法
}
复制代码

这样就可以随心所欲的跳来跳去了。

二. JsCore

小程序的逻辑层是在 JsCore 中运行的。限制如下:

  • 没有 Window、Document 对象,也就无法使用 基于 DOM 的一些库. 暂无解决方法。

还是从一张图说起:

不同于页面的渲染,所有的脚本逻辑都是跑在同一个 JsCode 线程里面,类似于路由中改变 Hash 值。 因此也会引起下面一些常见的坑

  1. 需要自己清理页面的 setTimeout 或者 setInterval 定时器
  2. 如果要求页面每次出现都是最新的数据,则要把拉取数据的逻辑放在 onShow 中执行,别放在 onload 中。
  3. 若追求“极致化体验”,在用户切到下一个页面的时候,可以在 onHide 中 abort 掉没有请求成功的接口,把即将处理的 setData 去掉,可以减轻最新页面的逻辑,让最新页面最快渲染展示。

三. 原生组件层级最高

像 canvas , video ,input ,map ,picker …… 组件,官方直接使用原生组件,渲染方式如下图:

从上图很容易就可以看出,Navtive 组件的层级是最高的,那么仅仅去改变 z-index 也无法让其他组件覆盖原生组件。还好,官方给出了一个解决方案:

  • 使用 cover-view cover-image 将希望层级变高的组件也包裹成“原生组件”

四. 独特的网络请求,本地存储

  1. 独特的 Storage 存储

    • 以用户纬度隔离,同一个设备,A 无法访问 B 用户的数据。
    • 持久缓存,只有在用户关掉小程序才会删除,如果空间不足,会进行 LRU ,也就是不经常使用的小程序的数据缓存区域会被全部清空。
    • 在体验版、开发版、和线上版都共用一套,并不会隔离。
    • 没有 Cookie
  2. Request uploadFile downloadFile 并发最多10个请求
  3. 只支持 HTTPS WSS

如果以往在移动端, PC 的接口会使用 Cookie 进行一些处理,那在小程序中使用该接口就比较尴尬了。

因此,我们可以在小程序中也模拟出 Cookie ,如下图:

在 Storage 中隔离一个字段,用来做 Cookie ,下面用了一个小技巧,把 Cookie 的内容存放于内存中,而非每次都从 storage 中读取。

let cookie = (function(){return wx.getStorageSync('cookies');
}())
const Cooke = {getCookie(){}, //从内存中获取cookiesetCookie(){}, // 设置cookiesetCookieInHeader(){}, //根据response的Header设置cookieremoveCookie() {},  //删除cookieisExpired() {} //判断是否过期
}
复制代码

然后,我们在每次 Request 成功后,解析 Header 中 SET-COOKIE 属性设置 Cookie ,在每一次请求的时候,手动在 Header 中设置 Cookie 。这样就完美地模拟浏览器的 Cookie 概念了。

  1. 并发请求处理

设置一个队列,如果请求处理完毕,则移出队列,如果当前数组超过10个请求,则进入等待状态。大概代码如下:

class Request {constructor() {this.maxLimit = 10;this.requestQueue = []; // 请求队列this.requestIng = 0; //当前并发数}request () {// 判断是否超出并发数if(this.requestIng >= this.maxLimit) {// 推入请求队列}else {this.requestIng ++;// 执行成功后 - 1 ,从 requestQueue 中取出重新请求}}
}
复制代码

五. setData

好吧,还是从一张图说起,显然,我们可以看出,每一次 setData 都是一次线程通信。

线程通信成本很高,非常耗时间,因此官方明确的给出了建议:

  1. 将多次 setData 合并成一次进行调用
  2. 只 setData 对象改变的某个值
data: {array: {changeData: '我改变了',noChangeData: '我没有改变'},
},
this.setData({'array.changeData':'changed data'
})
复制代码
  1. 与界面渲染无关的字段不要放在 data 中
data: {view: '与界面相关的数据'
},
noRelaView: '与界面无关'
复制代码

@Author:beidan

你可能不知道的小程序相关推荐

  1. C语言你不得不知道的小知识

    C语言你不得不知道的小知识: 1: 常见的变量修饰关键字:static.const.extern.volatile.register static:(该变量保存在全局静态区)  a.修饰局部变量--& ...

  2. 英雄联盟怎么解除小窗口_英雄联盟:老玩家都不知道的小技巧,一定要注意这些细节|英雄联盟|召唤师|防御塔|新英雄|亚索...

    英雄联盟:老玩家都不知道的小技巧,一定要注意这些细节 英雄联盟作为当下最火爆的游戏之一,已经陪伴大家走过了无数的春夏秋冬,如今英雄联盟已经迎来了越来越多的新英雄,随着英雄联盟里面的英雄不断的增多,越来 ...

  3. 一些你我所不知道的小知识

    一.老师没教的事 a.人类全身上下,最强韧有力的肌肉,竟是舌头. b.张开眼睛打喷嚏是不可能的. c.憋气自杀也是不可能成功的. d.每一次你舔一张邮票的背胶,你就吸收了十分之一卡路里. e.右撇子平 ...

  4. 不得不知的小程序基本知识

    1.小程序的基本架构: 每个小程序的结构都是由两个主要部分构成:主体部分 + 各个页面.   1)主体部分主要由3个文件构成 app.js:小程序逻辑,初始化APP: app.json :小程序配置, ...

  5. 有哪些老鸟程序员知道而新手不知道的小技巧?自我感受

    最近在朋友圈看到别人分享的一篇知乎回答:https://www.zhihu.com/question/36426051/answer/76031743 我觉得写得挺有道理的,作为一个写了10多年C#代 ...

  6. 师妹问我:有哪些新手程序员不知道的小技巧?

    阅读本文大概需要5分钟. 一个师妹问:洋哥,我今年应届毕业,刚开始写代码,不知道有没有一些新手需要注意的地方. 给了师妹一些建议之后,感觉这是个好问题!不光是新手程序员,很多小技巧小秘密恐怕老手也未必 ...

  7. 有哪些老鸟程序员知道而新手不知道的小技巧?

    1.重构是程序员的主力技能. 2.工作日志能提升脑容量. 3.先用profiler调查,才有脸谈优化. 4.注释贵精不贵多.杜绝大姨妈般的"例注".漫山遍野的碎碎念注释,实际就是背 ...

  8. 有哪些新手程序员不知道的小技巧?

    提到新手程序员,大家想到的第一个词可能就是:刷题.尤其是通过LeetCode刷题,想必新手程序员们都经历过这一步,甚至不少人认为只要在LeetCode上刷的题目够多,就一定能够进阶为大神. 但是,不难 ...

  9. 程序员常用编程工具: VS Code,那些你不得不知道的小知识!

    工欲善其事,必先利其器.这句话真好,一句话可以写两篇文章.上一篇我们介绍了键盘,对于程序员来说,光有键盘可不行,你还需要一个趁手的编程工具.就像很多工程师对 HHKB 键盘情有独钟一样,好的编程工具可 ...

最新文章

  1. 暑期集训1:C++STL 练习题B:HDU-1004
  2. 如何比较PixelCNN与DCGAN两种Image generation方法?
  3. 创新实训个人记录 : 个人工作总结
  4. mainwindow.obj:-1: error: LNK2019: 无法解析的外部符号 public: __cdecl about::about(class QWidget *) (??0abo
  5. VTK:IO之DEMReader
  6. python中match方法返回字符串的长度_Python re模块与正则表达式详解
  7. Github标星27.1k,可大批量生成假数据,这个工具忒牛
  8. php mysql not in_php – MySQL – NOT IN产生不需要的结果
  9. span 超出部分换行
  10. mac 程序员装机必备 一篇齐全
  11. jdbc下载mysql的驱动 mysql5版本
  12. 巨详细一文教你如何撰写商业计划书
  13. 俄罗斯方块(C/C++)
  14. 【初探篇】Nginx 虚拟主机与域名解析
  15. android WebView去广告 使用javascript脚本去除webView广告(两种思路)
  16. STorM32 BGC 相关
  17. Spring Security教程
  18. 2022-10-15(Linux应急响应、配置漏洞之DNS域传送、内网渗透之内网主机发现技巧)
  19. ArcGIS Earth 1.11版本发布啦!
  20. 困死了。。。。。。。。。。。。。。。。

热门文章

  1. 抗击疫情,AI一直在行动
  2. SAP WM 确认TO单的时候不能修改目的地STORAGE BIN
  3. 图灵奖得主Yann LeCun万字访谈:DNN“史前文明”、炼金术及新的寒冬
  4. 「SAP技术」SAP MM MB5M报表不显示特殊库存数据
  5. 了解GAN背后的设计,训练,损失函数和算法
  6. 自然语言(NLP)发展史及相关体系
  7. 人工智能应该如何监管——智库研究员乔舒亚·纽提出算法责任原则
  8. 【盘点】北美顶尖学府的人工智能与智能车实验室
  9. SAP MM MIGO Cancellation可以用于冲销上次冲销而产生的物料凭证
  10. SAP MM ME81N PO Value Analysis报表中Net Value 为负数是怎么回事?