這篇文章是關於 HTML 渲染的首屏優化的,
主要是針對 web app 這種相對交互較多的應用場景,
首屏優化主要爲了改善用戶對於頁面的感知,
而服務端渲染(SSR)是 web app 優化首屏依賴的重要手段.html
昨晚錄了視頻, 解釋了一遍, 能夠先看個大概:
http://weibo.com/1651843872/E...前端
以往基於字符串拼接的模板引擎技術, 性能還能夠, 可是前端不方便,
而如今基於 Virtual DOM 實現的後端渲染, 前端舒服, 後端卻變慢,
緣由是 Virtual DOM 難以作靜態分析進行預編譯, 最終難以提升性能.
另外組件級別 Caching 方案也不夠成熟, 之後比較難肯定有效果.web
既然提升性能短時間作不到, 那麼考慮對服務端渲染的工做進行縮減.
好比說, 首屏渲染多少內容? 整頁渲染性能低, 能不能只渲染部分,
好比說只渲染第一屏主體內容, 而下方或者更詳細數據在客戶端抓取.
就是說, 服務端渲染一部分, 客戶端加載一部分, 從而作出效果.
固然, 並非新的東西, 只是說這套方案在 Virtual DOM 上要從新實現一遍.後端
再說"漸進式", 上述過程"服務端/客戶端"渲染工做分割的比例如何?
好比說定義 Level 0~5 的等級, 服務端渲染的部分能夠有多種狀況,
最主要的好比說 App Shell 狀況, 也就是頁面的靜態框架部分,
那麼渲染過程就是: 服務端渲染局部, 客戶端渲染局部,
並且隨着服務端性能提升, 能夠分配更多工做到服務器上. 這樣的"漸進",瀏覽器
舉個例子, 若是用純數字的層級, 能夠這樣來判斷服務端:服務器
(def level 2) (def html-result (div {} (if (> level 0) (div {} (text "content 0")) (if (> level 1) (div {} (text "content 1")) (if (> level 2) (div {} (text "content 2")) (if (> level 3) (div {} (text "content 3")) (if (> level 4) (div {} (text "content 4")))))
而客戶端拿到 level
以後, 能夠計算差量, 算出缺失的部分,
這個其實就是 Virtual DOM 作 Diffing 的思路... 不難理解.
單純從原理上, 這是行得通的, 也就是我視頻當中展現的.app
從具體的使用的場景, 不一樣的 Level 實際上對應不一樣的頁面內容,
論壇是一個比較清晰的例子, 想象一個論壇:框架
網頁的靜態部分, HTML 固定的內容, 好比導航欄和底部前後端分離
頁面首屏的內容, 好比一個論壇的話題性能
頁面首屏看不到的內容, 好比話題下面多少回覆
切換路由纔會顯示的頁面, 好比導航的另外一個頁面
對於這樣的狀況, 顯然有若干種可行的渲染分割的方案:
全在客戶端渲染
1, 2, 3 在服務端渲染, 4 等到用戶點擊從瀏覽器抓
1, 2 在服務器渲染, 評論由客戶端加載
只有 1 在服務端渲染, 動態的數據所有由客戶端抓取.
而這些方案對於服務端來講, 性能的開銷各不相同, 造成一個梯度,
而最後一種狀況, 服務端預編譯頁面就行了, 幾乎沒有渲染負擔.
根據實際的場景, 能夠有更多 Level 能夠設計.. 只是沒這麼簡單罷了...
數據依賴問題是複雜的一個緣由, 可能仍是比較重要的一個.
對於稍微複雜的單頁面應用, 抓取數據可能會涉及多個接口,
考慮到先後端分離之類的因素, 極可能是跨機器去抓數據的,
固然這樣也就須要注意減小抓數據等待, 以便儘快返回.
可是這中間有一些誤區, 前端經常使用的辦法是組件 didMount 開始抓數據,
而實際上, 若是想要合併請求, 就要處理多個組件的 didMount,
甚至存在嵌套的狀況, 數據 A 加載完, 渲染, 而後須要加載 B, 結果就複雜了.
好一個點的辦法是藉助 router 或者其餘的 DSL 分析出缺失數據,
好比 Falcor 當中能夠借鑑的一些方案... 目前說不上多少.
處理數據依賴的問題在前端抓數據已經遇到, 服務端只是其中一個場景,
我我的來講如今沒有滿意的方案, 只是說簡單狀況強制寫就算了.
這一點 GraphQL, Falcor 這樣的方案也在思考中, 但願儘快有結果.
籠統一點講, Gulp 能夠預編譯 HTML 的頭部尾部, 也是渲染,那麼頁面渲染的步驟就有, Gulp -> Server -> Client 三步了,而 Client 中還有收到用戶點擊而產生的渲染,於是這一串的渲染步驟實際上是有很長的, 有不少的文章能夠作.但願咱們會有足夠靈活的方案, 來完成中間各類方式的處理.如今呢只能算一個試驗的方案, 目測各大框架都沒有提供直接的支持...