SPA优缺点、解决单页面应用的SEO困难问题以及三种网页渲染方式

SPA特点优点缺点总结

1. 单页Web应用(SPA - Single Page web Application)

也就是说只有一个HTML文件的Web应用, 我们就称之为单页Web应用, 就称之为SPA应用

我们通过Vue开发的项目其实就是典型的SPA应用

2. SPA的特点:

  1. SPA应用只有一个HTML文件, 所有的内容其实都在这个页面中呈现的
  2. SPA应用只会加载一次HTML文件, 不会因为用户的操作而进行页面的重新加载
    当用户与应用程序交互时, 是通过动态更新页面内容的方式来呈现不同的内容

3. SPA优点:

  1. 有良好的交互体验
    不会重新加载整个网页, 只是局部更新
  2. 前后端分离开发
    前端负责页面呈现和交互, 后端负责数据
  3. 减轻服务器压力
    只用处理数据不用处理界面
  4. 共用一套后端程序代码

4. SPA缺点:

  1. SEO难度较高
    只有一个界面, 无法针对不同的内容编写不同的SEO信息
  2. 初次加载耗时多
    为实现单页Web应用功能及显示效果,需要在加载页面的时候将所有JavaScript、CSS统一加载,
    在Vue中可以使用按需加载解决初次加载耗时多

4.1 如何解决单页面应用的SEO困难问题?

解决这个问题之前首先我们需要了解常见的三种网页渲染方式

4.1.1 客户端渲染(CSR - Client Side Render)

后端只提供数据,前端做视图和交互逻辑(SPA应用就是典型的客户端渲染)

4.1.1.1 客户端渲染过程
  1. 客户端请求html (请求)
  2. 服务端返回html
  3. 客户端渲染HTML,找到依赖的JS/CSS文件
  4. 客户端请求对应的JS/CSS文件 (请求)
  5. 服务端返回对应的JS/CSS文件
  6. 客户端等待JS/CSS文件下载完成
  7. 客户端加载并初始化下载好的JS文件
  8. 客户端执行JS代码向后端请求数据 (请求)
  9. 服务端返回数据
  10. 客户端利用服务端返回的数据填充网页

最大优点:

交互体验好可以做局部更新

最大缺点:

首屏加载慢(因为要等到HTML下载完才会去下载JS/CSS, 要等到JS下载完初始化完才会去获取数据),


4.1.2 服务端渲染(SSR - Server Side Render)

后端既提供数据又提供视图和交互逻辑
也就是服务器接到客户端请求之后,找到对应的数据并根据找到的数据生成对应的视图
然后将包含数据的视图一次性发给客户端,客户端直接将渲染即可

4.1.1.2 服务端渲染过程

1.客户端请求html (请求)
2.服务端内部查找对应的html文件和数据
3.服务器内部根据数据html文件和数据生成完整网页
4.服务端返回完整网页
5.客户端渲染HTML,找到依赖的JS/CSS文件
5.客户端请求对应的JS/CSS文件 (请求)
6.客户端等待JS/CSS文件下载完成
7.客户直接展示网页

最大优点:

首屏加载快(因为服务器返回的网页已经包含数据, 所以之下载完JS/CSS就可以直接渲染)
每次请求返回的都是一个独立完成的网页, 更利于SEO

最大缺点:

网络传输数据量大


4.1.3 预渲染

无需服务器实时动态编译,采用预渲染,在构建时针对特定路由简单的生成静态HTML文件
本质就是客户端渲染, 只不过和SPA不同的是预渲染有多个界面

最大优点:

由于有多个界面, 所以更利于SEO

最大缺点:

首屏加载慢, 预编译会非常的慢

4.1.4 如何选择

1.注重SEO的新闻、电商网站,建议采用服务器端渲染
2.强交互的页面,不注重SEO,采用客户端渲染
3.两者之间, 只需改善少数页面的SEO,采用预渲染

4.2 使用预渲染解决SPA应用SEO问题

vue-cli-plugin-prerender-spa

注意点: Router必须使用history模式

4.2.1 安装
vue add prerender-spa

一直点yes

在这里插入图片描述

生成单独界面

在这里插入图片描述

注意点: 如果需要使用预渲染的插件, 那么Router的模式必须是history模式

在这里插入图片描述

默认把index.html改成了app.html,使用的时候可以自己手动更改一下

4.2.1 打包编译时的报错

因为不符合ESlint规范,解决:安装ESLINT规范格式处理好

4.3 使用vue-meta-info统一管理SEO三大标签

使用预渲染创建出了多个单独的界面,每次单独去设置单独的title、keywords以及prescription,这样不方便管理,为了方便管理这些,使用vue-meta-info

统一管理所有界面的SEO信息

vue-meta-info

4.3.1 安装
npm install vue-meta-info --save
4.3.2 导入和注册
// main.js
import MetaInfo from 'vue-meta-info'
Vue.use(MetaInfo)
4.3.3 使用
4.3.3.1 在根目录下创建vue-meta-info.js

根据需要添加的页面进行编写

// vue-meta-info.js
export default {
  recommend: {
    title: '我是recommend',
    meta: [
      {
        name: 'keyWords',
        content: '关键字1,关键字1,关键字1'
      },
      {
        name: 'description',
        content: '这是一段网页的描述1'
      }
    ]
  },
  singer: {
    title: '我是singer',
    meta: [
      {
        name: 'keyWords',
        content: '关键字2,关键字2,关键字2'
      },
      {
        name: 'description',
        content: '这是一段网页的描述2'
      }
    ]
  },
  rank: {
    title: '我是rank',
    meta: [
      {
        name: 'keyWords',
        content: '关键字3,关键字3,关键字3'
      },
      {
        name: 'description',
        content: '这是一段网页的描述3'
      }
    ]
  },
  search: {
    title: '我是search',
    meta: [
      {
        name: 'keyWords',
        content: '关键字4,关键字4,关键字4'
      },
      {
        name: 'description',
        content: '这是一段网页的描述4'
      }
    ]
  },
  account: {
    title: '我是account',
    meta: [
      {
        name: 'keyWords',
        content: '关键字5,关键字5,关键字5'
      },
      {
        name: 'description',
        content: '这是一段网页的描述5'
      }
    ]
  },
  detail: {
    title: '我是detail',
    meta: [
      {
        name: 'keyWords',
        content: '关键字6,关键字6,关键字6'
      },
      {
        name: 'description',
        content: '这是一段网页的描述6'
      }
    ]
  }
}

4.3.3.2 组件内静态使用

在这里插入图片描述

4.3.3.3 注释public下的seo三大标签

因为上面的操作完成后会自动添加,如果手动添加了,上面内容可能无法添加

5.1 通过预渲染将单页面变成了多页面会出现的问题

5.1.0 问题一

打开页面刷新后,元素的尺寸出现问题

注意点

预渲染的本质就是在打包时就"模拟浏览器"提前访问路由对应的网页, 然后将访问的结果写入到.html文件中
但是由于在打包时访问并不是通过"真实的浏览器"来访问, 所以拿不到真正的像素比
所以预渲染时写入到.html文件中的meta就是错误的
也正是因为预渲染的时候已经写入过meta标签了, 而运行的时候又会执行一次JS代码再写入一次
就导致了网页中有两个meta标签

5.1.1 解决方法

在这里插入图片描述

prerender-spa插件中的postProcess拿到对应的标签,把预渲染添加的meta标签通过正则表达式删除

5.1.2 问题2

预渲染创建了带内容的标签,也需要删除
通过正则表达式查找带内容的标签比较困难

可以通过选择器来查找,但是代码是写在配置文件vue.config.js(这是nodejs代码),
nodejs没有document这些,借助 jsdom插件可以将字符串转换成document对象,就可以使用相应的方法

5.1.2.1 jsdom

在nodejs中操作DOM

jsdom
安装

npm install jsdom --save-d

引入

// vue.config.js
const jsdom = require('jsdom')
const { JSDOM } = jsdom
module.exports = {
 pluginOptions: {
    prerenderSpa: {
      registry: undefined,
      renderRoutes: [
        '/',
        '/recommend',
        '/singer',
        '/rank',
        '/search',
        '/account',
        '/detail'
      ],
      useRenderEvent: true,
      headless: true,
      onlyProduction: true,
      postProcess: route => {
        // 预渲染内容写入之前的额外操作
        let reg = /<meta name="viewport".*user-scalable=no">/gi
        let res = route.html.match(reg)
        route.html = route.html.replace(res[1], '')

        // 1.根据字符串创建一个网页
        let html = new JSDOM(route.html)
        // 2.从创建好的网页中拿到document对象
        let dom = html.window.document
        // 3.找到对应的元素, 删除对应的元素
        let loadingEle = dom.querySelector('.container')
        dom.body.removeChild(loadingEle)

        route.html = html.serialize()
        return route
      }
    }
  }
}

匹配简单的标签使用正则,匹配复杂的标签使用选择器的方式


学习笔记,版权归Jonathan

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值