新项目中使用 Vue.js,随着开发的推进,对 Vue 的官方文档及源码的阅读和学习也在深入。与 React 的jsx相似, Vue 在底层的实现上,也是将模板编译成虚拟 DOM 渲染函数。而这个编译过程一般通过webpack 等构建工具提前完成,在代码运行时只需要引入runtime版本即可,无需实时编译,否则会对性能造成影响 。
使用 runtime 版本替代带编译器版本
Vue的官方文档中有对 Runtime + Compiler vs. Runtime-only的说明,如果项目中的Vue 实例没有用到 template
字符串或 dom 模板作为选项,则可以引入 runtime 版本的dist 文件,在 webpack 中可以配置一个别名予以简化引入。我们的项目使用了官方的webpack 工程模板(有经过改造),在这里用的还是编译器版本的,于是将其调整为 runtime版本:
1 | module.exports = { |
使用 render 选项替代 template
项目中的组件模板都是通过单文件组件(*.vue
文件)组织的,通过vue-loader
已经提前编译成 render 函数,按理说可以使用 runtime 版本,但跑起来始终报 You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
Debug 发现,原来入口文件main.js
中初始化根组件时引入 App
组件就用了 template
选项:'<App/>'
,问题就在这里,改动方法也比较简单,就是将其改为 render
选项:
1 | new Vue({ |
render
选项传入的是一个回调函数,createElement
作为这个函数的参数,其实可以是任意一个有效函数名,但如文档所述,作为通用惯例,可以用h
来替代 createElement
。
总结
对于runtime版本的使用,官方文档都有详见的描述,但是由于使用了官方的 webpack 工程模板,默认使用了带编译器版本,而且没有对此细节的相关说明,也是踩了一个小坑。虽然官方说实时编译本来也已经很快了,但对大型应用来说,这个性能优化还是有必要的,而且runtime版本比带编译器版本的dist文件小了不少(生产构建版本当然不会差太多),也是能节省一点流量开销。
不过,要使用 runtime 版本得确保组件实例里不存在 字符串template 选项或dom模板,可以根据自己的实际项目需求来定。