zhangyuang / ssr

A most advanced ssr framework support React17/React18/Vue2/Vue3 on Earth that implemented serverless-side render specification.
http://doc.ssr-fc.com/
MIT License
2.61k stars 284 forks source link

feature: 支持 html <head> 标签内容分块提前返回 #283

Closed MervynFang closed 1 year ago

MervynFang commented 1 year ago

背景:

  1. ssr 框架直出页面因为服务端处理时间相比 cdn 静态文件较长,白屏时间较长且无法操作。
  2. http 协议支持分块返回,h1:Transfer-Encoding: chunked,h2:data 帧,故可以考虑提前返回 html 头部,达到提前加载静态资源,并可以提前返回 loading 或 骨架屏
  3. react 18 支持 renderToPipeableStream,故可以不用考虑 react 的实现

需求: 支持 vue2/3 ssr 提前返回 html 内容

个人愚见可以这么实现: #282

实现方案: 总的来说,需要支持单独获取 html head 标签内容,提前返回该内容并且不结束本次请求,这样浏览器端可以提前解析返回的 html 分块内容。然后正常调用 render,生成 body 内容返回,这与 layout 生成一致,最后再返回 </html>,并且结束请求 res.end()

  1. ssr-core 增加 headRender 方法,此方法为 controller 获取 html 头部字符串。
  2. config 增加 htmlHeadChunked 配置,此配置为 ssr-core render 方法区分为 true 情况下不拼接 <!DOCTYPE html> 和不设置响应头部,交由 controller 处理。(多次返回不能在一次返回后设置头部)
  3. server-entry 增加 headRender 方法,获取路由和配置,通过 utils generateHeadHtml 返回 head 标签字符串
  4. utils runtime 增加 generateHeadHtml,作用是生成 cssInjectcustomeHeadScript 替换 htmlTemplate 内容,其中包括 css files,preload js files,customeHeadScript 和 inline css,生成 html 头部标签内容字符串。
  5. controller 先返回 headRender 返回的字符串,然后正常返回 render stream,end 事件后返回 html 闭合标签,结束请求

预期效果:

  1. 由于 head 提前返回给浏览器解析,预期可以优化小比例的首屏时间
  2. css js 的预加载可以提升 fid
  3. 增加 loading / 骨架屏可优化白屏体验
zhangyuang commented 1 year ago

close by #284