Web 應用程序的客戶端與服務器端與預渲染

已發表: 2022-03-11

最近前端社區發生了一些事情。 由於 React 及其內置的服務器端水合功能,服務器端渲染越來越受到關注。 但這並不是以超快的首字節時間 (TTFB) 得分為用戶提供快速體驗的唯一解決方案:預渲染也是一個非常好的策略。 這些解決方案與完全客戶端呈現的應用程序有什麼區別?

客戶端呈現的應用程序

由於存在 Angular、Ember.js 和 Backbone 等框架,前端開發人員傾向於在客戶端渲染所有內容。 多虧了 Google 及其“讀取”JavaScript 的能力,它運行良好,甚至對 SEO 也很友好。

使用客戶端渲染解決方案,您將請求重定向到單個 HTML 文件,服務器將在沒有任何內容(或帶有加載屏幕)的情況下交付它,直到您獲取所有 JavaScript 並讓瀏覽器在渲染內容之前編譯所有內容。

在良好且可靠的互聯網連接下,它非常快且運行良好。 但它可能會好很多,而且做到這一點並不難。 這就是我們將在以下部分中看到的內容。

服務器端渲染 (SSR)

SSR 解決方案是我們多年前經常做的事情,但往往忘記了支持客戶端渲染解決方案。

使用舊的服務器端渲染解決方案,您構建了一個網頁(例如使用 PHP),服務器編譯所有內容,包含數據,並將完全填充的 HTML 頁面交付給客戶端。 它快速有效。

但是……每次你導航到另一條路線時,服務器都必須重新做一遍工作:獲取 PHP 文件,編譯它,然後交付 HTML,所有的 CSS 和 JS 將頁面加載延遲到幾百毫秒或甚至整秒鐘。

如果您可以使用 SSR 解決方案進行第一個頁面加載,然後使用框架通過 AJAX 進行動態路由,只獲取必要的數據會怎樣?

這就是為什麼 SSR 在社區中越來越受關注的原因,因為 React 通過一個易於使用的解決方案普及了這個問題: RenderToString方法。

這種新型 Web 應用程序稱為通用應用程序同構應用程序。 這些術語的確切含義以及它們之間的關係仍然存在一些爭議,但許多人可以互換使用它們。

無論如何,該解決方案的優勢在於能夠使用相同的代碼開發應用程序服務器端和客戶端,並通過自定義數據為用戶提供真正快速的體驗。 缺點是需要運行服務器。

SSR 用於獲取數據並使用自定義內容預填充頁面,利用服務器的可靠互聯網連接。 也就是說,服務器自己的互聯網連接比使用 lie-fi 的用戶更好),因此它能夠在將數據交付給用戶之前預取和合併數據。

使用預先填充的數據,使用 SSR 應用程序還可以解決客戶端呈現的應用程序在社交共享和 OpenGraph 系統方面存在的問題。 例如,如果您只有一個index.html文件要交付給客戶端,那麼它們將只有一種類型的元數據——很可能是您的主頁元數據。 當您想要共享不同的路線時,這不會被上下文化,因此您的任何路線都不會顯示在其他網站上,其中包含用戶想要與世界共享的適當用戶內容(描述和預覽圖片)。

預渲染

通用應用程序的強制服務器對某些人來說可能是一種威懾,對於小型應用程序來說可能是過度殺傷力。 這就是為什麼預渲染可以成為一個非常好的選擇。

我使用 Preact 和它自己的 CLI 發現了這個解決方案,它允許您編譯所有預先選擇的路由,以便您可以將完全填充的 HTML 文件存儲到靜態服務器。 借助 Preact/React 水合功能,您無需使用 Node.js,即可為用戶提供超快速的體驗。

問題是,因為這不是 SSR,所以此時您沒有要顯示的用戶特定數據——它只是在第一個請求時直接發送的靜態(並且有些通用)文件,原樣。 因此,如果您有特定於用戶的數據,您可以在這裡集成一個設計精美的骨架,向用戶展示他們的數據即將到來,以避免他們感到沮喪:

使用文檔骨架作為加載指示器的一部分

還有另一個問題:為了使這種技術發揮作用,您仍然需要有一個代理或其他東西來將用戶重定向到正確的文件。

為什麼?

對於單頁應用程序,您需要將所有請求重定向到根文件,然後框架使用其內置的路由系統重定向用戶。 所以第一個頁面加載總是相同的根文件。

為了使預渲染解決方案起作用,您需要告訴您的代理某些路由需要特定文件,而不總是需要根index.html文件。

例如,假設您有四個路線( //about/jobsblog )並且它們都有不同的佈局。 您需要四個不同的 HTML 文件將骨架交付給用戶,然後讓 React/Preact/etc. 用數據重新水化它。 因此,如果您將所有這些路由重定向到根index.html文件,則頁面在加載過程中會有一種令人不快的、有故障的感覺,用戶將看到錯誤頁面的骨架,直到它完成加載並替換佈局。 例如,用戶可能會看到只有一列的主頁骨架,而他們要求使用類似 Pinterest 的畫廊的不同頁面。

解決方案是告訴您的代理這四個路由中的每一個都需要一個特定的文件:

  • https://my-website.com → 重定向到根index.html文件
  • https://my-website.com/about → 重定向到/about/index.html文件
  • https://my-website.com/jobs → 重定向到/jobs/index.html文件
  • https://my-website.com/blog → 重定向到/blog/index.html文件

這就是為什麼這個解決方案對小型應用程序很有用的原因——你可以看到如果你有幾百頁會有多痛苦。

嚴格來說,這樣做並不是強制性的——你可以直接使用靜態文件。 例如, https://my-website.com/about/無需任何重定向即可工作,因為它會自動在其目錄中搜索index.html 。 但是,如果您有參數 url,則需要此代理- https://my-website.com/profile/guillaume需要使用自己的佈局將請求重定向到/profile/index.html ,因為profile/guillaume/index.html不存在,會觸發 404 錯誤。

如上一段所述,顯示代理如何在預渲染解決方案中發揮作用的流程圖


簡而言之,上面描述的渲染策略包含三個基本視圖:加載屏幕、骨架和最終渲染後的整個頁面。

比較加載屏幕、骨架和完全渲染的頁面

根據策略,有時我們會使用所有這三個視圖,有時我們會直接跳轉到完全渲染的頁面。 只有在一個用例中,我們才被迫使用不同的方法:

方法著陸(例如/ 靜態(例如/about 固定動態(例如/news 參數化動態(例如/users/:user-id
客戶端渲染正在加載 → 已滿正在加載 → 已滿加載→骨架→完整加載→骨架→完整
預渲染滿的滿的骨架→全HTTP 404(找不到頁面)
使用代理預渲染滿的滿的骨架→全骨架→全
固態繼電器滿的滿的滿的滿的

僅客戶端渲染通常是不夠的

客戶端渲染的應用程序是我們現在應該避免的,因為我們可以為用戶做得更好。 在這種情況下,做得更好就像預渲染解決方案一樣簡單。 這絕對是對僅客戶端渲染的改進,並且比完全服務器端渲染的應用程序更容易實現。

如果您有一個包含許多不同頁面的大型應用程序,那麼 SSR/通用應用程序會非常強大。 在與社交爬蟲交談時,它可以讓您的內容集中且相關。 搜索引擎機器人也是如此,現在它們在對您的網站進行排名時會考慮您的網站的性能。

請繼續關注後續教程,我將介紹如何將 SPA 轉換為預渲染和 SSR 版本,並比較它們的性能。

相關:流行的靜態站點生成器概述