PWA 如何实现 SSR?

阅读时长 6 min read

前言

PWA(Progressive Web App)已经成为了前端开发的一个热门话题,它可以让我们的 Web 应用更像是一个本地应用。而实现 PWA 的一个重要手段是 Service Worker。但是,Service Worker 只能在浏览器端运行,无法直接在服务器端运行。这就导致了一个问题:如何实现 PWA 的 SSR(Server-Side Rendering)?

在本文中,我们将探讨如何实现 PWA 的 SSR,以及一些实现的技巧和注意事项。

SSR 简介

SSR 是指在服务器端渲染页面,将最终渲染好的页面发送给客户端。相对于传统的 SPA(Single-Page Application),SSR 的主要优点是:

  • 更好的 SEO(Search Engine Optimization):由于搜索引擎对于 JavaScript 的支持并不完美,对于 SPA 而言,搜索引擎可能无法正确地解析页面内容,从而导致 SEO 效果不佳。而 SSR 可以在服务器端生成静态 HTML,搜索引擎可以直接解析这些 HTML,从而提高了 SEO 的效果。
  • 更快的首屏渲染速度:由于 SSR 可以在服务器端生成 HTML,客户端只需要下载静态资源(如 CSS 和 JavaScript)即可,无需等待 JavaScript 加载和执行,从而提高了首屏渲染速度。
  • 更好的可访问性:对于一些无法执行 JavaScript 的设备或用户,SSR 可以提供更好的可访问性。

PWA 的 SSR 实现方式

实现 PWA 的 SSR 有很多种方式,这里我们介绍一种比较常用的方式:使用 prerender-spa-plugin。

prerender-spa-plugin 简介

prerender-spa-plugin 是一个 Webpack 插件,它可以在构建时预渲染页面,并将渲染好的 HTML 保存到文件中。当客户端请求这些页面时,服务器端直接返回这些 HTML 文件,从而实现 SSR。

实现步骤

下面我们来看一下具体的实现步骤。

1. 安装依赖

首先,我们需要安装 prerender-spa-plugin 和 vue-server-renderer:

2. 配置 Webpack

在 Webpack 配置文件中,我们需要添加 prerender-spa-plugin 的配置。具体配置如下:

其中,staticDir 是静态文件目录,routes 是需要预渲染的页面路由,renderer 是渲染器。这里我们使用了 PuppeteerRenderer,它可以使用 Puppeteer 来预渲染页面。

3. 配置服务器端

在服务器端,我们需要使用 vue-server-renderer 来渲染页面。具体实现如下:

其中,createBundleRenderer 是用来创建渲染器的函数,bundle 是服务器端渲染的 bundle 文件,clientManifest 是客户端渲染的 manifest 文件,template 是 HTML 模板。在 server.get('*') 中,我们使用渲染器来渲染页面,并将生成的 HTML 返回给客户端。

注意事项

实现 PWA 的 SSR 过程中,有一些需要注意的事项:

  • Service Worker 只能在浏览器端运行,无法直接在服务器端运行。因此,在 SSR 期间,Service Worker 并不会执行,这意味着我们无法在 SSR 期间缓存一些资源。
  • 在 SSR 期间,我们需要将所有的资源(包括 CSS 和 JavaScript)都内联到 HTML 中,这样才能保证页面能够正确地渲染。由于内联的 CSS 和 JavaScript 会增加 HTML 的体积,因此需要注意 HTML 的大小。
  • 在 SSR 期间,我们需要将所有的链接替换为绝对路径,否则客户端会尝试从服务器端下载这些资源,从而导致一些错误。

示例代码

完整的示例代码可以在 GitHub 上找到。

Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/67d8e53da941bf7134007cf1