Open qiuhongbingo opened 4 years ago
开头我先介绍一下什么是 Opengraph,先看图
我在 Slack 分享了一篇微信公众号的文章,虽然我只是发送了文章链接,但 Slack 很聪明地帮我把文章标题/描述/封面图都读取出来了,同样的,大部分社交平台都是这么聪明,像 Facebook/Twitter/微博/微信等等都这么智能,这就是 Opengraph 的成果,那么这是怎么做到的
我立马就在 chrome 查看了这篇公众号文章的 HTML 源码,发现 head 里有几处 meta 标签,分别定义好了文章的基本信息,嗯,原来社交平台这么聪明就是因为这里啊
这里我也附上 Facebook 官方 Opengraph 文档 以及 调试工具
到这里,是不是觉得我这篇文章就大结局了,这也太水了吧,不就是在 HTML 里加几个 meta 标签就好了嘛,还有什么好讲的???
客官莫急莫急,容我解释一下
这篇文章我能写到这里,正是因为单页应用在处理这种 meta 标签是要绕绕路子的,要是传统的网页开发或者 SSR,哪来这么多屁事
众所周知,SPA 在 SEO 方面差强人意,先看图,这是一个 SPA 的页面,内容很丰富
但是当我们查看源代码,啊欧,发现根本没有文章列表的相关内容
原因是这样,SPA 靠 JavaScript 来填充页面的内容,就是那个大家都很熟悉的叫 #app 的 div 小朋友,这个小朋友长什么样全听 JavaScript 的,而浏览器只知道有小朋友这个人,不知道长什么样。那么当搜索引擎或者社交平台来到这个页面,空空如也,自然也就不帮你做内容收录和展示了
如果你的应用的所有页面都可以通用一个 meta 介绍,那么可以直接在应用的 index.html 加上 meta 即可
但大部分情况是页面都有不同的 meta,就以上面的文章页面来说,每篇文章的 meta 都需要依靠 JavaScript 单独设置,而 vue-meta 这个包就是解决这个问题的好帮手,使用方法也是很简单
export default { metaInfo: { meta: [ { property: 'og:type', content: 'article' }, { property: 'og:title', content: 'xxx' }, { property: 'og:description', content: 'xxx' }, { property: 'og:image', content: 'https://xxx.png' } ] } }
但这样还是不够,浏览器依旧不知道小朋友长什么样,莫急,我们继续往下走
既然 vue-meta 只能帮一点忙,剩下就全靠 Prerender 预渲染了。预渲染的原理简单说,就是在 npm run build 的阶段,让浏览器打开你的页面,看清小朋友长什么样,并把样貌画下来,这样搜索引擎和社交平台也就知道了小朋友的样貌
明白了原理,我们开始用上 Prerender,本文以 vue-cli 的项目举例
vue.config.js 需要做的
const path = require('path') const PrerenderSPAPlugin = require('prerender-spa-plugin') const Renderer = PrerenderSPAPlugin.PuppeteerRenderer module.exports = { configureWebpack: () => { if (process.env.NODE_ENV !== 'production') return return { plugins: [ new PrerenderSPAPlugin({ staticDir: path.join(__dirname, 'dist'), // 这里配好你需要预渲染的页面,对应 vue-router 的路径 routes: [ '/paper', ], renderer: new Renderer({ // 这里定义 Prerender 插件开始画样貌的信号 renderAfterDocumentEvent: 'render-event' }) }) ] } } }
main.js
new Vue({ router, store, render: (h) => h(App), // 这里就是触发 Prerender 插件开始画样貌 mounted: () => document.dispatchEvent(new Event('render-event')) }).$mount('#app')
到这里,代码就改完了,但最终打包上线我也遇到一些坑,顺便分享一下
如果你的应用也是用 Docker 打包,那么大概率你的镜像体积会变大一些,打包速度也会变慢,受限于 Prerender 依赖 chrome 内核,大陆环境下不容易获取
这里我推荐分为基础镜像和业务镜像单独打包,基础镜像可以使用 buildkite/puppeteer:latest,有 chromium 环境和 yarn 环境
docker/base/Dockerfile
FROM buildkite/puppeteer:latest WORKDIR /app COPY package.json ./ RUN yarn install RUN yarn cache clean
基于基础镜像再去构建业务镜像,对打包速度和体积都有好处
docker/beta/Dockerfile
# build stage FROM xxx-base:latest as build-stage WORKDIR /app COPY . . RUN npm run build-beta # production stage FROM nginx:alpine as production-stage COPY --from=build-stage /app/dist /usr/share/nginx/html COPY docker/beta/nginx.conf /etc/nginx/nginx.conf EXPOSE 8080 CMD ["nginx", "-g", "daemon off;"]
最后祭出 Makefile
NAME = xxx REGISTRY = aaa BETA_REGISTRY = bbb base: echo building ${NAME}-base:latest cp docker/base/Dockerfile . docker build -t ${BETA_REGISTRY}/${NAME}-base:latest . rm Dockerfile docker push ${BETA_REGISTRY}/${NAME}-base:latest beta: base echo building ${NAME}:beta cp docker/beta/Dockerfile . docker build -t ${BETA_REGISTRY}/${NAME}:beta . rm Dockerfile docker push ${BETA_REGISTRY}/${NAME}:beta prod: base echo building ${NAME}:master cp docker/prod/Dockerfile . docker build -t ${REGISTRY}/${NAME}:master . rm Dockerfile docker push ${REGISTRY}/${NAME}:master
哈!你是不是也不知道什么是 Opengraph
开头我先介绍一下什么是 Opengraph,先看图
我在 Slack 分享了一篇微信公众号的文章,虽然我只是发送了文章链接,但 Slack 很聪明地帮我把文章标题/描述/封面图都读取出来了,同样的,大部分社交平台都是这么聪明,像 Facebook/Twitter/微博/微信等等都这么智能,这就是 Opengraph 的成果,那么这是怎么做到的
我立马就在 chrome 查看了这篇公众号文章的 HTML 源码,发现 head 里有几处 meta 标签,分别定义好了文章的基本信息,嗯,原来社交平台这么聪明就是因为这里啊
这里我也附上 Facebook 官方 Opengraph 文档 以及 调试工具
到这里,是不是觉得我这篇文章就大结局了,这也太水了吧,不就是在 HTML 里加几个 meta 标签就好了嘛,还有什么好讲的???
客官莫急莫急,容我解释一下
SPA 单页面应用的缺点浮出水面
这篇文章我能写到这里,正是因为单页应用在处理这种 meta 标签是要绕绕路子的,要是传统的网页开发或者 SSR,哪来这么多屁事
众所周知,SPA 在 SEO 方面差强人意,先看图,这是一个 SPA 的页面,内容很丰富
但是当我们查看源代码,啊欧,发现根本没有文章列表的相关内容
原因是这样,SPA 靠 JavaScript 来填充页面的内容,就是那个大家都很熟悉的叫 #app 的 div 小朋友,这个小朋友长什么样全听 JavaScript 的,而浏览器只知道有小朋友这个人,不知道长什么样。那么当搜索引擎或者社交平台来到这个页面,空空如也,自然也就不帮你做内容收录和展示了
vue-meta 来帮忙
如果你的应用的所有页面都可以通用一个 meta 介绍,那么可以直接在应用的 index.html 加上 meta 即可
但大部分情况是页面都有不同的 meta,就以上面的文章页面来说,每篇文章的 meta 都需要依靠 JavaScript 单独设置,而 vue-meta 这个包就是解决这个问题的好帮手,使用方法也是很简单
但这样还是不够,浏览器依旧不知道小朋友长什么样,莫急,我们继续往下走
vue-meta 喊 prerender-spa-plugin 一起来帮忙
既然 vue-meta 只能帮一点忙,剩下就全靠 Prerender 预渲染了。预渲染的原理简单说,就是在 npm run build 的阶段,让浏览器打开你的页面,看清小朋友长什么样,并把样貌画下来,这样搜索引擎和社交平台也就知道了小朋友的样貌
明白了原理,我们开始用上 Prerender,本文以 vue-cli 的项目举例
vue.config.js 需要做的
main.js
到这里,代码就改完了,但最终打包上线我也遇到一些坑,顺便分享一下
预渲染的副作用
如果你的应用也是用 Docker 打包,那么大概率你的镜像体积会变大一些,打包速度也会变慢,受限于 Prerender 依赖 chrome 内核,大陆环境下不容易获取
这里我推荐分为基础镜像和业务镜像单独打包,基础镜像可以使用 buildkite/puppeteer:latest,有 chromium 环境和 yarn 环境
docker/base/Dockerfile
基于基础镜像再去构建业务镜像,对打包速度和体积都有好处
docker/beta/Dockerfile
最后祭出 Makefile
文末不禁想唱歌~这里的前端路十八弯~