82.使用vue后怎么針對搜索引擎做SEO優化?


什么是SEO

搜索引擎優化(Search engine optimization,簡稱SEO),指為了提升網頁在搜索引擎自然搜索結果中(非商業性推廣結果)的收錄數量以及排序位置而做的優化行為,是為了從搜索引擎中獲得更多的免費流量,以及更好的展現形象。

SEM(Search engine marketing,搜索引擎營銷),則既包括了SEO,也包括了付費的商業推廣優化。

本文主要介紹的是前端如何在代碼上做SEO以及單頁項目如何實現SEO。

搜索引擎工作原理

要了解SEO,首先得了解搜索引擎的工作原理,其原理是比較復雜,流程簡化如下:

爬蟲抓取網頁內容

一般爬蟲抓取頁面內容是先從一個頁面出發,從中提取出其他頁面的鏈接,然后當作下一個請求的對象,一直重復這個過程。所以要有良好的SEO,需要你在各大網站上擁有外鏈,這樣會提高你的網站被搜索引擎爬蟲的幾率。

分析網頁內容

爬蟲拿到HTML之后,就會對其內容進行分析。一般需要進行去雜、分詞、簡歷索引數據庫。什么是索引數據庫呢?簡單地說就是記錄一個詞在哪些文檔中出現、出現次數、出現的位置等等。為什么要簡歷索引數據庫呢?是為了快速查找。

搜索和排序

搜索會根據你輸入的關鍵詞,分別查詢其對應的索引數據庫,並對結果進行處理和排序。

前端編碼的SEO

網站結構

網站結構要清晰。一般網站的結構是樹形的,一般分為三個層次:首頁 → 頻道頁(列表頁) → 文章頁(詳情頁)。

網站的結構要扁平。結構層數越少越好,一般不要超過三層,搜索引擎一般到了第三層就不想繼續深入地爬取了。多數的網站,例如掘金、雪球等,他們的網站結構是兩層,他們的首頁和頻道頁是同一個頁面。

導航

頁面應該要有簡明的導航。導航可以讓搜索引擎知道網站的結構,也可以讓搜索引擎知道當前頁面在網站結構所在的層次。 建議:

每一個頁面都包含導航。

對於內容較多的網站可以采用面包屑導航。

鏈接使用文字鏈接,如果是圖片,則通過alt屬性告知搜索引擎鏈接的指向。

規范的URL

規范、簡單、易理解的URL能讓搜索引擎更好地抓取內容。建議:

同一個頁面,只對應一個url 。多個url可以采用301進行重定向。

url可以反應網頁內容以及網站結構信息。例如www.a.com/blog、www.a.com/blog/123、www.a.com/article。

url盡量簡短。

盡量減少動態url中包含的變量參數。

提交Sitemap

Sitemap 可通知搜索引擎他們網站上有哪些可供抓取的網頁,以便搜索引擎可以更加智能地抓取網站。

robot.txt

搜索引擎爬行網站第一個訪問的文件就是robots.txt。在這個文件中聲明該網站中不想被蜘蛛訪問的部分,這樣,該網站的部分或全部內容就可以不被搜索引擎訪問和收錄了,或者可以通過robots.txt指定使搜索引擎只收錄指定的內容。

合理的HTTP返回碼

不同的返回碼,搜索引擎的處理邏輯是不一樣的。

如果站點臨時關閉,當網頁不能打開時,建議使用503狀態。503可以告知百度spider該頁面臨時不可訪問,請過段時間再重試。

如果百度spider對您的站點抓取壓力過大,請盡量不要使用404,同樣建議返回503。這樣百度spider會過段時間再來嘗試抓取這個鏈接,如果那個時間站點空閑,那它就會被成功抓取了。

有一些網站希望百度只收錄部分內容,例如審核后的內容,累積一段時間的新用戶頁等等。在這種情況,建議新發內容暫時返回403,等審核或做好處理之后,再返回正常狀態的返回碼。

站點遷移,或域名更換時,請使用301返回。

合適的title

title是告訴搜索引擎網頁的主要內容。

每個網頁應該有一個獨一無二的標題,切忌所有的頁面都使用默認標題

標題要主題明確和精練,包含這個網頁中最重要的內容,且不羅列與網頁內容不相關的信息

用戶瀏覽通常是從左到右的,重要的內容應該放到title的靠前的位置

百度建議描述:

首頁:網站名稱 或者 網站名稱_服務介紹/產品介紹

頻道頁:頻道名稱_網站名稱

文章頁:文章標題_頻道名稱_網站名稱

合適的description

description是對網頁內容的精練概括。這個標簽存在與否不影響網頁權值,只會用做搜索結果摘要的一個選擇目標。 百度推薦做法:

為每個網頁創建不同的description,避免所有網頁都使用同樣的描述

網站首頁、頻道頁、產品參數頁等沒有摘要的網頁最適合使用description

准確的描述網頁,不要堆砌關鍵詞,長度合理

HTML語義化

HTML語義化是用標簽和屬性來描述內容。所以HTML語義化是SEO的基石。一般建議:

HTML結構要清晰和簡潔

跳轉使用<a>標簽,不要使用js跳轉

圖片加alt說明

文章用<article>標簽承載

...

Vue單頁項目的SEO

目前,對於SEO支持比較好的項目方案是采用服務端渲染。所以如果項目有SEO需求,那么比較好的方案是服務端渲染。

如果你已經采用了前后分離的單頁項目,而你的網站內容不需要AJAX去獲取內容和展示內容,那么可以試試 prerender-spa-plugin 這個插件,這個插件是一個webpack插件,可以幫助你在打包過程中通過無頭瀏覽器去渲染你的頁面,並生成對應的HTML。當然這個方案適合你的路由是靜態的,並且路由數量非海量。

如果你的內容是AJAX動態獲取的,那么vue單頁項目可以試試 prerender ,這個是一個預渲染服務,可以幫你通過無頭瀏覽器渲染頁面,並返回HTML。這個方案和prerender-spa-plugin很相似,都是通過無頭瀏覽器去渲染頁面,不同的是渲染的時機,prerender-spa-plugin是在打包過程中渲染,注定了其只能渲染靜態路由,而prerender 是在請求時渲染,所以可以渲染動態的路由。下面我重點介紹一下prerender方案。

prerender 的使用

1、安裝

$ npm install prerender

復制代碼

2、啟動服務 server.js

const prerender = require('prerender');

const server = prerender();

server.start();

復制代碼

3、測試

http://localhost:3000/render?url=https://www.example.com/

復制代碼

經過上面三個步驟,你就已經啟動一個預渲染服務,並且會返回"www.example.com/"的內容,整個過程還是比較簡單的。其github官網上面還介紹了它的許多中間件(Middleware),例如prerender-node (Express)、nginx.conf等,那么這個和 prerender 是什么關系呢?是否直接使用中間件就可以呢?下面介紹prerender是如何工作的吧。

prerender方案的原理

首先服務端接收到一個頁面的請求,然后判斷這個請求是否來自搜索引擎的爬蟲,如果不是,則直接返回單頁項目的HTML,按照普通單頁項目的工作模式(客戶端渲染),如果是,則把請求轉發給prerender服務,prerender服務會通過無頭瀏覽器進行預渲染,渲染完成把內容返回,這樣爬蟲就可以拿到有內容的HTML了。prerender中間件就是用來判斷請求是否來自搜索引擎爬蟲和轉發請求的。

值得注意的是,prerender服務是不包含無頭瀏覽器的,所以需要自行安裝chrome瀏覽器。因此,整個方案運行需要三部分:

chrome瀏覽器

prerender服務

prerender中間件

那么prerender服務是怎么知道頁面渲染已經完成的呢? Prerender服務通過計算未完成的請求數量,來確定頁面何時完成加載。一旦未完成的請求數達到零,服務會等待一段時間(默認500ms),然后保存HTML。

prerender的最佳實踐

經過實踐,請求一個經過prerender渲染的頁面是時間,快的時候約2s,慢的時候會長達8s。一般來說,請求時間在3s以內是最好的。所以我從以下幾個方面入手,探索prerender的優化方法。

減少資源請求的時間

影響prerender渲染時間的資源主要有js請求資源和api請求資源,api請求時間一般由后端決定,所以我考慮的是如何減少js資源請求時間。一般prerender服務渲染的資源請求地址是由頁面請求URL決定的,所以一般是線上的地址,如果我們把prerender服務部署在網站的服務器上,讓prerender服務請求資源走本地,那么就可以縮短資源的請求時間了。

如果你的線上服務是開啟了CDN的話,那么資源走本地還有一個好處,就是可以節省CDN流量。

優化prerender選項

prerender提供了一些自定義的選項

pageDoneCheckInterval:這個參數是prerender檢查頁面請求是否完成的定時器時間,默認是500ms,即每500ms檢查未完成的請求數量是否為零,我將其修改為100ms,提高其檢查的頻率。

waitAfterLastRequest:這個參數是最后一個請求完成之后等待的時間,默認是500ms,主要是請求完成之后,頁面更新渲染需要時間,立即返回的話,可能請求的數據來不及渲染,我將時間修改為200ms。

prerender插件

httpHeaders —— 返回合理的HTTP狀態碼

添加httpHeaders這個插件,可以更改返回的HTML的HTTP狀態碼,添加方式如下

var prerender = require('prerender');

var server = prerender()

server.use(prerender.httpHeaders());

server.start();

復制代碼

prerender通過識別在<head>中的<meta>標簽來設置頁面返回的HTTP狀態碼。

 

復制代碼

如果你需要設置301重定向,可以這樣做

 

 

復制代碼

blockResources —— 無需等待圖片資源

prerender是根據未完成的請求數來判斷是否渲染結束的。但是我們給搜索引擎返回的HTML只需要渲染通過js動態增加的DOM,其實不需要渲染css或者渲染接口返回的圖片的,我們來看下prerender在渲染中是否會請求這些資源。 prerender可以開啟是否打印請求,開啟方式如下:

var server = prerender({

logRequests: true

});

復制代碼

開啟之后就可以在控制台看到請求了,請求里面是包含css和圖片資源的。

2019-07-17T04:34:03.180Z - 47 http://xxx.com/css/chunk-f4a02584.da8dca38.css

2019-07-17T04:34:03.180Z {

source: 'network',

level: 'error',

text: 'Failed to load resource: net::ERR_INVALID_ARGUMENT',

timestamp: 1563338043130.37,

url: 'http://xxx.com/wefid/css/chunk-f4a02584.da8dca38.css',

networkRequestId: '1000039068.65'

}

2019-07-17T04:34:03.924Z + 3 http://xxx.com/img/erweima_wx.a84d82ef.jpg

2019-07-17T04:34:03.924Z + 4 http://xxx.com/img/erweima_wb.06971584.png

復制代碼

為什么prerender要等待這些資源呢?因為prerender服務還有一個強大的功能,那就是Prerender.com,其可以通過一個接口給你返回如下的東西:

網頁的HTML文件

網頁的屏幕截圖(視口或全屏)

網頁的PDF文件

網頁的HAR文件

執行您自己的javascript並返回json和HTML

很明顯,這些功能是需要加載你所需的CSS或圖片資源的,不然網頁顯示有問題。這個時候,如果你只需要滿足SEO需求而不需要Prerender.com的功能的話,那么blockResources插件就可以派上用場了。插件添加方式如下:

var prerender = require('prerender');

var server = prerender()

server.use(prerender.blockResources());

server.start();

復制代碼

使用blockResources插件之后,圖片資源和字體資源會被abort(舍棄)。

自定義渲染結束時間

如果你想更細粒化地控制prerender的返回時機,提前結束或者延后結束,那么可以使用這個標志window.prerenderReady。

首先需要設置window.prerenderReady為false,prerender在檢測到window.prerenderReady為false之后,會等待你設置為true再返回結果。

 

復制代碼

當你渲染完成之后,一般在接口請求完成並渲染完成之后

window.prerenderReady = true;

復制代碼

這樣你就可以更加自由地控制渲染結束的時機。

開啟緩存

緩存這里有兩個方面,一方面是HTTP緩存(瀏覽器緩存),另一方面是渲染結果緩存。

首先HTTP緩存可以讓prerender服務不用頻繁地發起資源請求,節省傳輸時間。這個我就不展開將,我想講的是渲染結果緩存。prerender中間件提供了兩種緩存方式, redis 或者 memcached ,以redis為例:

$ npm install redis

復制代碼

var redis = require("redis"),

client = redis.createClient();

prerender.set('beforeRender', function(req, done) {

client.get(req.url, done);

}).set('afterRender', function(err, req, prerender_res) {

client.set(req.url, prerender_res.body)

});

復制代碼

你可以通過 beforeRender 和 afterRender 這兩個鈎子進行細粒化地控制,對於內容變化頻繁的不緩存或緩存時間短,對於內容變化不頻繁的設置長時間緩存。開啟緩存不僅可以加速返回時間,還可以減輕服務器的壓力。

統計和監控

統計和監控可以放在中間件的 afterRender 中進行。

prerender.set('afterRender', function(err, req, prerender_res) {

if(err){

// 這里是錯誤監控代碼

// ...

// return

}

let {headers: req_headers, originalUrl} = req

let {headers: res_headers, body} = prerender_res

// 這里是統計代碼,可以保存請求和返回的相關信息

})

復制代碼

小結

通過以上的優化方法(除了自定義渲染結束時間和開啟緩存),我已經將HTML的請求時間穩定在2.5s左右。

總結

以上就是我想講的關於前端編碼SEO的全部內容,總而言之,就是

合適的HTML標簽和屬性

合理的HTTP狀態碼

Sitemap & robot.txt

合適的渲染方案

參考文章:

https://juejin.im/post/5d2d64f36fb9a07eba2c6f65

https://z.itpub.net/topic/110000101783


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM