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


当然,在最新的 Next 版本中已经支持了Stream以及 Server Components 。
整个过程就像是这张图中的样子:
 

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

文章插图
 
2)优势
简单聊过了所谓 SSR 的原理后,如果你有认真看上述的内容 。其实我相信相较于 CSR,SSR 这种方式的好处不言而喻:
  • 更好的搜索引擎优化 SEO 方式,HTML 模板是从服务端直接下发这也就导致搜索引擎爬虫中更多的关键字匹配 。
  • 更快的首屏渲染,因为相较于 SPA 它少了在 Client 中下载和执行 JS 脚本后渲染的过程 。
  • 页面不需要 JS 也可以正常渲染,虽然没有 JS 意味着页面失去了可交互性 。但对于禁用 JS 的用户来说,展示一些静态内容总比 SPA 应用的白屏来的更加友好一些对吧 。
3)劣势
当然,任何技术方案在不同场景下也存在它自己的不足 。
  • 强依赖于服务 。
    针对于 CSR 的方式它是一种纯静态资源 。我们可以直接将它放在 CDN 上就可以良好的用户访问到,而 SSR 的方式必须依赖于一个服务器进行服务端预渲染 。(当然纯 SSG 应用我们不在这个讨论范围之内)
    同时,有服务的地方就存在并发压力 。当你需要为你的应用考虑服务端渲染的方式时,一定不要忘记为你的服务器进行压测 。
  • ??Time to Interactive?? 可交互时间 (TTI) 的增长,虽然说 SSR 的方式有效的缩短了首屏加载的方式,但是会增加所谓的TTI(可交互时间) 。
    所谓的 TTI 指标测量页面从开始加载到主要子资源完成渲染,并能够快速、可靠地响应用户输入所需的时间 。
    因为 SSR 的方式在用户访问时会下发当前页面中静态的 HTML 内容,也就是所谓的 ?First Contentful Paint? 首次内容绘制 (FCP) 会非常快速,但是页面需要用户交互效果又需要下载和执行完成 JS 脚本发生 hydatrion 后才具有交互性 。
    这也就造成页面的 TTI 相较于 CSR 方式会有所差劲,因为 CSR 在渲染完成后就会立即具有交互性(不需要其他任何多余步骤) 。
1.3 qwik上述聊了那么多前置内置,终于要和大家切入正题了 。
所谓磨刀不费砍柴功,上边和大家强调现阶段 SSR 的方案以及对应的优劣势就是为了引入下面的内容 。
首先,这篇文章的目的是为了让大家在当前众多 SSR 框架中思考性能方面是否可以有所提升的,在服务器方面不会过多的深入 。
我们可以稍微思考下上述服务器端渲染的过程:
 
新时代的 SSR 框架破局者:qwik

文章插图
 
第一步我们需要在服务端获取对应页面的 HTML 页面,大多数情况(非纯静态页面)就需要在服务端掉用对应渲染方法渲染出 HTML 页面 。
那么,如果我们能在第一步渲染 HTML 页面时,就添加对应的事件处理 。后续的 3 步是不是完全可以省略下来了对吧 。
其实社区内部之前已经有非常多的方案来提升所谓 SSR 框架的性能方案 。
比如 Remix 的 HTTP stale-while-revalidate 缓存指令
比如 astro 等新兴框架的 Islands 架构方案,关于 Islands 有兴趣的朋友可以参考神三元的这篇 Islands 架构原理和实践 。
针对于上面的概念,我们直接来看看 qwik 中提到的 Hydration is Pure Overhead (完全多余的 Hydration) 。
1)Hydration 造成的开销
首先针对于 Hydration 的过程,我们提过到首先会在服务器上进行一次静态 HTML 渲染,之后当 HTML 下发到客户端后又会再次进行 hydrate 的过程,在客户端进行重新执行脚本添加事件 。
Hydration 过程的难点就在于我们需要知道需要什么事件处理程序,以及将该事件处理程序附加在哪个对应的 DOM 节点上 。
这个过程中,我们需要处理:
  • 每一个事件处理程序中的内容,绝大多数框架中的状态都作为闭包函数保存在内容中 。所以需要 hydration 的过程来重新获取状态 。
  • 其次,在搞清楚了每个事件处理函数的内容后 。我们也需要将对应的事件处理函数附加到对应的 DOM 节点上,同时还要确保该监听器的正确事件类型 。
更加复杂每个事件处理函数中的内容是一个闭包函数,这个函数内部需要处理两种状态,App_STATE 以及 FRAMEWORK_STATE 。


推荐阅读