/
Quarkdown 的Web 服务器 实现了编译器 CLI 与浏览器之间的直接通信,从而使实时预览成为可能。
服务器暴露了以下端点:
/:file:提供相对于目标文件的静态文件(即 quarkdown start 的 -f 选项)。
/live/:file:工作方式与前一个端点类似,但会用一层包装将 HTML 文件包裹起来,以启用实时重载。
/reload:用于实时重载的 WebSocket 端点。
/live 端点的浏览器会监听重载消息,并在收到时刷新页面。当通过 /live/:file 端点提供文件时,服务器会将 HTML 文件包裹在一个简单的 HTML 包装层中,该包装层通过 iframe 来显示 /:file 的内容。
此外,一段小程序会与 /reload 端点建立一个持久的 WebSocket 连接。该程序监听重载消息,并在收到时触发 iframe 内容的重载。
sequenceDiagram
participant Browser
participant Server
participant CLI
Browser->>Server: GET /live/:file
Server-->>Browser: Live preview HTML wrapper
Browser->>Server: WebSocket connect /reload
CLI->>Server: WebSocket message /reload
Server->>Browser: WebSocket broadcast /reload
Browser->>Browser: Reload iframe content当 iframe 重载时,可能会出现令人不快的闪烁效果。为了提供流畅的用户体验,Quarkdown 采用了一种称为双缓冲(double buffering)的技术。
作为背景,你在日常计算中经常会遇到双缓冲:你的 GPU 在显示当前帧的同时,将下一帧渲染到一个离屏缓冲区中。一旦下一帧准备就绪,缓冲区就会交换,从而实现无闪烁的平滑过渡。
Quarkdown 应用了相同的原理,维护两个 iframe:A 和 B。假设 A 当前可见。当检测到变更时,Quarkdown 会在 A 仍停留在屏幕上的同时,将更新后的内容渲染到 B 中。一旦渲染完成,可见的 iframe 就会从 A 切换到 B,从而实现无缝更新。
在交换缓冲区之前,系统还会保留上一帧的滚动位置,并将其恢复到新帧中,这样你就不会因为文档的位置丢失而找不到内容。