每個開發工具公司和團隊似乎都假設初級開發人員熟悉這些術語。
當我開始編碼時,我到處都看到它們:Nuxt 是一個 SSR 框架,你可以使用 Gatsby 進行 SSG,如果你在 next.config.js 中設定這個或那個標誌,你可以啟用 SPA 模式。
什麼鬼?
作為第一步,這裡有一個術語表 - 儘管它不會幫助您理解詳細資訊:
接下來,讓我們為黑暗帶來一些光明。
最初,網站是您從伺服器請求的 HTML 檔案。
你的瀏覽器會詢問伺服器,「嘿,你能把那個/about頁面遞給我嗎?」伺服器會回應一個 about.html 檔案。您的瀏覽器知道如何解析所述文件並呈現一個漂亮的網站,例如這個。
我們稱這樣的伺服器為靜態網路伺服器。開發人員手動編寫 HTML 和 CSS(可能還有一點 JS),將其儲存為文件,將其放入資料夾中,然後伺服器根據請求交付它。沒有特定於使用者的內容,只有每個人都可以存取的通用、靜態(不變)內容。
app.get('/about', async (_, res) => { const file = fs.readFileSync('./about.html').toString(); res.set('Content-Type', 'text/html'); res.status(200).send(file); })
然而,靜態網站很無聊。
如果使用者能夠與網站互動,那麼對使用者來說會更有趣。因此,開發人員使之成為可能:只需一點 JS,她就可以點擊按鈕、展開導覽列或過濾搜尋結果。網路變得互動起來。
這也意味著 /search-results.html 頁面將包含不同的元素,具體取決於使用者作為搜尋參數發送的內容。
因此,使用者將在搜尋欄中輸入內容,按 Enter 鍵,然後將帶有搜尋參數的請求傳送到伺服器。接下來,伺服器將從資料庫中取得搜尋結果,將其轉換為有效的 HTML,並建立完整的 /search-results.html 檔案。用戶收到了結果文件作為回應。
(為了簡化創建特定於請求的 HTML,開發人員發明了 HTML 模板語言,例如 Handlebars。)
app.get('/search-results', async (req, res) => { const searchParams = req.query.q; const results = await search(searchParams); let htmlList = '<ul>'; for (const result of results) { htmlList += `<li>${result.title}</li>`; } htmlList += '</ul>'; const template = fs.readFileSync('./search-results.html').toString(); const fullPage = embedIntoTemplate(htmlList, template); res.set('Content-Type', 'text/html'); res.status(200).send(fullPage); });
在很長一段時間裡,我發現這個術語渲染非常令人困惑。
在其原始意義中,渲染描述了電腦創建人類可處理的圖像。例如,在電玩遊戲中,渲染指的是每秒創建 60 個圖像的過程,用戶可以將其作為引人入勝的 3D 體驗來消費。我想知道,已經聽說過伺服器端渲染,它是如何工作的 - 伺服器如何渲染圖像供用戶查看?
但事實證明,我意識到這有點太晚了,伺服器端或客戶端渲染上下文中的「渲染」意味著不同的事情。
在瀏覽器上下文中,「渲染」保持其原始意義。瀏覽器確實渲染圖像供使用者查看(網站)。為此,需要一個最終結果的藍圖。該藍圖以 HTML 和 CSS 檔案的形式出現。瀏覽器將解釋這些文件並從中派生出模型表示形式,即文件物件模型 (DOM),然後可以渲染和操作該模型。
讓我們將其映射到建築物和架構上,以便我們可以更好地理解它:有一個房子的藍圖(HTML 和CSS),建築師將其轉換為他辦公桌上的小型物理模型( DOM),這樣他可以操縱它,當每個人都同意結果時,建築工人會查看模型並將其「渲染」成實際的建築物(使用者看到的圖像)。
但是,當我們在伺服器上下文中談論「渲染」時,我們談論的是建立,而不是解析 HTML 和 CSS 檔案。首先完成此操作,以便瀏覽器可以接收要解釋的文件。
轉向客戶端渲染,當我們談論「渲染」時,我們指的是操作 DOM(瀏覽器透過解釋 HTML 和 CSS 文件創建的模型)。然後瀏覽器將 DOM 轉換為人類可見的圖像。
隨著 Facebook 等平台的興起,開發者需要更多、更快的互動性。
在互動式網頁應用程式中處理按鈕點擊需要時間 - 必須建立 HTML 文件,必須透過網路傳送它,並且使用者的瀏覽器必須呈現它。
All that hassle while the browser could already manipulate the website without requesting anything from the server. It just needed the proper instructions — in the form of JavaScript.
So that's where devs placed their chips.
Large JavaScript files were written and sent to the users. If the user clicked on a button, the browser would insert an HTML component; if the user clicked a "show more" button below a post, the text would be expanded — without fetching anything.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <div id="root"></div> <script> document.addEventListener('DOMContentLoaded', () => { const root = document.getElementById('root'); root.innerHTML = ` <h1>Home</h1> <button>About</button> `; const btn = document.querySelector('button'); btn.addEventListener('click', () => { root.innerHTML = ` <h1>About</h1> `; }); }); </script> </body> </html>
Though the code snippet suggests the opposite, developers didn't write vanilla JavaScript.
Ginormous web apps like Facebook had so much interactivity and duplicate components (such as the infamous Like-button) that writing plain JS became cumbersome. Developers needed tools that made it simpler to deal with all the rendering, so around 2010, frameworks like Ember.js, Backbone.js, and Angular.js were born.
Of them, Angular.js was the one that brought Single Page Applications (SPAs) into the mainstream.
An SPA is the same as Client-Side Rendering, but it is taken a step further. The conventional page navigation, where a click on a link would fetch and render another HTML document, was taken over by JavaScript. A click on a link would now fire a JS function that replaced the page's contents with other, already preloaded content.
For this to work properly, devs needed to bypass existing browser mechanisms.
For example, if you click on a
Devs invented all kinds of hacks to bypass this and other mechanisms, but discussing those hacks is outside the scope of this post.
So what were the issues with that approach?
SEO and Performance.
First, if you look closely at the above HTML file, you'll barely see any content in the
tags (except for the script). The content was stored in JS and only rendered once the browser executed the