声明:需要读者对 NodeJs、vue 服务器端渲染有一定的了解
现在,前后端分离与客户端渲染已经成为前端开发的主流模式,绝大部分的前端应用都适合用这种方式来开发,又特别是 react、Vue 等组件技术的发展,更是使这种方式深入人心。
但有一些应用,客户端渲染就会遇到一些问题了:
如果能把客户端渲染的组件化技术(React、Vue 等)与传统的后端渲染的方式有效的结合起来,两者兼具,那就太完美了。
所以,这次就来聊聊 Vue 组件的服务器端渲染。
根据社区现有的一些方案,结合自己的实践,针对团队技术力量的不同,说说不同应用场景选择方案时的优先级。
一般前后端的工作流是 后端 -> 前端。
传统的后端渲染模式是后端负责包括 url、接口、模板渲染等,前端与后端耦合在一起,当然这种方式正在慢慢的退出历史舞台。
主流的客户端渲染则是后端只提供接口(如有需要,可以提供必要的 url),前端与后端只通过接口交流数据,路由与渲染都在前端完成。
而 NodeJs 渲染中间层的工作流则是 后端 -> NodeJs -> 前端(NodeJs 渲染中间层由前端开发人员掌握)。
这种模式下,后端只提供接口,传统的服务器端路由(url)、模板渲染则都有 NodeJs 层接管。这样,前端开发人员可以自由的决定哪些组件需要在服务器端渲染,哪些组件可以放在客户端渲染,前后端完全解耦,但又保留了服务器端渲染的功能。
这种方案最成熟的是 nuxt.js。
如果有需要,大家可以自己去 nuxt.js 官方文档 看看具体的使用方法和详细的功能。
应该说,这种方式是目前最完美的一种方案,但也有一些隐患:
所以,这种方式适合对并发量、安全性、稳定性等要求不高,但又需要做 SEO 或首屏快速加载的页面。
当然,如果你能够自己改造相关的工具,就另当别论了。
当不能使用 NodeJs 中间层时,而又要达到 SEO 与首屏快速响应的目的时,在传统的后端模板渲染的基础上,就需要对前端的页面加以适当的改造。
首屏快速响应就意味着首屏渲染所需的数据是跟 HTML 文件一起到达浏览器的,这些数据当前是由后端模板引擎嵌入到 HTML 页面中的。
以 Java 的 freemarker 模板引擎为例:
(html 中以 script 的方式获取模板的数据,这样就算是在本地调试、开发,也不会报错)。
<script>
window.globalData = {
stringValue: '${stringValueTplName}',
intValue: parseInt('${intValueTplName}', 10),
};
</script>
如果是复杂的 Json 数据或者其他复杂的模板数据(比如列表数据),则可以像下面这样接收:
<script type="text/tpl" id="tpl-script-json">
window.tmpData = {
jsonValue: ${jsonValueTplName},
};
</script>
<script>
try {
eval(document.getElementById('tpl-script-json').innerText);
} catch (e) {
window.tmpData = { jsonValue: {} };
}
window.globalData = {
jsonValue: window.tmpData.jsonValue,
};
</script>
这样,你就可以在组件里使用 window.globalData 的数据了,而不用另外用接口获取数据,达到加快首屏渲染的目的,而且本地开发、调试也不会报错。
如果你使用了本地数据 Mock 功能,也可以很容易的与这种方式结合在一起,只要稍加改造:
此外,还有一些措施来进一步加快首屏渲染:
在上面加载首屏渲染的基础上,对于 SEO 优化也可以做相应的改造。
其实,在客户端渲染已慢慢成为主流开发模式的同时,搜索引擎也在跟进这种变化。
截至目前,Google 和 Bing 可以很好对同步 JavaScript 应用程序进行索引,也就是说,即使是客户端渲染,但只要是同步数据渲染(非 Ajax 获取数据,比如模板数据),搜索引擎也能抓取到相应的 HTML 片段。
(国内的百度搜索与360搜索等暂时还没有跟进动态)
但为了兼容所有的搜索引擎,可以像下面改造:
<div>
<!-- 这里放置由后端模板引擎渲染的专给搜索引擎抓取的片段,用户不可见 -->
</div>
<script>
// 接收同步数据
window.globalData = {
stringValue: '${stringValueTplName}',
intValue: parseInt('${intValueTplName}', 10),
};
</script>
如果页面没有动态数据,那就好办了,直接把组件导出为静态 html,然后由客户端激活。
具体过程可以参考 官方文档。
这种方案比较好的是 nuxt.js generate 静态 HTML 文件。
目录结构:
- pages/ # 页面结构目录
- index.vue
- second.vue
- ...
- nuxt.config.js # 配置文件
- package.json
- dist # 导出静态 HTML 文件的默认目录
导出静态 HTML 文件
npx nuxt generate
如果一个项目里有多个 pages,可以这样构建:
目录结构:
- nuxt.config.js # 配置文件
- package.json
- src/
- home/ # home 页面
- pages/ # 页面结构目录
- index.vue
- second.vue
- ...
- dist # 导出静态 HTML 文件的默认目录
- about/ # about 页面
- pages/ # 页面结构目录
- index.vue
- second.vue
- ...
- dist # 导出静态 HTML 文件的默认目录
导出静态 HTML 文件
npx nuxt generate src/home -c ../../nuxt.config.js # home 页面
npx nuxt generate src/about -c ../../nuxt.config.js # about 页面
除了上面提到的这些方式外,当然还有其他的方式,比如:
因为模式的改变,服务器端渲染与传统的后端模板渲染工作方式有很大的不同,所以在开发时需要与后端开发人员做好沟通,避免认知上的不同导致协作不协调。
作者:深予之 (@senntyou)
地址:https://github.com/senntyou/blogs/blob/master/extend/18.md
在使用vue的时候,我们都知道它是双向数据绑定的,但是在使用不熟的情况下,经常会遇到:data中的数据变化了,但是并没有触发页面渲染。下面就整理一些出现这种情况的场景以及解决办法。
这里结合art-template模板引擎说明。首先了解下前端页面中如何使用art-template。当不需要对SEO友好的时候,推荐使用客户端渲染;当需要对 SEO友好的时候,推荐使用服务器端渲染
在使用vue的时候,偶然发现多次刷新或者网络加载缓慢的时候,会一瞬间出现设置的模板的情况。实在很影响美观,可以使用vue现成的指令来解决这个问题:v-cloak
大部分Web应用的富文本内容都是以HTML字符串的形式存储的,通过HTML文档去展示HTML内容自然没有问题。但是,在微信小程序(下文简称为「小程序」)中,应当如何渲染这部分内容呢?
估计大家都听过,尽量将 CSS 放头部,JS 放底部,这样可以提高页面的性能。然而,为什么呢?大家有考虑过么?很长一段时间,我都是知其然而不知其所以然,强行背下来应付考核当然可以,但实际应用中必然一塌糊涂
原生JS改变页面数据,必须要获取页面节点,也即是进行DOM操作,jQuery之类的框架只是简化DOM操作的写法,实质并没有改变操作页面数据的底层原理,DOM操作影响性能(导致浏览器的重绘和回流),Vue是一个mvvm框架(库),大幅度减少了DOM操作
在决定渲染方式时,需要测量和理解真正的瓶颈在哪里。静态渲染或服务器渲染在多数情况都比较适用,尤其是可交互性对JS依赖较低的场景。下面是一张便捷的信息图,显示了服务器到客户端的技术频谱:
如果从服务端返回的数据量较少,或者只有几个字段,可以用vue的set方法,如果数据量较大,请直接看第二种情况。官网API是这样介绍的:Vue.set(target,key,value)
当数据需要异步加载时render获取不到数据可能会报一些错误,此时需要在render函数中加一个判断.行到render时,state对象的haveData为false, 所以此时页面展示 loading,当异步获取数据成功时
在vue.js中,要将一段字符串渲染成html,可以使用v-html指令。但是 官方文档 中的v-html部分也提醒了
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!