iT邦幫忙

2023 iThome 鐵人賽

DAY 4
2
Modern Web

深入淺出,完整認識 Next.js 13 !系列 第 4

Day 04 - 該怎麼知道網站是 CSR 還是 Pre-Rendering 呢?

  • 分享至 

  • xImage
  •  

昨天介紹完了 Client Side Rendering ( CSR )、Server Side Rendering ( SSR )、與 Static Site Generation ( SSG ) 三種網頁渲染的模式,假如對三種模式的概念還不熟悉的朋友,可以先閱讀上篇文章

那要如何知道一個網頁是使用哪種渲染模式呢?今天來就來教大家幾個簡單的方法!


檢視網頁原始碼

第一種方式,我們可以在瀏覽器上查看網頁 html 原始碼,查看方式有兩種:

  • 網頁空白處右鍵 -> 檢視網頁原始碼 ( View Page Source )
  • 開啟開發者工具 -> 來源 ( Sources ) -> 網域名稱資料夾 -> 點選 HTML 文件

我們來實作一個簡單的網頁,包含一個 Navbar,和一個的計數器,並分別用 Next 寫一個 Pre-Rendering 的版本,和用 React 寫一個 CSR 的版本,來檢視他們的原始碼:

假如網頁是 Pre-Rendering,你可以在原始碼中找到頁面內容對應的 HTML Elements:

...
<body class='className__inter_59dee874__bbf899b6'>
        <div class='text-white'>
          <nav class='bg-[#181818]'>
            <ul class='h-[70px] flex items-center justify-center gap-[30px] cursor-pointer'>
              <li>首頁</li>
              <li>產品</li>
              <li>關於團隊</li>
              <li>FAQ</li>
              <li>聯繫我們</li>
            </ul>
          </nav>
          <main class='w-1/3 mx-auto flex flex-col items-center mt-[50px] bg-[#1b2028] rounded-[10px] p-[70px]'>
            <div class='text-[35px]'>Hello World!</div>
            <div class='w-full flex justify-between items-center mt-[50px] text-[25px]'>
              <button class='w-[50px] h-[50px] bg-[#a4a4a3] rounded-[10px] font-bold text-[20px]'>
                -1
              </button>
              <div>
                Count: <span class='font-bold'>0</span>
              </div>
              <button class='w-[50px] h-[50px] bg-[#a4a4a3] rounded-[10px] font-bold text-[20px]'>
                +1
              </button>
            </div>
          </main>
        </div>
        ...
      </body>

假如是 CSR 生成的網頁,原始碼 <body> 中,只會看到一個 <div id=’root’ /> 的容器,其餘內容會透過 bundle.js 注入:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>React App</title>
  <script defer src="/static/js/bundle.js"></script></head>
  <body>
    <div id="root"></div>
  </body>
</html>

禁用 JavaScript

第二種方法,我們可以在瀏覽器上禁用 JavaScript,看看分別會對兩個網頁造成什麼影響:

方法:開啟開發者工具 -> Ctrl (Cmd) + Shift + P -> 輸入 JavaScript -> 選擇 Disable JavaScript

停用後我們重新整理網頁,會發現 Pre-Rendering 的網頁內容依然正常載入,只是點 +1 和 -1 中間的 count 不會變動。這是因為 server 只會渲染並回傳靜態內容,禁用 JavaScript 後變無法進行 hydration。
Disable JavaScript_SSR

而 CSR 的網頁重新整理後則會呈現白頁,因為網頁內容需靠 JavaScript ( React ) 渲染後注入容器中,因此禁用 JavaScript 即無法執行渲染。
Disable JavaScript_CSR

透過 Google Cached Link

第三種方法我們可以從 Google 爬蟲的視角,看爬到你的網頁時網頁長什麼樣子!

方法:Google 搜尋你要查看的網頁 -> 點選搜尋結果網址旁的三個點點 -> 點選彈跳視窗最上方,「更多選項」的展開按鈕 -> 點選「頁面存檔」
Google Cached Link

理論上 Pre-Rendering 的內容會相對 CSR 完整許多,但如同昨天的文章提到,Google 現在針對 CSR 網頁也有 SEO 的措施。簡單來說,當 Google Search 進入你的網頁後,它會先執行 JavaScript 來渲染出一份新的 HTML,再重新進行解析和索引。

但要注意,不是每個搜尋引擎的爬蟲都能執行 JavaScript,而且目前 Google 針對 CSR 網站的爬蟲也有些限制須注意。

比方說,假如用戶進到網頁後,會先發一支 API request 取得 user 的資料。等待 response 的過程中畫面先跑 loading 特效,取得 response 後再 re-render 拿到的資料。

但 Google 爬蟲並不會等到取得 response 後才爬,所以只會爬到 loading 的畫面。因此 SEO 考量上,Google 官方還是推薦使用 Pre-Rendering。

假如有興趣了解更多,可以參考官方的說明

最後想問大家一個問題:大家常說 Next.js 的優勢之一是預設 Pre-Rendering,那用 Next 寫的專案,假如不特別設定成 CSR,就一定會是 Pre-Rendering 嗎?

來做一個小實驗:同樣是開頭用 Next 和 React 寫的計數器網頁,我們加入一個判斷式:
假如 local storage 中沒有 “counter” 這個 item,Hello World 就改成 Local Storage is Empty:

export default function Home() {
  ...
  const localStorageCounter = localStorage.getItem('counter');
  return (
  ...
    <div className='text-[45px]'>
      {localStorageCounter ? 'Hello World!' : 'Local Storage is Empty'}
    </div>
    ...
  );
}

這時我們打開網頁,畫面顯示和計數器功能都正常,但假如檢查原始碼會發現:咦怎麼 <body> 中只剩一堆 <script>,elements 都不見了?禁用 JavaScript 後網頁怎麼也變白頁了?

這個問題等講解 server components 會再詳細跟大家分享!可以先記得一個簡單的結論:在 Next 中,假如 Pre-Rendering 時違反了某些規定,例如上述的例子,在 server 環境使用 Web Storage API,可能會造成 Pre-Rendering 無法進行,網頁改為 CSR。

至於要如何處理剛剛的問題,以及在做 server-side rendering 時有什麼其他要注意的事項,就留到後續 Server Components 的文章分享囉!


謝謝大家耐心的閱讀,我們明天見!


上一篇
Day 03 - 什麼是網頁渲染 ( Rendering )?CSR、SSR、SSG、ISR 有什麼差別?
下一篇
Day 05 - 如何建立 Next.js 13 專案?問題選項該怎麼選?
系列文
深入淺出,完整認識 Next.js 13 !30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0

閱讀此篇文章的當下,Google Cached Link 的功能應該是已經被砍掉了
也謝謝大大的分享,獲益良多!

我要留言

立即登入留言