新时代的 SSR 框架破局者:qwik( 四 )


  • APP_STATE:应用程序的状态 。简单来说应用程序的状态就是 HTML 事件中的各个状态事件,如果不存在这些事件状态那么所有的内容都是没有任何交互效果的 。
  • FRAMEWORK_STATE:框架内部状态 。通常我们会利用诸如 React 或者 Vue 等框架进行接替渲染 。如果没有 FRAMETER_STATE,框架内部就不知道应该更新哪些DOM节点,也不知道应该在什么时候更新它们 。
通俗来说 Hydration 就是在客户端重新执行 JS 去修复应用程序内部的 APP_STATE 以及 FRAMEWORK_STATE 。
同样还是这这张图:
 
新时代的 SSR 框架破局者:qwik

文章插图
 
在图中的前三个阶段可以被称为 RECOVERY 阶段,这三个阶段主要是在重建你的应用程序 。
当从 Server 端下发的 HTML 静态页面后,我们希望它是具有交互效果的 HTML 正常应用程序 。
那么此时 hydartion 的过程必须经历下载 HTML 、下载所有相关 JS 脚本、解析并且执行下载的 JS 脚本 。
RECOVERY 阶段是和 hydartion 的页面的复杂性成正比,在移动设备上很容易花费 10 秒 。
由于RECOVERY是昂贵的部分,大多数应用程序的启动性能都不是最佳的,尤其是在移动设备上 。
前三个阶段被称为 RECOVERY 的阶段其实是完全没有必要的,因为在服务端我们已然渲染过对应的 HTML,但是为了应用程序的可交互性以及服务端仅保留了静态的 HTML 模版导致不得不在 Client 上继续执行一次 Server 端的逻辑 。
总而言之,hydration 其实是通过下载并重新执行 SSR/SSG 呈现的 HTML 中的所有 JS 脚本并执行来恢复组建中的事件处理程序 。
同一个应用程序,会被发送到客户端两次,一次作为 HTML,另一次作为 JavaScript 。
此外,框架必须立即执行 JavaScript 以恢复在服务器上被丢掉的 APP_STATE和FRAMEWORK_STATE 。所有这些工作只是为了检索服务器已经拥有但丢弃的东西!!
比如这样一个例子:
export const Main = () => <><Greeter /><Counter value=https://www.isolves.com/it/cxkf/kj/2023-02-28/{10}/>export const Greeter = () => {return ()}export const Counter = (props: { value: number }) => {const store = useStore({ count: props.number || 0 });return ()}上边的例子中我们编写了一个 Counter 的计数器组件,在传统 SSR 过程中该组件会被渲染成为:
<button>Greet</button><button>10</button>可以看到上边的两个按钮不拥有任何处理状态的能力 。
要使网页具有交互性,必须要做的就是通过下载对应 HTML 页面中的 script 脚本并执行代码从而恢复按钮上的交互逻辑和状态 。
为了具有交互性,客户端不得不执行代码实例化组件后重新创建状态 。
当上述过程完成后,你的应用程序才会真正具有可交互性 。无疑,同一个组件的渲染逻辑被执行了两遍,这是一个非常冗余且耗费性能的过程 。
2)Resumability: 更加优雅的 hydartion 替代方案
所以为了消除额外的开销,我们需要思考如何避免重复的 RECOVERY 阶段 。同时还要避免上面的第四步,第四步是执行脚本后给现有的 HTML 附加正确的事件处理程序 。
qwik 中提出了一个全新的思路来规避 RECOVERY 带来的外开销:
  • 将所有必需的信息序列化为 HTML 的一部分 。qwik 将需要的状态以及事件序列化保存在 Server 端下发的 HTML 模版中,需要序列化信息需要包括WHAT(事件处理函数内容), WHERE(哪些节点需要哪些类型的事件处理函数), APP_STATE(应用状态), 和FRAMEWORK_STATE(框架状态) 。
  • 依赖于事件冒泡来拦截所有事件的全局事件处理程序 。qwik 中事件处理程序是在全局处理的,这样我们就不必在特定的 DOM 元素上单独注册所有事件 。
  • qwki 内部存在一个可以延迟恢复事件处理程序的工厂函数 。
    该工厂函数主要用于处理 WHAT 阶段,也就是用来识别某个事件处理函数中应该存在什么脚本逻辑 。
 
新时代的 SSR 框架破局者:qwik

文章插图
 
我们可以看到所谓的 Resumable 对比 Hydration 明显可以省略不需要后三个阶段,直接获取 HTML 后页面其实就已经准备完毕,这无疑对于性能的提升是巨大的 。


推荐阅读