使用HeadlessChrome作單頁應用SEO

隨着react、vue、angular等前端框架的流行愈來愈多的web應用變成了單頁應用,它們的特色是異步拉取數據在瀏覽器中渲染出HTML。使用這些框架極大的提高web用戶體驗和開發效率的同時缺帶來一個新問題,那就是這樣的網頁沒法被搜索引擎收錄。雖然這些web框架支持服務端渲染,但這可能又會增長開發成本。html

有沒有一個可用於任何單頁應用的SEO解決方案,讓咱們不用對代碼作改變保持原有的開發效率?chrome-render能夠幫咱們作到這點,它經過控制HeadlessChrome渲染出最終的HTML返回給爬蟲來實現。前端

HeadlessChrome介紹

前不久chrome團隊宣佈chrome支持headless模式,HeadlessChrome支持chrome所具備的全部功能只不過由於不顯示界面而更快資源佔用更小。相比於以前的phantomjs(做者由於HeadlessChrome的推出而宣佈中止維護)chrome的優點在於它又一個很強的爹(google)會一直維護它優化它,而且chrome在用戶量、體驗、速度、穩定性都是第一的,因此我認爲HeadlessChrome會漸漸替代以前全部的HeadlessBrowser方案。vue

如何操控HeadlessChrome

既然HeadlessChrome是以無界面模式運行的,那要怎麼控制它和它交互?
chrome提供了遠程控制接口,目前能夠經過chrome-remote-interface來用js代碼向chrome發送命令進行交互。在啓動chrome的時候要開啓遠程控制接口,而後經過 chrome-remote-interface 鏈接到chrome後再經過協議控制chrome。具體操做見文檔:react

chrome-render原理與實踐

原理

chrome-render先會經過chrome-runner以headless模式啓動和守護你操做上的chrome,再經過chrome-remote-interface操控chrome去訪問須要被SEO的網頁讓chrome運行這個網頁,等到包含數據的HTML被渲染出來時讀取當前網頁DOM轉換成字符串後返回。chrome

怎麼知道你的網頁何時已經渲染出包含數據的HTML了能夠返回了呢?爲了提高chrome-render效率,默認會在domContentEventFired時返回。對於複雜的場景還能夠經過開啓chrome-render的useReady選項,等到網頁裏調用了window.chromeRenderReady()時返回。api

只渲染出了HTML還不夠咱們還須要檢測出來着搜索引擎爬蟲的訪問,若是請求來着爬蟲就返回chrome-render渲染後的HTML不然返回正常的單頁應用所需HTML。瀏覽器

綜上,總體架構以下:
koa-seo arch

實踐

只需如下幾行簡單代碼就可以讓chrome渲染出HTML:

const ChromeRender = require('chrome-render');
ChromeRender.new().then(async(chromeRender)=>{
    const htmlString = await chromeRender.render({
       url: 'http://qq.com',
    });
});

chrome-render只是作了渲染出HTML的工做,要實現SEO還須要和web服務器集成。爲了方便你們使用我作了一個koa中間件koa-seo,要集成到你現有的項目很簡單,以下:

const seoMiddleware = require('koa-seo');
const app = new Koa();
app.use(seoMiddleware());

只需像這樣接入一箇中間件你的單頁應用就被SEO了。

應用場景擴展

chrome-render除了用於通用SEO解決方案其實能夠用於通用服務端渲染,由於目的都是渲染出最終的HTML再返回。針對通用服務端渲染我也作了一個koa中間件koa-chrome-render。使用chrome-render作服務端渲染的

優點在於:

  • 通用,適用於全部單頁應用

  • 對原有代碼幾乎無改動,最多再合適的地方加個window.chromeRenderReady(),保持原有開發效率

缺點在於:

  • 和react、vue等只帶的服務端渲染相比性能低(經我測試大約 200ms vs 60ms)

  • chrome-render渲染時佔用資源高,一次渲染大約佔用25Mb內存,當請求量大時服務器可能扛不住。可是能夠經過緩存渲染結果優化。

總結

你們可能會說這個很像prerender.io,沒錯思路是同樣的,chrome-render的優點在於:

  • chrome-render開源可本身部署,prerender要收費是商業產品

  • prerender基於已經中止維護的phantomjs

本文中所提到的相關項目都是開源的而且有詳細的使用文檔,它們的文檔連接以下:

喜歡的給個star,但願你們和我一塊兒來改進它們讓它們更強大。

閱讀原文

相關文章
相關標籤/搜索