性能优化之SSR服务端渲染动态SDK组件的注意点

1,021 阅读2分钟

性能优化之SSR服务端渲染动态SDK组件的注意点

看之前需要有SSR服务端渲染的相关知识积累

背景

在做性能优化时,碰到一个场景:

  1. HTML页面中的某一大块内容是通过引SDK加载出来的。但问题就是,这块内容无法支持SSR服务端渲染,只能在客户端渲染。这样会造成一个很大的时延

这个场景大家平常可能会比较少碰到。我也是因为我们业务比较多,比较复杂,才碰到这么一个特殊的场景

场景条件

  1. vue
  2. SSR服务
  3. 某块内容由SDK加载,这块内容无法支持SSR服务端渲染,只能在客户端渲染

ps:SDK可以理解为 封装好的一个组件,里面有完全的功能,比如一个很复杂的表单。 后面就以表单举例,SDK就可以理解成一个表单。要渲染这个表单,我们需要 import ... from 'sdk.js'

分析:为什么无法支持SSR服务端渲染?

首先分析如何使用这个SDK,发现有以下几个特点

  1. 必须要有一个dom,并且要写id,和SDK约定好的id <div id="__oneForm__"></div>
  2. 放mounted和created等 服务端都无法渲染出来,客户端正常渲染
<template>
  <div>
    <div id="__oneForm__"></div>
  </div>
</template>

<script>
import oneForm from 'sdk.js'
export default {
  mounted () {
    new oneForm({
      ...配置项
    })
  }
}
</script>

分析:

  1. 服务端无法渲染出来,很可能和dom有关系,服务端没有dom
  2. 看这种写法和 new Vue() 比较像,稍微了解vue的源码的话(可以看我以前的文章,有基础的vue源码解析),就知道源码会有一个 $mount('#app')的过程,实际上就是去页面上,把div id="app">domNode.replaceChild() 掉,所以依赖真实的dom,服务端没有dom所以行不通
  3. 看了一下SDK的源代码,确实用的new Vue()

分析到这,看起来是已经无解,尬住了

但实际上,再仔细想想的话,其实有解决办法

解决办法

想想同类型的场景,比如ui组件库,为什么能支持SSR的服务端渲染?

  • 是因为他们都做成了子组件( Vue.component() / Vue.use() ),所以组件级别的SSR服务端渲染还是能支持的

所以,解决思路是

  • 把SDK稍微改造一下,改成 Vue.component() 或 Vue.use() 的方式去注册组件,而不是 new Vue({ el: '#app', ... })

码子不易,点赞鼓励!