三个月,从无到有,“肆意”生长出一个基于原生nwjs的庞然大物(小程序),希望能大概描述一下当前小程序的“轮廓”,去糟粕取精华。
运行单元:page + component
每一个目录下由三剑客组成scss、wxml、js;
- scss:开发过程直接编译压缩至css
- wxml:每一个wxml会被一个顶层容器组件包裹,用于实现自定义头部等每一个页面都有公共功能
- js:page对象默认继承一个公共base-config,用于实现全局页面的配置
- app.js: 除处理生命周期外,可以方便挂载公共方法或对象,方法在此的好处是子包和主包不用编译两份文件,组件及页面可以共享实例,甚至是一个单例的非常好的载体; 目前项目中很多主流方法都放在里边,例如网络请求、打点、监控以及一些特殊的全局数据
数据状态管理
关于数据的管理,现在相对比较混乱,没有一个确定的规范,列一下目前在用的几种手段;
- 全局共享一份数据
实例放进全局app实例中,通过方法进行获取,可以解决拿取数据重复请求的问题
- 页面数据
页面尽可能拆分组件,便于状态管理,简化页面结构
- 针对组件之间基本联动较少的情况,数据状态尽可能下沉到组件内部,在各个子组件内实现状态管理,每一个组件等于一个model
- 组件间联动较多,针对页面拆分为多个子pageConfig.js,每一个pageConfig.js对应一个业务类型或者一种功能事件,对于组件则可以拆分为多个behavior实现
- 层级跨度较深的联动,通过eventbus解决,尽量不用或者少用
- westore,嗯...从入门到放弃,以上三种基本能够满足现在的需求
组件共享
目前项目中的组件主要分为:
- 纯ui组件(dxy-image、item)
- 布局组件 (card、layout)
- 业务组件(输入id => view)
- 页面级组件(约等于page)
项目中在主包以及子包中落地对应demo页,展示组件,业务在快速迭代中,落地的demo明显滞后
开发发布流程
- 脚手架: 用于生成page和component模板,减少自己配置错误等带来的时间成本
- npn run changeAppId:提供切换appId方法:线上线下账号快速切换,减少人肉改动
- npm run dev:pretask + scss监控
- npm run dev-mock,本地启动server完成mock,相关文件不进行打包,目前mock仅在dev阶段使用
- commit:提供必要的校验,eslint stylelint 自定义校验,例如禁止空文件、禁止assets存在大资源、检测存在未解决冲突的文件等,减少协作过程带来的异常问题
- 发布:组内其他同学开发了基于cli发布的脚本命令,由于目前没有实现服务端发布,目前在自己的项目中还没有很好的利用
- 测试:缺!(单元 + 自动化 测试?)
项目配置及主要三方包
当前项目主包约1.2M
- 引入rungenrator或开启增强编译,启用await async
- pretask:项目独立追踪一个project.config.json以外的配置文件,用于全局项目配置,在项目启动开发pretask的时候复制到project.config.json,保证组员本地开发环境同步并无感知,目前主要用来配置packOption.ignore
- cookie管理,weapp-cookie,当前存在storageSync失败的问题,考虑加入失败重试,治标不治本
- 富文本解析,基于wxParse修改
- computed,通过代理setData实现
- ...
性能优化
- 非可视区域,延迟加载,例如swiperview的使用。
- 防止内存泄漏,页面退出要及时清理,例如setInterval等
- 多用img lazy-load,对于大图片,backgound-image不是一个好选择,图片合理压缩,对内存帮助很大,根据视窗大小控制压缩比,webp在当前除兼容性较差外,在小米等机型表现也很一般。
- 多余数据禁止setData(如audio实例),页面退出及时销毁实例;避免使用多余的coputed属性,多用wxs ;善用延时,非及时数据延迟初始化或懒加载,控制加载时序,必须高内存高运算的持续工作。
- 页面隐藏(非销毁状态),停止响应setData,避免不必要的消耗。
- asset禁止放置大的图片文件,选择iconfont,不可用iconfont尽量走cdn
- 尽量避免sync-api 例如storageSync-api,此类api响应不稳定,并会阻塞全局进程,当前引入的weapp-cookie.js库就是利用的同步api
- 配置项目禁止打包非生产环境相关文件,json、js结尾的都会被统一打包,通过配置排除
- 打包工具不会对wxss进行压缩,配置压缩wxss减小包体积
- 列表尽量采用scroll-view,利用视图recycle提高性能
- 从深层次页面回到首页,可以考虑relaunch
- ...
未解决问题
- 报错日志,例如:
a. setStorageSync:fail;at App onError function;at api request success callback function 同步方法失败,主要存在cookie设置中;
b. SyntaxError: Attempted to redefine property '13'.
c. Error: module "weapp-cookie.js" is not defined
- 内存过大、黑屏/闪屏问题在部分机型仍存在(尤其小米8)
- ...