/

实时预览的原理

Quarkdown 的Web 服务器 实现了编译器 CLI 与浏览器之间的直接通信,从而使实时预览成为可能。

服务器暴露了以下端点:

实时预览包装层

当通过 /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:AB。假设 A 当前可见。当检测到变更时,Quarkdown 会在 A 仍停留在屏幕上的同时,将更新后的内容渲染到 B 中。一旦渲染完成,可见的 iframe 就会从 A 切换到 B,从而实现无缝更新。

在交换缓冲区之前,系统还会保留上一帧的滚动位置,并将其恢复到新帧中,这样你就不会因为文档的位置丢失而找不到内容。