15 Commits

Author SHA1 Message Date
崮生(子虚)
cc792d27b0 fix: 更新字体输出格式为 ttf,优化加载性能 2026-08-27 06:06:42 +08:00
崮生(子虚)
8e2c68e6f9 docs: uni-webfont 补 README/LICENSE;依赖改 npm 语义版本(webfont-sdk ^0.2.1) 2026-08-16 15:10:08 +08:00
崮生(子虚)
67b29487be chore: dist-bundle 加入 gitignore 并移除误提交的构建中间产物(真实载体是 uni_modules/gs-webfont) 2026-08-16 15:03:40 +08:00
崮生(子虚)
140f84d3c7 feat: uni-app 插件 gs-webfont —— 字体按需加载(子集化)上线准备
- webfont-sdk 引擎修复两处并发池 bug(原版排队分支丢任务;闭包复用会让
  队列真身丢失导致 pending 卡死),新增 per-state provider 与 submitText 分批
- 新增 packages/uni-webfont:字符累积 + uni.loadFontFace 同 family 重载策略,
  串行保序(maxConcurrent=1),二次 loadFont 从引擎播种累积集
- 产物同步 uni_modules/gs-webfont/js_sdk(自包含 ESM+iife+d.ts)
- 端到端验证:mock 全绿;线上真实服务 4 字 → 10.1KB 合法 TTF
2026-08-16 10:34:40 +08:00
崮生(子虚)
5c85a2ebe7 chore(leafer-x-webfont): 0.2.0 发布 + demo CDN 引用统一 importmap @latest
- npm 0.2.0:脏节点增量扫描 + 贡献者回记 + 百万节点零风暴(见 0ab51e4)
- demo 页三个裸导入统一进 importmap,版本引用 0.1.0/0.2.0 混用 → 全部 @latest
2026-08-15 23:27:42 +08:00
崮生(子虚)
0ab51e496c perf(leafer-x-webfont): 注册回调贡献者回记+静默链应用,百万节点打字场景零风暴
问题(1M Text 节点实测):
- v0 字体注册回调里全树改写 fontFamily:百万次 property.change 污染
  dirty 集,打字场景退化 20s;单点改动 978ms
- 公共 setter 路径(v2):百万次完整属性变更管线 = 2.2s 风暴

方案(v4):
- 贡献者回记:commit 时合并累加每个 family 的贡献节点(不覆盖,
  迟到 chunk 仍能找到贡献者),chunk 回调只把贡献者标脏——链应用
  范围从全树缩小到实际用字节点,打字场景 O(1)
- 静默/公共写分流:溢出(初始全量等贡献者>512)走静默写 __ 数据层
  (~50ns/次,不触发事件不污染 dirty);少量贡献者走公共 setter
  (leafer 自动局部重绘该节点)
- ready() 语义闭环:字体全部落地后同步消化残留 dirtyAll/renderPending,
  否则会被下一个不相关的用户操作捡走——表现为「改一个字卡 800ms」
- forceRender 收敛:仅静默写/浏览器模式标记 renderPending,flush 尾部
  无 in-flight chunk 时合并成一次执行

实测(1M Text,真实 leafer + 本地后端):
- 单点改动 flush: 856ms → 0.15ms
- 随机100节点 flush: 0.9ms
- 新增 Text: 0.08ms
- 打字同步按键成本: 0.2ms/次(与无插件基线 0.012ms 同数量级)
- 拖拽等无文字变化操作: 0 请求 0 提交
2026-08-15 21:13:07 +08:00
崮生(子虚)
ca1d2fc1e7 feat(webfont-sdk): 0.2.0 新增服务端 API 客户端子路径 webfont-sdk/api
- createWebFontApi 工厂封装全部 6 个 REST 接口(fonts/fontMeta/
  config/stats/upload/reportEvent)+ 全套类型,独立子路径导出不进主入口
- leafer demo 删除硬编码 FONTS 数组,改 api.fonts() 实时拉取
  (24 个字体 vs 原硬编码 6 个),初始字体带回退、失败显式报错
- 主站 src/api.ts 重写为 SDK 客户端薄适配层(dogfooding):
  旧类型名保留为别名组件零改动,顺带消灭 FontInfo 重复声明
- /docs 文档页新增 npm 安装、双模式用法、API 客户端示例(中英)
- 主站 package.json 添加 workspace 依赖 webfont-sdk

已发布 npm webfont-sdk@0.2.0,CDN 与 demo 端到端验证通过。
2026-08-15 20:35:17 +08:00
崮生(子虚)
b385bc89bc perf(leafer-x-webfont): 脏节点集增量扫描,百万节点画布可正常运行
全量 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)。
2026-08-15 20:19:27 +08:00
崮生(子虚)
bf98a49a79 perf(leafer-x-webfont): 按 family 内容指纹短路无变化的 loader.update
拖拽/缩放等操作每帧触发布局事件,防抖后仍会全量重扫并逐 family
调用 loader.update。新增 committed 指纹表:本轮收集的字符集与上次
提交一致时跳过 update,无文字变化的交互中 update 调用归零。
存字符串本身而非 hash,比较为 memcmp 级且零碰撞。
2026-08-15 19:13:36 +08:00
崮生(子虚)
64b9ca9a57 chore(deps): 全量升级依赖——vite 8.2.1 / jsdom 30 / puppeteer 25.7 / pinyin-pro 3.29 等;unhead 对齐 2.1.17(vite-ssg 内部依赖 2.x,升 3 会双 head 实例) 2026-08-15 16:53:44 +08:00
崮生(子虚)
c82da2f6ed feat: demo 加源码/npm 链接,构建时复制进主站 dist/leafer-demo/(vite 插件 + sitemap 路由) 2026-08-15 16:22:17 +08:00
崮生(子虚)
bbc5d6f8b1 feat(demo): 全 CDN 化——leafer-ui/export/插件/SDK 全走 jsDelivr,服务地址本地/线上自适应 2026-08-15 16:18:49 +08:00
崮生(子虚)
ec5740c266 chore(packages): 补齐两包 npm 发布元数据(LICENSE/README/types 路径修正/author/repository) 2026-08-15 16:09:30 +08:00
崮生(子虚)
a0c2b4aafc feat: webfont-sdk Node 模式 + leafer 版基准测试(双方案并存)
- webfont-sdk: 新增 Node 模式(node-registry),GlobalFonts 注册 + 每 chunk 唯一 family + 逗号链回退
- leafer-x-webfont: fontFamily 链写回(Node 端),scan 链归一化防套娃、rewriteFamily 跳过链形态防抹回
- 修复 pnpm 双实例 bug: @napi-rs/canvas 版本对齐 1.0.6(根与 SDK 同版本共享 .pnpm 条目)
- 基准测试重构: 用例表抽取为 基准测试用例.ts 共享,SSIM 计算收敛到 scripts/ssim.ts
- 新增 基准测试_leafer.test.ts: @leafer-ui/node + Skia 渲染验证(无浏览器),ttf 输出用例 SSIM=1.0000;woff2 用例仅计时(Skia 不吃 woff2,容器验证由 puppeteer 版守护)
- Node 端集成测试 scripts/test-leafer-node.mts(插件链路 SSIM=1.0000)
2026-08-15 15:51:42 +08:00
崮生(子虚)
0693521716 feat: SDK 抽取为 webfont-sdk npm 包 + leafer-x-webfont 插件(浏览器验证通过)
- packages/webfont-sdk:TS 重写,IncrementalEngine 核心(去重/并发池/失败字符记忆/retryFailed)
  - CSS 模式(WebFont)API 与旧 public/webfont-sdk.js 完全兼容
  - FontFace 模式(WebFontCanvas)供 Canvas 场景,unicodeRange 注册 + onChunk 回调
  - tsdown 双产物:dist/(ESM+dts)+ dist-iife/(script 直引)
  - scripts/sync-public.mjs 构建后同步到 public/webfont-sdk.js
  - 修复 banner 内嵌套块注释导致的语法错误(/* 重绘 */ 提前闭合 banner)
- packages/leafer-x-webfont:LeaferJS 插件,依赖 webfont-sdk
  - 监听 property.change + layout.end 防抖扫描 Text 节点聚合字符
  - 新旧 API 兼容(on_/on__、off_/off__)
  - 注册后自动改写 fontFamily 为合法 CSS 名(去 .ttf 后缀)
  - demo/index.html:海报场景(标题/副标题/字体切换/导出 PNG)本地 vendor 验证通过
- backend/app.ts:fs 适配层改为 top-level await import(修复 dev 模式 mkdir 崩溃)
- doc/:商业化思路一/二评估 + 主动拓客文档
2026-08-15 13:07:32 +08:00