由兴趣驱动开源 cherry markdown 成长之路

如果无法正常显示,请先停止浏览器的去广告插件。
分享至:
1. 由兴趣驱动开源 Cherry Markdown 成长之路 胡杰雄 腾讯TAPD 前端开发工程师
2. 1. 组件介绍与背景 目录 2. 内核引擎实现 3. 性能 4. 应用与拓展
3. 01 组件介绍与背景
4. Cherry Markdown 简介 工具栏 语言编辑区 Markdown解析引擎 富媒体预览区
5. 组件背景 公司内部使用不同开源组件 公司的开源协同战略 公司内部支持md的产品都是使用的外部开源组件,这一方面导 1. 2019 年公司开启开源协同战略 致不同产品md编辑体验、语法能力、语法规则不统一,用户在 2. 腾讯前端技术委员会的成立 产品间切换时学习成本高;另一方面引入外部组件缺乏技术审 核,有协议、安全风险 业界 Markdown 开源组件支持有限 个人原因、项目经验 业界 Markdown 开源组件支持的功能与场景有限,有的仅做语 个人兴趣驱动,想做一款业内好用的 Markdown 编辑器,加上 法转译的部分,有的是chrome插件或者现成无法拓展功能的应 部门内有志同道合的同事一起作战;TAPD Markdown 功能 6 用软件。 年的积累,场景多,用户反馈体验升级诉求。 组件预期: 语法转译 + 可视化 + 按需加载语法 + 自定义语法
6. 团队成立 2019·11 团队成立 4个来自3个产品团队的开发小伙伴聚到了一起 没有产品、没有KPI、没有经费、没有用户 一腔热情配张饼
7. 02 内核引擎实现
8. 内核引擎实现效果 Markdown解析引擎
9. 内核引擎业界实现 1 —— AST 语法树 # title ```javascript var a = 1; ``` Markdown Flow (结尾添加换行符 \n) 预处理 词法分析 文本切割 # title ```javascript var a = 1; ``` 语法分析 标题 render DOM 树 Document Heading CodeBlock 代码块 优点 缺点 性能相对快 拓展性差 实现难度高 一次词法分析 语法分析需预编译 或 依赖第三方语法规则
10. 内核引擎业界实现 2 —— 正则表达式 # title ```javascript var a = 1; ``` Markdown Flow 正则 语法 1 let temp = text.match(/^#\s/); 语法 1 If (temp[0] === ‘#’) { // render return ‘<h1>’+ rows.substring(2) + ‘</h1>’ } render 语法 2 正则 render DOM 树 // 正则 语法 2 …. 代码块 正则 … 代码块 render <h1>title</h1> <pre> <code> <span>var a = 1;</span> </code> </pre> 优点 缺点 易实现 性能相对慢 易拓展 多次正则匹配(词法分析)
11. Cherry Markdown 内核引擎实现目标 Markdown 语法可插拔 Markdown 语法学习成本低 易拓展 内核引擎调度 Markdown 语法链路简单 提高可维护性
12. Markdown Hook 机制 每个 Markdown 语法设为 Hook 优点:易拓展、调度 Markdown 语法链路灵活、学习成本低
13. Markdown Hook 链路配置 —— before、after 通过 before、after 插入数组链路的单元中 配置声明 Markdown Flow 编译链路 tapd-table tapd-html custom-hook
14. Markdown Hook 代码实现 代码 Hook 编译流程图 Markdown text input Hook.rule () Hook.makeHtml () 方法含义 makeHtml: 转义 markdown text 文本 rule: 语法匹配 优点 2种周期方法,概念少 result output
15. Markdown Hook 机制难点 部分 Markdown 语法 makeHtml 方法输出影响其他语法 代码块语法内容不允许被转义
16. Markdown Hook 分类 加粗 基础语法 Syntax 类 斜体 … Hook 代码块 排它语法 Paragraph 类 基础语法:默认语法 排他:预先转译并缓存转译结果,等编译结束返回缓存结果 公式 …
17. Markdown Hook 难点解决 —— 排他 Markdown Flow List CodeBlock List 基础类 排它类 CodeBlock 基础类 排它类
18. Markdown Hook 难点解决 —— 排他实例
19. Markdown Hook 心智思路开发 心智思路 真实链路
20. 内核引擎架构图
21. 第一版发布 · 内部开源 2019·11 团队成立 4个来自3个产品团队的开发小伙伴聚到了一起 没有产品、没有KPI、没有经费、没有用户 一腔热情配张饼 2020·4 第一版发布 · 内部开源 实现所有通用语法功能 内部产品率先使用(TAPD、乐享 iwiki) 第一次内部推广(3k+浏览,63收藏,63评论,团队扩张) 制定开发规范、代码提交规范、完成API文档 用户有了啥都有了
22. 03 性能
23. 正则表达式 —— 缺点 # title ```javascript var a = 1; ``` Markdown Flow 正则 语法 1 let temp = text.match(/^#\s/); 语法 1 If (temp[0] === ‘#’) { // render return ‘<h1>’+ rows.substring(2) + ‘</h1>’ } render 语法 2 正则 render DOM 树 // 正则 语法 2 …. 代码块 正则 … 代码块 render <h1>title</h1> <pre> <code> <span>var a = 1;</span> </code> </pre> 优点 缺点 易实现 性能相对慢 易拓展 多次正则匹配(词法分析)
24. 场景 1. 首次阶段,全文编译 减少正则匹配次数 2. 后续编辑阶段 减少正则匹配原文行数 排它类
25. 编辑时优化 局部编译 1. 首次阶段 (以段落为节点存储原文) 首次编译 <h2></h2> <p></p> <ul></ul> Render 信息缓存 md5StringCache[text1] = hash(text1) md5StringCache[text2] = hash(text2) md5StringCache[text3] = hash(text3) (text1、text2、text3 为 markdown 原文) 2. 后续编辑阶段 编译 & 缓存 undefiend 查找 md5StringCache md5StringCache Hash 无操作
26. 优化效果 2000 行数的编译效果 首次阶段 编辑阶段 优化前 307 217.35 217.35 20 全文编译(ms) 局部编译(ms) 后化后
27. 大文档下,编辑实时回显带来性能开销 2000 行 text 渲染612.73ms
28. 性能低效原因分析 render setData Hooks 预览对象 innerHTML Previewer DOM 耗时612.73ms 新 DOM Tree 原因: 1. 大批量 DOM 操作,全局更新预览区域 2. 绝大多数 DOM 无需更新 优化:局部更新 render Hooks 新 DOM Tree Virtual DOM Diff Old DOM Tree Patch end 耗时 ? ms
29. 解决思路—— Virtual Dom Diff 处理 负优化
30. Virtual Dom Diff 不是万能 Vue/React 框架 Cherry Markdown data 响应 / setData 某组件 数据更新较快的原因: 慢原因: 1. 组件化:简化 Dom Tree 复杂度,各组件“自治” Dom 更新 1. Virtual Dom Diff 不适合复杂且数据量极大的场景 2. setData/ data 响应式: 触发某小块 Dom 区域的数据更新 2. 缺乏数据变化的监听事件 3. 预览区包含代码块、公式、画图等复杂 DOM 树,加重 Virtual DOM Diff 计算负担
31. 解决思路优化—— 局部编译 + 局部渲染 缩小 DOM Diff 成本
32. 局部编译 + 局部渲染 局部编译 编译 <h2></h2> <p></p> <ul></ul> 收集 data-sign Hash Text Hash List 原文 Hash 处理 Hash Text 放入 Render DOM Attr 方便预览对象收集 局部更新 Myers Diff + Virtual dom diff patch update 收集 data-sign Update Hash Virtual Dom patch Insert Hash Append dom Remove Hash Remove dom Hash List Myers Diff 算法 预览对象 Old Hash List (最短编辑距离) (找出最短增删改操作)
33. 渲染优化效果 优化前 612.73 47 渲染耗时(ms) 后化后
34. 局部编译+局部渲染效果
35. 0.4版发布 2020·8 2019·11 0.4版发布 团队成立 安全 4个来自3个产品团队的开发小伙伴聚到了一起 性能 扩展能力 没有产品、没有KPI、没有经费、没有用户 接入便捷性 对方不仅使用我们,还给我们提了一堆issue 一腔热情配张饼 2020·4 第一版发布 · 内部开源 实现所有通用语法功能 内部产品率先使用(TAPD、乐享) 第一次内部推广(3k+浏览,63收藏,63评论,团队扩张) 制定开发规范、代码提交规范、完成API文档 用户有了啥都有了
36. 04 应用与拓展
37. 应用层实现 开箱即用 · 实例化对象 实例化对象 New Cherry 对象。 · 框架提供容器作用 • Angular 、React、Vue等框架提供容器作用即可。 Vue 为例 框架提供容器环境
38. 拓展插件 · 自定义插件,拓展语法 实现自定义 codeBlock 插件 自定义 codeBlock 插件
39. 拓展能力例举——嵌入第三方应用
40. 成长时间轴·正式成为Oteam 2019·11 2020·8 团队成立 0.4版发布 4个来自3个产品团队的开发小伙伴聚到了一起 安全 没有产品、没有KPI、没有经费、没有用户 性能 扩展能力 接入便捷性 一腔热情配张饼 对方不仅使用我们,还给我们提了一堆issue 2020·4 第一版发布 · 内部开源 2021·5 正式成为腾讯 Oteam 实现所有通用语法功能 申请专利9篇 内部产品率先使用(TAPD、乐享) 参与人数达到12个团队35人 第一次内部推广(3k+浏览,63收藏,63评论,团队扩张) 与11款toC、toB、组件类产品合作(腾讯文档、TAPD、腾讯灯塔) 制定开发规范、代码提交规范、完成API文档 更多用户更多创意 用户有了啥都有了
41. 图片缩放、对齐、引用
42. 根据表格内容生成图表 自定义图形库
43. 字体颜色、字体大小 可能是唯一支持的 markdown 组件
44. 表格单元格合并
45. 复制HTML 粘贴自动转译成 Markdown
46. 图片大小
47. 导出
48. 成长时间轴·开源 2019·11 2020·8 2021·10 团队成立 0.4版发布 正式对外开源 4个来自3个产品团队的开发小伙伴聚到了一起 安全 没有产品、没有KPI、没有经费、没有用户 性能 扩展能力 接入便捷性 一腔热情配张饼 对方不仅使用我们,还给我们提了一堆issue 2020·4 第一版发布 · 内部开源 2021·5 正式成为腾讯 Oteam 实现所有通用语法功能 申请专利9篇 内部产品率先使用(TAPD、乐享) 参与人数达到12个团队35人 第一次内部推广(3k+浏览,63收藏,63评论,团队扩张) 与11款toC、toB、组件类产品合作(腾讯文档、TAPD、腾讯灯塔) 制定开发规范、代码提交规范、完成API文档 更多用户更多创意 用户有了啥都有了
49. 共建
50. 感谢倾听 大会官网

Home - Wiki
Copyright © 2011-2024 iteam. Current version is 2.137.1. UTC+08:00, 2024-11-15 20:32
浙ICP备14020137号-1 $Map of visitor$