Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

浅谈:SPA 及其 SEO 优化方案 #36

Open
jtwang7 opened this issue Nov 11, 2021 · 0 comments
Open

浅谈:SPA 及其 SEO 优化方案 #36

jtwang7 opened this issue Nov 11, 2021 · 0 comments

Comments

@jtwang7
Copy link
Owner

jtwang7 commented Nov 11, 2021

参考文章:

前后端分离

前后端耦合导致的问题

传统的 Web 前后端开发:前端编写页面,然后将页面交付给后端,后端再将页面集成到项目中去 (与后端数据及业务逻辑耦合)。

  • 对于后端来说,不仅要写后端逻辑,还得集成前端页面,页面一旦修改,就需要同步修改相应的集成逻辑。
  • 对于前端来说,不是容易看到页面真正渲染出来的样子,不利于开发调试,开发效率低下。

概念

由于前后端的高耦合,使得任何一方的变化都可能会影响到另一方,针对类似于上述的一些问题,前后端分离的思想便应运而生。
前后端分离基本概念:前后端根据 AJAX 接口进行数据的交互 (目前常见的是后端直接将数据以 JSON 的格式返回给前端),前端根据后端服务器返回的数据,操作 DOM 进行页面渲染。

优点

  • 分工明确,前后端各司其职,后端专注业务逻辑和功能的实现,前端专注页面设计。
  • 接口明确,并行开发,在后端接口没有实现好之前,前端完全可以自己通过 Node.js 的 Express 和 koa 等的 Web 框架模拟接口,提供测试数据。
  • 提高开发效率,一定程度上减少了前后端的沟通成本。

在前后端分离中,后端一般提供 RESTful API,常将数据以 JSON 格式返回;而前端则一般使用 SPA 来进行页面开发。

SPA (Single Page Application, 单页面应用)

概念

SPA 是一种网络应用程序或网站的模型,它通过监听 url 变化,动态重写当前页面与用户交互,这种方法避免了页面之间切换时需要请求 html 的额外开销。在单页应用中,所有必要的代码(HTML、JavaScript和CSS)都通过一次性请求的单个页面进行加载和检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面,页面在任何时间点都不会重新加载,也不会将控制转移到其他页面。

注:SPA 和 MPA 都是 Application,而不单单是一个 Page。一个网络应用程序中包含多个页面,因此 SPA 和 MPA 才存在页面切换这一说法。

SPA 与 MPA 的区别

MPA 多页面应用中,每个页面都是一个主页面,都是独立的。当我们在切换访问另一个页面的时候,都需要重新向服务器请求 html、css、js 文件并加载。

单页面应用(SPA) 多页面应用(MPA)
组成 一个主页面和多个页面片段 多个主页面
刷新方式 局部刷新 整页刷新
url模式 哈希模式 历史模式
SEO搜索引擎优化 难实现,可使用SSR方式改善 容易实现
数据传递 容易 通过url、cookie、localStorage等传递
页面切换 速度快,用户体验良好 切换加载资源,速度慢,用户体验差
维护成本 相对容易 相对复杂

优点

  • 应用内页面间切换速度快:内容的改变不需要重新请求资源并重新加载整个页面。
  • 具有桌面应用的即时性、网站的可移植性和可访问性。
  • 良好的前后端分离,分工更明确:SPA 只需要关注前端逻辑,通过 AJAX 请求来动态获取展示数据。后端程序只需要提供API,完全不用管客户端到底是Web界面还是手机等。

为什么页面切换快?

  1. 减少了 html 请求:页面每次切换跳转时,不需要处理 html 文件的请求,节约了很多 HTTP 发送时延。
  2. 局部渲染:SPA 处理页面切换,主要通过 js 监听 url 变化(前端路由),来局部动态渲染,不会在每次页面切换时发生整页的重载。

缺点

  • 首屏渲染速度很慢:用户首次加载需要先下载 SPA 框架及应用程序的代码,然后在空 html 中通过 js 构建文档树,最后渲染成页面。
  • 不利于 SEO:搜索引擎的爬虫能扒取初始 html 里的内容,很少能支持扒取页面加载后 js 动态渲染生成的内容。而上述我们也提到,SPA 应用的页面,在首次请求包时,服务端返回的打包内容中,html 是空的,需要依赖包中的 js 来动态生成页面 DOM。但后生成的内容搜索引擎不识别,也就不会给一个好排名,会导致单页应用做出来的网页在搜索引擎上的排名差。

SEO (Search Engine Optimization, 搜索引擎优化)

概念

SEO 是一种利用搜索引擎的运作规则来提高网站在搜索引擎中某些关键词的搜索结果排名的优化方案。
搜索引擎运作规则:

  • 如何抓取网站页面
  • 如何索引
  • 如何根据特定的关键字展现搜索结果排序等

作用

SEO 可以提高网站的权重,增强搜索引擎友好度,以达到提高排名,增加流量,改善(潜在)用户体验,促进销售的作用。

分类

SEO 可分为白帽SEO和黑帽SEO。白帽SEO,起到了改良和规范网站设计的作用,使网站对搜索引擎和用户更加友好,并且网站也能从搜索引擎中获取合理的流量,这是搜索引擎鼓励和支持的。黑帽SEO,利用和放大搜索引擎政策缺陷来获取更多用户的访问量,这类行为大多是欺骗搜索引擎,一般搜索引擎公司是不支持与鼓励的。

白帽 SEO 优化

  1. 对网站的标题、关键字、描述精心设置,反映网站的定位,让搜索引擎明白网站是做什么的;
  2. 网站内容优化:内容与关键字的对应,增加关键字的密度;
  3. 在网站上合理设置 Robots.txt 文件;
  4. 生成针对搜索引擎友好的网站地图;
  5. 增加外部链接,到各个网站上宣传。

前端 SEO 的优化事项

  1. 网站结构布局优化:提倡扁平化结构,用户浏览和爬虫获取都是从上到下,从外到内的访问,因此要把重要的内容放在前面,方便爬虫获取关键信息,同时也给用户良好的体验。
  2. 网页代码优化:合理使用 title,description 和 keywords 等属性,语义化书写 HTML 代码(多利用 HTML 语义标签),图片等可以添加 alt 属性进行说明。这些操作都会让爬虫更好的识别和获取网站的关键信息。
  3. 网站性能优化:尽可能利用手段加快网页的加载速度,例如减少 http 请求,压缩图片,利用浏览器缓存等。这样做的目的是增加用户体验,增大用户在页面的停留时间,同时也防止网页加载超时导致爬虫离开。

SPA 的 SEO 优化方案

  1. SSR 服务端渲染
    将组件或页面通过服务器生成 html,再返回给浏览器,如 nuxt.js,next.js 等。
  2. 静态化
    目前主流的静态化主要有两种:(1)一种是通过程序将动态页面抓取并保存为静态页面,这样的页面的实际存在于服务器的硬盘中(2)另外一种是通过WEB服务器的 URL Rewrite的方式,它的原理是通过web服务器内部模块按一定规则将外部的URL请求转化为内部的文件地址,一句话来说就是把外部请求的静态地址转化为实际的动态页面地址,而静态页面实际是不存在的。这两种方法都达到了实现URL静态化的效果
  3. 使用Phantomjs针对爬虫处理
    原理是通过 Nginx 配置,判断访问来源是否为爬虫,如果是则搜索引擎的爬虫请求会转发到一个 node server,再通过 PhantomJS 来解析完整的 HTML,返回给爬虫。

CSR 服务端渲染

通常我们采用的渲染方案是 CSR 客户端渲染(Client Side Rendering):

  1. 客户端:在浏览器地址中输入 url
  2. 客户端:浏览器向服务端请求页面资源 -> 服务端:接受请求,并返回(空的)HTML页面。此处空页面指的是 SPA 应用中页面的 root 节点,实际页面还包含了 js 代码。
  3. 客户端:接收得到的 HTML 页面,并渲染。(此时展示空白页面,因为还没有动态生成内容)
  4. 客户端:解析 HTML 页面,读取到 script 标签后,再次向服务端发送请求。 -> 服务端:接受请求,返回 js 文件。
  5. 客户端:执行 js 代码,渲染页面。
    5.1. 客户端:可能会在渲染过程中,再次发送 ajax 请求,获取页面初始化需要的数据。 -> 服务端:接受请求,返回数据
    5.2. 客户端:获取数据,再次渲染页面

CSR 整体流程:

SSR 服务端渲染

SSR 服务端渲染是指将单页应用(SPA)在服务器端渲染成 HTML 片段,发送到浏览器,然后交由浏览器为其绑定状态与事件,成为完全可交互页面的过程。

服务端渲染涉及到了 Node 中间层,因此需要一些能在 Node.js 上运行的框架支撑。

  1. 客户端:在浏览器地址中输入 url
  2. 客户端:浏览器向服务端请求页面资源
  3. Node 中间层:注意,此时请求会被 Node 服务器获取,Node 服务器接收到请求后,通过当前 url 路由分析,找到匹配的路由组件,然后判断当前路由组件中是否需要请求数据,若需要则会向业务接口服务器请求数据资源,然后在 Node 服务器中完成初步的页面渲染,返回 HTML (此时已在 Node 服务端完成了初步的 DOM 搭建,root 节点中是有内容的)
  4. 客户端:浏览器接收 HTML 页面,并渲染。(会渲染得到服务端已经初步搭建好的 DOM 树)
  5. 客户端:解析 HTML 页面,遇到 script 标签时,再次向服务器发送请求。-> Node 服务器:接受请求并返回对应的 js 文件
  6. 客户端:执行 js 代码,渲染页面 (此时 js 主要处理一些事件绑定的逻辑)

之后的页面交互中,若客户端要发送 ajax 请求数据,会先将请求发送到 Node 中间层,Node 服务器会接受 ajax 请求,并代理到业务接口服务器,服务器返回数据给 Node,Node 再将数据返回给客户端,进行页面渲染

Node 服务端只负责首次“渲染”(真正意义上,只有浏览器才能渲染页面,服务端首次渲染其实是生成 HTML 内容),然后返回给客户端,客户端接管页面交互(事件绑定等逻辑),之后客户端路由切换时,直接通过 JS 代码来显示对应的内容,不再需要服务端渲染(只有页面刷新时会需要)。当发生数据请求时,Node 服务端会作为代理服务器的角色,接收和转发请求和响应。

优势

  • 更快的首屏加载速度:无需等待 JavaScript 完成下载且执行才显示内容。Node 服务端会根据请求直接构建对应路由组件的 DOM 树,并将初步构建完成的页面返回给前端。前端解析渲染这颗 DOM 树,就能更快速地看到完整渲染的页面,有更好的用户体验。
  • 更友好的 SEO:爬虫可以直接抓取渲染之后的页面,CSR 首次返回的 HTML 文档中,是空节点(root),不包含内容,爬虫就无法分析你的网站有什么内容,所以就无法给你好的排名。而 SSR 返回渲染之后的 HTML 片段,内容完整,所以能更好地被爬虫分析与索引。

缺点

  • 对服务器性能消耗较高:HTML 内容需要在服务端生成
  • 项目复杂度变高,出问题需要在前端、node、后端三者之间找
  • 需要考虑 SSR 机器的运维、申请、扩容,增加了运维成本(可以通过 Serverless 解决)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant