愈來愈複雜的 UI 意味着愈來愈重的渲染工做。目前一般有兩種選擇:服務器渲染與客戶端渲染。javascript
以 Jade, YAML 爲表明的模板渲染引擎通常做用於服務器做爲後端的視圖部分。 css
而使用 JavaScript 直接 處理 HTML DOM 則是 做用於前端,性質是客戶端執行渲染。html
二者在最終用戶看到的效果是一致的。 前端
Web App 最終都仍是要落實到HTML,CSS,JavaScript上才能體現到用戶界面上。 vue
歸根結底,後端渲染是將一些模板規範語言翻譯成如上三種語言回傳給前端;而前端渲染則是將整個生成邏輯代碼所有回傳前端,再由客戶端生成用戶界面。java
一開始,Web App 直接由若干 HTML,CSS, JS 組成,每個頁面須要特殊的邏輯,所以隨着App規模的擴大,後端網站目錄下的代碼文件就愈來愈多,並且,彼此之間是沒有同步的,好比你改了站點的佈局風格。那麼你極可能須要改動成百上千的HTML文件,這誰能忍?react
聰明的工程師們想到,既然如此多的HTML具備必定的邏輯聯繫,何不使用代碼生成代碼?因而後端模板語言誕生了,這但是前端狗的一大痛點啊,因而人們開始普遍使用模板語言代替手寫HTML。我認爲,模板語言的成功源於它成功地減小了前端工程師的工做量。webpack
後端模板渲染的思路應該是源自「如何管理數以千計的存儲於後端的前端頁面的版本一致?」這個問題的。經過代碼生成代碼,本質上是編譯,他們基於HTML等基礎語言做了更高層次的抽象封裝,加強了易用性。各類模板語言大同小異,但大多都有模板中的模板這樣的性質來完成繼承這樣的面向對象特性。nginx
可能,當時工程師們沒有考慮前端渲染的一大緣由是 以JavaScript爲表明的前端技術還沒有崛起。如今HTML5,CSS3,JS 受到愈來愈廣的普及使得前端的可做爲性大大提高,特別是在Node.js出現之後 JS 工程師維護後端的成本大大下降。web
在一些jQuery用戶的角度看來,JS生成前端無非就是這樣的
var e = document.createElement('div'); $('#container').append(e);
你須要先把DOM生成,而後再插入到其餘的DOM裏去。純JS處理DOM確實是一件麻煩事,這可能也是客戶端渲染遲遲沒有發展起來的緣由之一。
考慮一下爲何後端模板語言方便簡潔? 由於它用了與HTML相似的語法。在PHP,JSP頁面裏面你可使用大量的HTML語法,只使用少許的變量注入與迭代注入。
使用HTML進行設計明顯比純JS更方便快捷而且直觀。
那麼能夠借鑑地,解決客戶端渲染問題的最後一個錦囊就是引入模板,在這裏咱們稱之爲組件(Component) 。
對待模板,新興的Angular,React,Vue 意見不一,甚至他們對本身在Web App 的定位也不同。 具體狀況能夠本身去了解,這並非本文的重點。
隨着前端也支持了模板語言,那麼之前的代碼管理問題也解決了,以往的後端渲染引擎也大多有了基於JS的前端版本。
先後端真正解耦,前端將專一於UI,後端將專一於數據處理,兩端經過設計好的API進行交互,這會是一個趨勢。
互聯網早期,用戶使用瀏覽器瀏覽的都是一些沒有複雜邏輯的、簡單的頁面,這些頁面都是在後端將html拼接好的而後將之返回給前端完整的html文件,瀏覽器拿到這個html文件以後就能夠直接解析展現了,而這也就是所謂的服務器端渲染了。而隨着前端頁面的複雜性提升,前端就不只僅是普通的頁面展現了,而可能添加了更多功能性的組件,複雜性更大,另外,彼時ajax的興起,使得業界就開始推崇先後端分離的開發模式,即後端不提供完整的html頁面,而是提供一些api使得前端能夠獲取到json數據,而後前端拿到json數據以後再在前端進行html頁面的拼接,而後展現在瀏覽器上,這就是所謂的客戶端渲染了,這樣前端就能夠專一UI的開發,後端專一於邏輯的開發。
客戶端渲染和服務器端渲染的最重要的區別就是到底是誰來完成html文件的完整拼接,若是是在服務器端完成的,而後返回給客戶端,就是服務器端渲染,而若是是前端作了更多的工做完成了html的拼接,則就是客戶端渲染。
客戶端渲染路線:
1. 請求一個html -> 2. 服務端返回一個html -> 3. 瀏覽器下載html裏面的js/css文件 -> 4. 等待js文件下載完成 -> 5. 等待js加載並初始化完成 -> 6. js代碼終於能夠運行,由js代碼向後端請求數據( ajax/fetch ) -> 7. 等待後端數據返回 -> 8. 客戶端從無到完整地,把數據渲染爲響應頁面
服務端渲染路線:
1. 請求一個html -> 2. 服務端請求數據( 內網請求快 ) -> 3. 服務器初始渲染(服務端性能好,較快) -> 4. 服務端返回已經有正確內容的頁面 -> 5. 客戶端請求js/css文件 -> 6. 等待js文件下載完成 -> 7. 等待js加載並初始化完成 -> 8. 客戶端把剩下一部分渲染完成( 內容小,渲染快 )
本來由服務器執行的渲染任務轉移給了客戶端,這在大量用戶訪問的時候大大減輕後端的壓力。讓後端專一作後端應該作的事情,性能將大大提升,由於服務器作的事情確實減少了,而如今隨着客戶端軟硬件的發展,也能處理好大多數的渲染工做了。
將整個UI邏輯交給客戶端之後,一些有經驗有能力的用戶可能會劫持UI,使得他們可以看到一些不應看到的界面。這彷佛違反了安全的原則。可是「一切在前端談安全都是耍流氓」,後端不能輕信一切從前端傳來的數據,切記必定要作好過濾與驗證。只要使用SSL、屏蔽XSS、後端不出漏洞,想僞造身份劫持App仍是難以作到的。
前端耗時少。由於後端拼接完了html,瀏覽器只須要直接渲染出來。
有利於SEO(搜索引擎優化)。由於在後端有完整的html頁面,因此爬蟲更容易爬取得到信息,更有利於seo。
無需佔用客戶端資源。即解析模板的工做徹底交由後端來作,客戶端只要解析標準的html頁面便可,這樣對於客戶端的資源佔用更少,尤爲是移動端,也能夠更省電。
後端生成靜態化文件。即生成緩存片斷,這樣就能夠減小數據庫查詢浪費的時間了,且對於數據變化不大的頁面很是高效 。
不利於先後端分離,開發效率低。使用服務器端渲染,則沒法進行分工合做,則對於前端複雜度高的項目,不利於項目高效開發。另外,若是是服務器端渲染,則前端通常就是寫一個靜態html文件,而後後端再修改成模板,這樣是很是低效的,而且還經常須要先後端共同完成修改的動做; 或者是前端直接完成html模板,而後交由後端。另外,若是後端改了模板,前端還須要根據改動的模板再調節css,這樣使得先後端聯調的時間增長。
佔用服務器端資源。即服務器端完成html模板的解析,若是請求較多,會對服務器形成必定的訪問壓力。而若是使用前端渲染,就是把這些解析的壓力分攤了前端,而這裏確實徹底交給了一個服務器。
優勢:
先後端分離。前端專一於前端UI,後端專一於api開發,且前端有更多的選擇性,而不須要遵循後端特定的模板。
體驗更好。好比,咱們將網站作成單頁Web應用(single page web application,SPA,是加載單個HTML 頁面並在用戶與應用程序交互時動態更新該頁面的Web應用程序)或者部份內容作成SPA,這樣,尤爲是移動端,可使體驗更接近於原生app。
缺點:
前端響應較慢。若是是客戶端渲染,前端還要進行拼接字符串的過程,須要耗費額外的時間,不如服務器端渲染速度快。
不利於SEO。目前好比百度、谷歌的爬蟲對於SPA都是不認的,只是記錄了一個頁面,因此SEO不好。由於服務器端可能沒有保存完整的html,而是前端經過js進行dom的拼接,那麼爬蟲沒法爬取信息。 除非搜索引擎的SEO能夠增長對於JavaScript的爬取能力,這才能保證SEO。
不談業務場景而盲目選擇使用何種渲染方式都是耍流氓。好比企業級網站,主要功能是展現而沒有複雜的交互,而且須要良好的SEO,則這時咱們就須要使用服務器端渲染;而相似後臺管理頁面,交互性比較強,不須要seo的考慮,那麼就可使用客戶端渲染。
另外,具體使用何種渲染方法並非絕對的,好比如今一些網站採用了首屏服務器端渲染,即對於用戶最開始打開的那個頁面採用的是服務器端渲染,這樣就保證了渲染速度,而其餘的頁面採用客戶端渲染,這樣就完成了先後端分離。
若是進行了先後端分離,那麼前端就是經過js來修改dom使得html拼接徹底,而後再顯示,或者是使用SPA,這樣,SEO幾乎沒有。那麼這種狀況下如何作SEO優化呢?
咱們能夠自行提交sitemap,讓蜘蛛主動去爬取,可是遇到了sitemap中的url,達到指定頁面以後只有元js怎麼辦呢?這是咱們可使用<noscript>標籤來進行簡單的優化,好比打印出當前頁面信息的一些關鍵的信息點,可是正經常使用戶並不須要這些,會形成額外的負擔,且前端能夠判斷是否支持JavaScript,然後段不行,只好根據百度的spider作UA(用戶代理)判斷,使用phantomjs或者nginx代理,來對spider訪問的頁面進行特殊的處理,達到被收錄的效果。但這種效果仍是很差。。。
而目前的react和vue都提供了SSR,即服務器端渲染,這也就是提供SEO很差的解決方式了。
實際上,時至今日,先後端分離必定是必然或者趨勢,由於早期在web1.0時代的網頁就是簡單的網頁,而現在的網頁愈來愈朝向app前進,而先後端分離就是實現app的必然的結果。因此,咱們能夠認爲html、css、JavaScript組成了這個app,而後瀏覽器做爲虛擬機來運行這些程序,即瀏覽器成爲了app的運行環境,成了客戶端,總的來講就是當前的前端愈來愈朝向桌面應用或者說是手機上的app發展了,而好比說電腦上的qq能夠服務器端渲染嗎?確定不能!因此先後端分離也就成了必然。而咱們目前接觸額前端工程化、編譯(轉譯)、各類MVC/MVVM框架、依賴工具、npm、bable、webpack等等看似很新鮮、創新的東西實際上都是傳動桌面開發所造成的概念,只是近年來前端發展較快而借鑑過來的,本質上就是開源社區東平西湊作出來的一個visual studio。