支付宝小程序框架的简介、目录结构、性能优化建议

286 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

文件结构

小程序分为app和page两层。app用来描述整个应用。page用来描述各个页面,此外还有关乎整个project的配置描述(可选)
app由三个文件组成,必须放在项目的根目录。

image.png

image.png image.png

page 由四个文件组成,分别是

image.png

image.png
注意: 为了方便开发者,支付宝小程序规定这四个文件必须具有相同的路径与文件名。
project 特指 mini.project.json 文件,必须放在项目的根目录

逻辑结构

小程序的核心是一个响应式的数据绑定系统,分为视图层和逻辑层。这两层始终保持同步,只要在逻辑层修改数据,视图层就会相应的更新

image.png
注意: 由于框架并非运行在浏览器中,所以 JavaScript 在 web 中的一些能力都无法使用,如 documentwindow 等对象。
逻辑层 js 可以用 ES2015 模块化语法组织代码

image.png

第三方 NPM 模块(微信不可以)

小程序支持引入第三方模块,需先在小程序根目录下执行如下命令安装该模块

image.png
引入后即可在逻辑层中直接使用:

image.png
注意: 由于 node_modules 里第三方模块代码不会经过转换器,为了确保各个终端兼容,node_modules 下的代码需要转成 ES5 格式再引用,模块格式推荐使用 ES2015 的 import/export。同时,浏览器相关 web 能力同样无法使用(因为有些可能会涉及到DOM对象等)

目录结构示例(简单的):

image.png
注意小程序包体积限制在2MB以内(如果超过的话开发没影响,但是无法上传和真机)

性能优化建议

控制首屏一次性渲染节点数量

业务请求返回后,通常会调用 setData 触发页面重新渲染。执行过程如下:

  1. 数据从 worker 传递到 webview
  2. webview 上根据传过来的数据构造虚拟 DOM,并与之前做差异比较(从根节点开始),然后渲染。

    由于 worker 与 webview 通信时,数据需要序列化,然后到了 webview 需要执行 evaluateJavascript,因此如果一次性传输数据太大,会影响首屏渲染性能。
    另外,如果 webview 上构造节点过多,层级嵌套太深,例如有的小程序列表页面一次性渲染超过 100 个列表项,每个列表项又有嵌套内容,而实际上整个屏幕可能只是显示不到 10 个, 会导致差异比较时间较长,同时由于是首屏渲染,会一次性构造很多 DOM,影响首屏渲染性能。
    优化建议
  • setData 数据量不宜过大,避免一次性传递过长的列表。
  • 首屏请勿一次性构造太多节点,服务端可能一次请求传递大量数据,请勿一次性 setData,可先 setData 一部分数据,然后等待一段时间(比如 400ms,具体需要业务调节)再调用 $spliceData 将其他数据传输过去。(假设手机首屏能显示20条数据,那么剩下的数据可以等待一定的时候在进行请求,控制data的数据展示的时间,以免一下子请求太多。)

优化setData逻辑

任何页面变化都会触发setData,同一时间可能会有多个setData触发页面进行重新渲染,如下四个接口都会触发webview页面重新渲染。

  • Page.prototype.setData: 触发整个页面做差异比较

  • Page.prototype.$spliceData: 针对长列表做优化,避免每次传递整个列表,触发整个页面做差异比较

  • Component.prototype.setData: 只会从对应组件节点开始做差异比较

  • Component.prototype.$spliceData: 针对长列表做优化,避免每次传递整个列表,只会从对应组件节点开始做差异比较 优化建议

  • 避免频繁触发 setData 或者 $spliceData,不管是页面级别还是组件级别。在我们分析的案例中,有些页面有倒计时逻辑,但是有的倒计时过于频繁触发(ms毫秒级别的触发)。

  • 需要频繁触发重新渲染时,避免使用页面级别的 setData 和 spliceData,将这一块封装成自定义组件,然后使用组件级别的setDataspliceData, 将这一块`封装成自定义组件`,然后使用组件级别的 setData 或 spliceData 触发组件重新渲染。(只渲染对应的组件)

  • 长列表数据触发渲染时,使用 $spliceData 多次追加数据,而不用传递整个列表。

  • 复杂页面建议封装成自定义组件,减少页面级别的 setData

优化代码案例

推荐指定路径设置数据:

image.png
不推荐如下用法:

image.png

使用key参数

在for中使用key来提高性能,注意key不能设置在block上

image.png