mirror of
https://github.com/2234839/web-font.git
synced 2026-09-04 23:02:27 +08:00
全量 walk O(全树) 改为事件驱动增量: - property.change 携带 target(PropertyEvent 五参构造)→ 精确记脏节点 - child.add/remove 携带 child → 整棵子树入脏集(构造期赋值不走 setAttr) - 订阅集与 Leafer 自家 Watcher 相同(property.change + child.*), 渲染可靠 = 事件可靠;不再订阅 layout.end(每帧触发,百万级下 周期性全量 walk 是持续卡顿源) - 脏节点 >512 退化全量(模板整体替换场景全量更省) - 全量/增量共用 collect/walkInto/commit,指纹短路保证无变化时 update 调用归零 - 新增 provider 透传(测试/私有部署)、flushNow(跳过防抖立即提交)、 updateCalls 计数(量化指纹短路效果) 压力测试(_prof_million.entry.ts,1M Text 节点): - 初始全量 scan: ~580ms(一次性) - 打字稳态(emit+flush): 0.024ms/键 - 无文字变化 flush ×100: 0.16ms,update=0 - 内存: 指纹表 O(family 数),与节点数无关 真实 leafer 验证(scripts/test-leafer-incremental.mts): 初始添加/改文字/新增子树全自动捕获,拖拽 50 次 0 请求 0 提交。 附带修复 dev 后端启动:llrt_lr.ts 改动态 import + fsReady (createRequire 与 tsx ESM loader 模块图隔离导致 implInterface 注册到孤儿实例,mkdir undefined)。
36 lines
1.5 KiB
TypeScript
36 lines
1.5 KiB
TypeScript
/**
|
||
* fs 适配层分发器。
|
||
*
|
||
* 按编译期 __RUNTIME__ 常量选择实现 —— tsdown define 常量折叠后未命中分支被消除:
|
||
* - LLRT 构建(__RUNTIME__="llrt"):require("./llrt"),内联进 bundle
|
||
* - Node 构建(__RUNTIME__="node"):require("./node"),内联进 bundle
|
||
* - dev(tsx ESM 直跑源码,__RUNTIME__ 未定义):动态 import("./node")
|
||
*
|
||
* 适配器在模块顶层调用 implInterface 完成注册。
|
||
*
|
||
* 注意:
|
||
* - 构建分支必须保持**裸 require("./xxx")** 字面量——打包器靠静态分析内联适配器,
|
||
* 变量间接调用(createRequire 等)无法被分析;且 native require 与 tsx ESM loader
|
||
* 模块缓存隔离(双实例),implInterface 会注册到另一个实例上,运行时必错。
|
||
* - 不能用 top-level await import —— tsdown 的 CJS 产物不支持。
|
||
* - dev 无全局 require:走动态 import(经 tsx ESM loader,与 app 同模块图),
|
||
* 返回 fsReady 由 app.ts 的 main() 开头 await,保证注册先于任何 fs 调用。
|
||
*/
|
||
|
||
/** 编译期常量:tsdown define 注入,dev 下未定义 */
|
||
declare const __RUNTIME__: string | undefined;
|
||
|
||
let fsReady: Promise<void>;
|
||
|
||
if (typeof __RUNTIME__ !== "undefined" && __RUNTIME__ === "llrt") {
|
||
require("./llrt");
|
||
fsReady = Promise.resolve();
|
||
} else if (typeof __RUNTIME__ !== "undefined") {
|
||
require("./node");
|
||
fsReady = Promise.resolve();
|
||
} else {
|
||
fsReady = import("./node").then(() => undefined);
|
||
}
|
||
|
||
export { fsReady };
|