摘要(Auto)

  • 生成时间:2025-12-21
  • 关注点:Schema 驱动渲染链路、编辑器一致性、运行时性能治理、SSR/Hydration、导出一致性与权限隔离、稳定性与降级

建议追问(Auto)

  • 为什么选 SSR/CSR/流式 SSR?反例是什么?
  • 导出怎么保证一致性与权限?失败怎么兜底?
  • 低代码如何做物料版本治理与 schema 迁移?

关联卡片

在我项目中的角色与使用场景

  • 低代码(大屏/报表)里通常会同时遇到三类“选型问题”:
    • 渲染器:自研 vs 开源二次开发;编辑态/运行态一致性如何保证?
    • 渲染模式:SSR vs CSR vs 流式 SSR,首屏/SEO/鉴权/稳定性如何权衡?
    • 导出:客户端截图 vs 服务端渲染/离线渲染;一致性、权限隔离与失败兜底怎么做?

原理简述

把问题拆成三段更容易讲清楚:

  • Schema 驱动低代码(核心)
    • schema 是可序列化的“UI + 数据 + 事件”描述;runtime 把 schema → runtime tree → 组件树。
    • 关键:nodeId 索引 + 局部更新,避免“schema 一动全树重渲染”。
    • 编辑器:拖拽/撤销重做/编组,本质是对 schema 的增量变更(command/patch)。
  • SSR/CSR(核心)
    • CSR:逻辑简单、生态成熟,但首屏完全依赖 JS 下载与执行;弱网/低端机更容易慢。
    • SSR:服务端先把 HTML 渲染出来(可带鉴权),客户端 hydration 接管;要处理一致性(时间/随机数/环境差异)。
    • 流式 SSR:边渲染边输出,TTFB 更早;但错误处理/中断/缓存隔离更复杂。
  • 导出(核心)
    • 最重要的是“一致性 + 权限”:导出任务要带用户身份/权限快照,服务端按权限过滤数据,且与线上展示口径一致。
    • 失败兜底:异步任务、重试、降级到截图或导出占位(按业务约束选择)。

对比表格

1)低代码渲染器:自研 vs 开源二次开发

维度自研渲染器开源框架二次开发
定制能力(贴合业务 DSL)中-强(受框架边界影响)
交付速度
治理成本(长期维护)中(跟随社区升级)
风险与回滚可控(版本锁定)但需要自建迁移体系受上游版本影响,需要隔离升级风险

2)渲染模式:CSR vs SSR vs 流式 SSR

维度CSRSSR流式 SSR
首屏中-差(依赖 JS)(HTML 直出)更好(边渲染边输出)
SEO
实现复杂度中-高(hydration/同构数据)高(错误/中断/缓存)
稳定性与降级简单(直接回退)需要 SSR→CSR 降级策略更需要(流中断/异常)

3)导出:截图 vs 服务端渲染 vs 离线渲染任务

维度客户端截图服务端渲染导出离线渲染任务(队列)
一致性中(受浏览器影响)(同口径渲染)(可控环境)
性能/稳定性受客户端影响中(服务端压力)(异步、可重试)
权限隔离易遗漏可严控可严控
适用场景轻量兜底中等规模、实时导出大规模/耗时导出

模拟问答

  • [ ] Q1:为什么低代码一定要做“物料版本治理 + schema 迁移”?不做会怎样?

    • 不做的后果:物料升级后线上配置失效、渲染报错、回滚困难。
    • 口径:配置锁定物料版本;破坏性变更用 migration 脚本升级 schema;支持一键回滚旧物料版本。
  • [ ] Q2:SSR 的 hydration mismatch 常见原因是什么?你怎么避免?

    • 常见原因:时间/随机数、依赖浏览器 API、服务端与客户端数据不一致、条件渲染分支不同。
    • 避免:同构数据注水/脱水(dehydrate)、避免在 render 中引入不确定性、把浏览器专属逻辑放到 effect。
  • [ ] Q3:流式 SSR 的收益点是什么?最大的坑是什么?怎么做降级?

    • 收益:TTFB 更早、首屏更快。
    • 坑:错误处理/中断恢复更复杂;缓存必须按用户/权限隔离;并发下超时与资源泄露风险更高。
    • 降级:SSR 超时/失败回退 CSR;关键模块失败只降级局部,不拖垮整页。
  • [ ] Q4:导出怎么保证“一致性 + 权限隔离”?失败怎么兜底?

    • 一致性:导出与线上展示同一份数据与渲染口径(同一套数据加工/筛选规则)。
    • 权限:导出任务携带用户身份与权限快照,服务端按权限过滤数据,避免越权导出。
    • 兜底:异步任务 + 重试;必要时降级到截图或导出占位,并完整上报失败原因与版本号。
  • [ ] Q5:高频刷新大屏为什么容易卡?你怎么治理并“可观测”?

    • 卡的根因:长任务(计算/渲染)、联动触发链过长、图表动画/数据量过大、内存增长。
    • 治理:数据层合并/节流/降采样;渲染层局部更新/分片/虚拟化;图表降级(动画/细节)。
    • 可观测:Long Task、FPS/掉帧、内存趋势、错误率与关键交互耗时(按大屏/组件维度打标签)。

手写代码区

1)SSR 注水/脱水(避免 hydration mismatch 的最小思路)

type Dehydrated = { route: string; data: unknown }

export function serializeState(state: Dehydrated) {
  // 真实项目:注意 XSS(转义/安全序列化)
  return JSON.stringify(state)
}

export function deserializeState(raw: string): Dehydrated {
  return JSON.parse(raw) as Dehydrated
}
1
2
3
4
5
6
7
8
9
10

2)导出任务:带权限快照的最小协议(伪代码)

type ExportJob = {
  reportId: string
  userId: string
  permissionSnapshot: string[] // 例如资源权限列表
  params: Record<string, any>
}

export function canExport(job: ExportJob, requiredPerm: string) {
  return job.permissionSnapshot.includes(requiredPerm)
}
1
2
3
4
5
6
7
8
9
10

我的补充(Manual)

(不会被脚本覆盖:真实约束、组织因素、踩坑)

上次更新:
(adsbygoogle = window.adsbygoogle || []).push({});