架构与运行机制 ✅
面向微信/支付宝/抖音等小程序平台的通用架构认知,围绕运行时、渲染通信、数据更新与限制展开。
小程序整体架构与运行原理?
答案
核心概念:
小程序采用“逻辑层(JS) + 渲染层(WebView/Native)”双线程模型,宿主提供通信通道完成数据下发与事件上报;UI 以 DSL(WXML/WXSS 等) 声明,逻辑层不可直接操作 DOM。
示例说明:
面试官视角:
- 要点清单: 双线程/不可直控 DOM/单向数据下发/事件上行
- 加分项: 了解原生组件/同层渲染与端差异
- 常见失误: 当成标准 H5 使用,忽视通信成本
延伸阅读:
为什么小程序有逻辑层与渲染层两线程?
答案
核心概念:
分离渲染与逻辑避免 JS 计算阻塞 UI,提升稳定性与一致性;事件上报与数据下发通过异步队列传递。
示例说明:
// 伪代码:批量合并 setData 降低过桥频次
let q = [], scheduled = false
function batchSetData(diff){
q.push(diff)
if (!scheduled){
scheduled = true
setTimeout(() => {
const merged = Object.assign({}, ...q)
q = []; scheduled = false
// @ts-ignore
this.setData(merged)
}, 16)
}
}
面试官视角:
- 要点清单: 并行/隔离的收益;异步通信的代价
- 加分项: 批处理策略;框架层 Hook
- 常见失误: 高频小粒度 setData;重计算挡在主线程
延伸阅读:
为什么不能直接操作 DOM?
答案
核心概念:
渲染层由宿主容器掌控,逻辑层运行在独立运行时(JSCore/V8);DOM API 不可用,使用选择器/节点查询与组件能力完成交互。
示例说明:
<view id="box" />
const q = wx.createSelectorQuery()
q.select('#box').boundingClientRect(rect => console.log(rect)).exec()
面试官视角:
- 要点清单: 安全模型/一致性;替代方案
- 加分项: 组件化封装交互能力
- 常见失误: 直接调用 document.*
延伸阅读:
setData 工作机制与性能陷阱?
答案
核心概念:
setData 将数据 diff 序列化过桥,下发给渲染层生成补丁;大对象/深层结构/高频调用会放大通信与序列化开销。
示例说明:
// 推荐:最小 diff + 去抖
this.setData({ [`list[${i}].checked`]: true })
// 避免:整树替换
// this.setData({ list })
面试官视角:
- 要点清单: 最小化 diff;合并/节流;扁平化
- 加分项: 长列表窗口化;Worker/任务切片
- 常见失误: 高频大 payload;跨层级全量更新
延伸阅读:
页面/组件生命周期与事件模型?
答案
核心概念:
页面 onLoad/onShow/onHide/onUnload;组件 lifetimes/pageLifetimes;冒泡/捕获与自定义事件。
示例说明:
Page({ onLoad(){}, onShow(){}, onHide(){}, onUnload(){} })
Component({ lifetimes:{ attached(){}, detached(){} } })
面试官视角:
- 要点清单: 资源管理与清理;事件传递
- 加分项: 防抖/去重进入;路由栈管理
- 常见失误: 忽视卸载清理;重复注册监听
延伸阅读:
JS 运行时(JSCore/V8/X5) 有何差异与限制?
答案
核心概念:
不同端运行时差异导致部分 Web API 缺失;避免 eval/new Function,使用宿主 API 与 polyfill。
示例说明:
wx.getSystemInfo({ success: console.log })
面试官视角:
- 要点清单: 运行时能力边界;兼容策略
- 加分项: 适配/抽象层
- 常见失误: 直接依赖浏览器特性
延伸阅读:
- 各端能力说明文档(微信/支付宝/抖音)
页面/组件/全局的数据通信?
答案
核心概念:
组件 props/triggerEvent,页面间事件总线/全局 App,状态库(mobx-miniprogram 等);临时本地存储共享。
示例说明:
// 组件向外触发
this.triggerEvent('change', { value })
面试官视角:
- 要点清单: 单向数据流;低耦合
- 加分项: 规模化状态管理
- 常见失误: 跨页频繁 setData;全局变量滥用
延伸阅读:
原生组件/同层渲染的作用与限制?
答案
核心概念:
camera/map/video 等同层渲染可获更好性能,但存在层级/zIndex/滚动遮挡等限制。
示例说明:
<map style="width:100%;height:300px" enable-3D="true" />
面试官视角:
- 要点清单: 层级限制;手势冲突
- 加分项: 蒙层穿透/交互协调
- 常见失误: 与 scroll-view 叠加遮挡
延伸阅读:
Worker/分线程如何使用?
答案
核心概念:
使用 Worker 处理重计算,避免阻塞逻辑主线程;postMessage 通信注意数据复制与释放。
示例说明:
const worker = wx.createWorker('workers/calc.js')
worker.postMessage({ type: 'sum', payload: bigArray })
worker.onMessage(({ result }) => this.setData({ result }))
面试官视角:
- 要点清单: 任务切片;数据量控制
- 加分项: 二进制传输与释放;内存压测
- 常见失误: 主线程仍做大循环
延伸阅读:
WXS 在哪些场景合适?
答案
核心概念:
WXS 在渲染层运行,适合格式化/轻逻辑以减少 setData;避免放业务复杂逻辑。
示例说明:
<wxs module="f">module.exports.format=n=>n.toFixed(2)</wxs>
<text>{{ f.format(price) }}</text>
面试官视角:
- 要点清单: 在地渲染/减少过桥
- 加分项: 可维护性权衡
- 常见失误: 复杂业务放入 WXS
延伸阅读: