预加载 prerender-spa-plugin

1,555 阅读1分钟

这是在vue-cli4 + vue 3.0的基础下实现的预加载。

ssr

优势:

1.更好的 SEO,利于搜索引擎抓取页面信息。

2.加快首屏渲染

预加载

优势:可以实现ssr上面的优势

缺点:SEO 优化不完整

原理

预加载原理就是项目build的时候运行 谷歌浏览器 并发起接口请求,获取接口数后渲染页面,把已渲染好的 dom页面 保存下来,直接用于服务器访问。

安装 prerender-spa-plugin (建议使用 v3.4.0)

npm i prerender-spa-plugin

在vue.config文件中配置

...
const PrerenderSPAPlugin = require("prerender-spa-plugin");

...

module.exports = {
  ...
  // 预加载
  configureWebpack: config => {
    if (process.env.NODE_ENV !== 'production') return; // router 4.0未兼容
    return {
      plugins: [
        new PrerenderSPAPlugin({
          // 生成文件的路径,也可以与webpakc打包的一致。
          // 下面这句话非常重要!!!
          // 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
          staticDir: path.join(__dirname, "dist"),
          // 对应自己的路由文件
          routes: [
            "/",
            "/service",
            "/product",
            "/about",
            "/about/newscolum",
            "/about/enterprise",
            "/about/message",
            "/cooperation"
          ],

          // 代理接口配置
          server: {
            port: 8081,
            proxy: {
              "/api": {
                target: "https://www.xxxxxx.com/",
                changeOrigin: true,
                secure: true
              }
            }
          },
          postProcess (renderedRoute) {
            // 忽略重定向 redirects
            renderedRoute.route = renderedRoute.originalRoute;
            return renderedRoute;
          },
          // 这个很重要,如果没有配置这段,也不会进行预编译
          renderer: new Renderer({
            inject: {
              foo: 'bar'
            },
            // 渲染时显示浏览器窗口。
            headless: false,
            // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
            renderAfterDocumentEvent: "render-event"
          })
        }),
      ],
    };
  }
  
}

router.js 路由配置

vue-router v4.0.0 路由配置模式必须选择 createWebHistory 模式

// vue-router v4.0.0
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";

const routes: Array<RouteRecordRaw> = [
  {
    path: "/",
    name: "/",
    component: () => import("@/pages/index/index.vue")
  },
  ...
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

export default router;

在需要预加载页面上的 mounted 生命周期中加上对应 renderAfterDocumentEvent

  ...
  mounted() {
    document.dispatchEvent(new Event("render-event"));
  },
  ...

最终 npm run build 出来的结果是如下: