Как мы все знаем, одностраничное приложение Vue SPA не дружит с SEO, конечно, есть соответствующие решения.По поиску информации есть примерно следующие четыре метода. (Я использовал только первый и третий варианты)
1. Развертывание приложения рендеринга сервера Nuxt (рендеринг сервера SSR)
О рендеринге сервера: введение на официальном веб-сайте Vue, есть требования к версиям Vue, есть определенные требования к серверу, и необходимо поддерживать среду NodeJS.
Компромиссы использования SSR:
Ограниченный условиями разработки, специфичный для браузера код может использоваться только в некоторых хуках жизненного цикла; некоторые внешние библиотеки могут потребовать специальной обработки для запуска в приложениях, отображаемых на сервере;
Требования к среде и развертыванию выше, и требуется рабочая среда сервера Node.js;
В случае большого трафика подготовьте соответствующую нагрузку на сервер и разумно используйте стратегию кэширования.
Преимущество:
Лучшее SEO, так как сканеры поисковых систем могут напрямую просматривать полностью обработанные страницы; Более быстрое получение контента, особенно для медленных сетевых условий или медленных устройств.
Недостаточно: (яма встречалась в развитии)
1. Один набор кода и два набора сред выполнения вызовут различные проблемы. Например, на стороне сервера нет объектов окна и документа. Метод обработки заключается в повышении суждения. Если это на стороне клиента, он будет быть казненным:
if(process.browser){
console.log(window);
}
Обратитесь к пакетам npm с операциями dom, например: wowjs, вы не можете использовать метод импорта, используйте:
if (process.browser) {
var { WOW } = require('wowjs');
require('wowjs/css/libs/animate.css');
}
2. Следующий метод asyncData, получить данные перед инициализацией страницы, но только для вызова компонента страницы:
// 并发加载多个接口:
async asyncData ({ app, query }) {
let [resA, resB, resC] = await Promise.all([
app.$axios.get('/api/a'),
app.$axios.get('/api/b'),
app.$axios.get('/api/c'),
])
return {
dataA: resA.data,
dataB: resB.data,
dataC: resC.data,
}
}
3. Если вы используете синтаксис v-if, вы также можете столкнуться с этой ошибкой при онлайн-развертывании:
Ошибка при инициализации приложения DOMException: не удалось выполнить «appendChild» на «узле»: этот тип узла не поддерживает этот метод. в Object.We [как appendChild] Согласно выпуску № 1552 на github nuxt, измените синтаксис v-if на v-show.
2. Развертывание статического приложения Nuxt
Динамическая маршрутизация игнорируется, когда NUXT.JS выполняет статический пакет генерирования.
-| pages/
---| index.vue
---| users/
-----| _id.vue
Если вам нужна динамическая маршрутизация, вам нужно сначала сгенерировать статическую страницу, вам нужно указать значение параметра динамической маршрутизации и настроить его в массиве маршрутов.
// nuxt.config.js
module.exports = {
generate: {
routes: [
'/users/1',
'/users/2',
'/users/3'
]
}
}
Запустите пакет, чтобы увидеть упакованную страницу.
Но что, если значение динамического параметра маршрута будет динамическим, а не фиксированным?
используйте функцию, которая возвращает тип объекта Promise; Используйте функцию, обратный вызов которой callback(err, params).
// nuxt.config.js
import axios from 'axios'
export default {
generate: {
routes: function () {
return axios.get('https://my-api/users')
.then((res) => {
return res.data.map((user) => {
return {
route: '/users/' + user.id,
payload: user
}
})
})
}
}
}
Теперь полезная нагрузка, к которой мы можем получить доступ из /users/_id.vue, выглядит так:
async asyncData ({ params, error, payload }) {
if (payload) return { user: payload }
else return { user: await backend.fetchUser(params.id) }
}
Если ваш динамический маршрут имеет много параметров, таких как сведения о продукте, их может быть несколько десятков тысяч. Интерфейс необходим для возврата всех идентификаторов, а затем для обхода идентификаторов при упаковке и локальной упаковки.Если продукт изменен или удален с полки, его необходимо переупаковать.В случае большого количества упаковка также очень медленно, что очень нереально.
Преимущество:
Чистые статические файлы, сверхбыстрая скорость доступа; По сравнению с SSR здесь не возникает проблема загрузки сервера; Статические веб-страницы не должны быть взломаны и более безопасны.
недостаточный:
Неприменимо, если имеется много параметров динамической маршрутизации.
3. Prerender prerender-spa-plugin
Если вы используете его только для улучшения SEO нескольких маркетинговых страниц (например, /, /about, /contact и т. д.), то вам, вероятно, потребуется предварительный рендеринг. Вместо использования веб-сервера для динамической компиляции HTML «на лету» используйте предварительный рендеринг, чтобы просто создавать статические файлы HTML для определенных маршрутов во время сборки. Преимущество заключается в том, что проще настроить предварительные рендеры и ваш интерфейс может быть полностью статическим сайтом.
1
$ cnpm install prerender-spa-plugin --save
vue cli 3 конфигурация vue.config.js:
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
const path = require('path');
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV !== 'production') return;
return {
plugins: [
new PrerenderSPAPlugin({
// 生成文件的路径,也可以与webpakc打包的一致。
// 下面这句话非常重要!!!
// 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
staticDir: path.join(__dirname,'dist'),
// 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
routes: ['/', '/product','/about'],
// 这个很重要,如果没有配置这段,也不会进行预编译
renderer: new Renderer({
inject: {
foo: 'bar'
},
headless: false,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
renderAfterDocumentEvent: 'render-event'
})
}),
],
};
}
}
Добавить: в main.js:
new Vue({
router,
render: h => h(App),
mounted () {
document.dispatchEvent(new Event('render-event'))
}
}).$mount('#app')
Примечание. Режим: «История» должна быть установлена в роутере.
После упаковки вы можете увидеть файл и запаковать его из папки /index.html, например: about => about/index.html, который содержит html-контент.
Преимущество:
Изменения небольшие, добавлен плагин;
недостаточный:
Нельзя использовать динамическую маршрутизацию; Подходит только для проектов с небольшим количеством страниц, при сотнях страниц упаковка будет очень медленной;
4. Phantomjs работает со сканерами
Phantomjs — это безголовый браузер на основе ядра webkit, то есть в нем нет UI-интерфейса, то есть это браузер, но операции, связанные с человеком, такие как нажатие и перелистывание страниц в нем, требуют разработки и реализации программы.
Хотя «PhantomJS объявил о прекращении разработки», отношение SEO к Vue было удовлетворено.
Это решение на самом деле является обходным механизмом. Принцип заключается в том, чтобы определить, является ли исходный UA доступа доступом сканера через конфигурацию Nginx. Если это так, перенаправьте запрос сканера поисковой системы на сервер узла, а затем используйте PhantomJS для анализа полный HTML, возвращенный сканеру.
Чтобы установить глобальные фантомы, локальные экспрессы, проверьте:
$ phantomjs spider.js 'www.baidu.com' Если вы видите толчок HTML в командной строке, поздравляю, вы завоевали фантоми.
После запуска или использования postman для добавления значения User-Agent в Baiduspider в заголовке запроса эффект тот же.
Развертывание запущено
Чтобы установить конфигурацию узла, pm2, phantomjs и nginx онлайн:
upstream spider_server {
server localhost:3000;
}
server {
listen 80;
server_name example.com;
location / {
proxy_set_header Host $host:$proxy_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
if ($http_user_agent ~* "Baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator|bingbot|Sosospider|Sogou Pic Spider|Googlebot|360Spider") {
proxy_pass http://spider_server;
}
}
}
Преимущество:
Код проекта вообще не нужно менять, его можно разработать по оригинальному SPA, а стоимость разработки SSR не должна быть слишком маленькой; Это лучший выбор для проектов, которые уже были разработаны с помощью SPA.
недостаточный:
Для развертывания требуется поддержка узлового сервера;
Доступ сканера медленнее, чем доступ к веб-странице, потому что рассчитанная по времени загрузка ресурса завершается до возврата к сканеру;
Если вы вызываете большое количество романов Baidu macrower, вы вызовете проблему с загрузкой сервера, и решение состоит в том, чтобы определить IP-адрес доступа, является ли это IP-адресом официальной рептилии Baidu.
Суммировать
Если вы создаете масштабный веб-сайт, например торговый центр, не стесняйтесь обращаться непосредственно к SSR-серверу для рендеринга.Конечно, вас ждут соответствующие ямы.Комьюнити более зрелое и английский язык лучше. Все проблемы можно легко решить.
Если это просто личный блог, официальный сайт компании, можно использовать остальные три.