在单页应用(SPA)中,网站或应用的所有内容都由一款 JavaScript 应用程序处理,用户输入的 URL 不会直接引发页面刷新,仅仅是切换视图。这种技术带来的好处是极快的用户体验和流畅的页面转场,但也带来了一个严重的问题:SEO。
由于搜索引擎抓取页面的方式是通过 URL 请求 HTML,而 SPA 的 HTML 是通过 JavaScipt 在客户端生成的,因此,搜索引擎无法抓取到 SPA 的完整内容,导致 SPA 的所有页面都不容易被搜索引擎索引。
为了解决这个问题,我们可以使用 Vue Server-Side Rendering(SSR),这是一种适合使用 Vue.js 构建的应用程序的解决方案,它允许我们在服务器端生成 HTML,然后将其发送到客户端,这样搜索引擎就可以直接抓取到完整的 HTML 了。
使用 Vue-SSR 的优势
- 对 SEO 更加友好。由于页面是服务器端渲染的 HTML,搜索引擎可以直接抓取到完整的 HTML。
- 在首次加载时和 SEO 蜘蛛爬取时显示 dom 就绪的 HTML(即 网页中有 DOM 结构), 减少白屏时间。
使用 SSR 的原则
虽然 SSR 可以让你的 SPA 改善 SEO,但也会增加开发、文件大小、服务器配置等成本。所以,在使用 Vue-SSR 时,请考虑以下原则:
- 页面的内容需要被搜索引擎收录。
- 页面对加载速度的要求不是非常苛刻或需要被缓存。
- 部分的视图功能需要在服务端渲染。 如全站路由导航、底部公共元素(如底部导航) 等。
如果你的页面并未达到这些原则的要求,那么不需要使用 SSR。
创建 Vue-SSR 工程
我们可以在 Node 环境中使用 vue-cli 3.x 快速创建一个基于 Vue-SSR 的工程:
- ---- ------- --- ------- -- -------- - ---- --- ------ ---------- - -- --- -- -- ---------- --- --- ---
安装时,选择“Manually select features”,并选择以下插件:
- Babel
- Router
- Vuex
- CSS Pre-processors
- Linter / Formatter
- SSR
插件安装完成后,项目结构如下:
文件/文件夹 | 说明 |
---|---|
public | 存放静态资源 |
src | 存放源代码 |
├─app.js | 客户端入口文件 |
├─entry.js | 服务端入口文件 |
├─router.js | 路由配置文件 |
├─store.js | Vuex 配置文件 |
├─App.vue | Vue 入口文件,包含页面架构和全局样式 |
├─index.html | HTML 模板文件 |
├─server.js | 服务端执行文件 |
├─client.js | 客户端执行文件 |
├─template.html | 服务端模板文件 |
├─layouts | 页面布局文件夹 |
└─views | 页面文件夹 |
编写服务端代码
接下来,我们来编写一些服务端代码,用于 SSR。
准备工作
打开 entry.js
,如下修改:
------ --------- ---- ------- ------ ------- ------- -- - ----- - ---- ------- ----- - - ----------- -- ------ ------ --- ------------------------ -- -- ------ ---------------- ------ --- ----------------- ------- -- - ----------------- -- - ----- ----------------- - ----------------------------- -- --------------------------- - -------- ----- --- -- - -- ------------ ----------- ------------------------------------------- -- - -- --------------------- - ------ --------------------- ------ ------ ------------------- -- - ----------- -- - ------------- - ----------- ------------ ---------------- -- ------- -- -
我们在 entry.js
中使用 createApp
返回 app、router、store。
然后,在 server.js
中,我们能够拿到键 __context__,并且在主体部分调用 renderToStringWithContext
传递一个将被渲染的 Vue套件,一个对象表示被渲染的组件的初始状态,以及一个与上下文相关的对象。在这个对象中,我们可以传递一些信息,例如 URL,它可以被 entry.js
用来通过路由进行预载。
如果需要,您还可以将 renderToStringWithContext
包装在 Promise
中并使其异步,例如在查询中使用MongoDB获取数据。在这种情况下,您可以使用服务器端本身的状态(例如response.locals
)。此状态是每次启用页面时始终保持的,无论使用之前的缓存还是创建新的服务器实例,都会这样。
-- --------- ----- ------- - ------------------ ----- --------- - ------------------------------------------- ----- --- - --------- -- ---- ---------------- ------------------------- ------------ ----- ---- -- - ----- ------- - - ---- ------- - --------------------------- -- - ----- ---- - - --------- ----- ------ ------ ---------- ----------- ------- ------ ---- -------------------------- -------------------------------- - ----------------------------------------- ------- ---------------------------------------- ------- ------- - -------------- -- -- ----- ---- - ---- ---------------- -- -- - ---------------- ------ -- ------- -- -------------------------- --
在代码中,我们首先将服务器的入口文件加载为一个默认值(基于 entry-client.js
),此文件提供了一个“工厂”函数,它会创建一个新的 Vue 实例作为应用程序的上下文,并在 router 和 vuex 设置后返回组件、实例和路由(如果存在)。
然后,将返回的实例传递给 renderer.renderToString()
方法,并将其作为第一个参数:该应用程序实例将渲染为 HTML,它也接受一个 context
参数,该参数对象可以传递给 Renderer 以生成正确的 HTML(例如通过检查路由参数等)。
-- --------------- ------ --- ---- ----- ------ - --------- - ---- ------- ----- - ---- ------- ----- - - ----------- -- ----------- -- -------------------------- - -------------------------------------------- - ----------------- -- - -- ----------------------------------- ------------------ --
在经过处理的完整 HTML 形式,将由 renderer 的 renderToString
方法返回,传递给服务器的客户端代码将包含在 HTML 中,并在功能完整的网页脱颖而出。
编译并启动应用
使用以下命令对您的应用程序进行构建:
--- --- -----
在构建过程中,将使用 Webpack 打包所有 JavaScript 代码。它还将创建两组捆绑:一组用于在客户端上运行,另一组用于运行在 Node.js 环境中的服务器上。
启动您新的 SSR Vue 应用程序:
--- --- -----
它将启动一个 Node.js 服务器,该服务器将从您的 /dist
文件夹中提供静态文件,然后在页面渲染请求上呈现出 SSR 页面。
可以在浏览器中访问 http://localhost:8000/ 查看您的应用。
总结
SSR 可以极大地改善 SPA 的 SEO,提升用户体验。
使用 Vue-SSR 时,请首先考虑页面内容是否需要被搜索引擎抓取,是否需要展现更好的页面性能。
在编写Vue-SSR时,使用Vue CLI快速生成基础代码,并在服务端代码中使用关键的原则以及 Vue-SSR 的方法。
使用 NodeJS 将分离的前端代码和生态系统连接在一起,这完全有助于您将其作为服务进行扩展。
示例代码
该文章中,所有的示例代码均上传到了github仓库, 都可以运行, 学习调试.
来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/6465c13e968c7c53b066a323