圖片總是上傳失敗朗恳。
瀏覽器渲染原理
- DOM
- CSSOM
- RenderTree
- Layout
- Paint
文檔對象模型 (DOM)
[圖片上傳失敗...(image-a35366-1526004305368)]
- 轉換: 瀏覽器從磁盤或網(wǎng)絡讀取 HTML 的原始字節(jié)涕侈,并根據(jù)文件的指定編碼(例如 UTF-8)將它們轉換成各個字符璃氢。
- 令牌化(Token): 瀏覽器將字符串轉換成 W3C HTML5 標準規(guī)定的各種令牌,例如及刻,“<html>”美澳、“<body>”,以及其他尖括號內的字符串眠饮。每個令牌都具有特殊含義和一組規(guī)則元潘。
- 詞法分析(Node): 發(fā)出的令牌轉換成定義其屬性和規(guī)則的“對象”(我理解成標簽)箫攀。
- DOM 構建: 最后川尖,由于 HTML 標記定義不同標記之間的關系(一些標記包含在其他標記內),創(chuàng)建的對象鏈接在一個樹數(shù)據(jù)結構內江咳,此結構也會捕獲原始標記中定義的父項-子項關系:HTML 對象是 body 對象的父項返咱,body 是 paragraph 對象的父項钥庇,依此類推。
注:DOM 是增量構建咖摹,沒有必要等到 DOM 構建完成之后在渲染到頁面
CSS 對象模型 (CSSOM)
[圖片上傳失敗...(image-c50f77-1526004305369)]
與 DOM 的流程類似评姨,只不過它是 CSSOM
[圖片上傳失敗...(image-e6dc0b-1526004305369)]
上圖說明 CSSOM 為啥是樹形結構
構建渲染樹 Render Tree
[圖片上傳失敗...(image-571272-1526004305369)]
- 從 DOM 樹的根節(jié)點開始遍歷每個可見節(jié)點。
- 某些節(jié)點不可見(例如腳本標記萤晴、元標記等)吐句,因為它們不會體現(xiàn)在渲染輸出中,所以會被忽略店读。
- 某些節(jié)點通過 CSS 隱藏嗦枢,因此在渲染樹中也會被忽略,例如屯断,上例中的 span 節(jié)點---不會出現(xiàn)在渲染樹中文虏,---因為有一個顯式規(guī)則在該節(jié)點上設置了“display: none”屬性。
- 節(jié)點位置和大小是基于 viewport 計算的
- 對于每個可見節(jié)點殖演,為其找到適配的 CSSOM 規(guī)則并應用它們氧秘。
- 發(fā)射可見節(jié)點,連同其內容和計算的樣式趴久。
- 最終輸出的渲染同時包含了屏幕上的所有可見內容及其樣式信息
注:簡單提一句丸相,請注意 visibility: hidden 與 display: none 是不一樣的。前者隱藏元素彼棍,但元素仍占據(jù)著布局空間(即將其渲染成一個空框)灭忠,而后者 (display: none) 將元素從渲染樹中完全移除膳算,元素既不可見,也不是布局的組成部分更舞。
總結:
- 到目前為止(以上 3 步驟),我們計算了哪些節(jié)點應該是可見的以及它們的計算樣式坎吻,但我們尚未計算它們在設備視口內的確切位置和大小---這就是“布局”階段 Layout缆蝉,也稱為“自動重排”。
- Render Tree 會等到 CSSOM 構建完在執(zhí)行瘦真,因為 css 是增量構建刊头,但不是增量渲染的。瀏覽器不能先渲染 14px 字诸尽,又接著渲染 18px原杂,發(fā)現(xiàn)又變量,渲染成 16px
布局階段 Layout:計算渲染樹的位置和大小
為弄清每個對象在網(wǎng)頁上的確切大小和位置您机,瀏覽器從渲染樹的根節(jié)點開始進行遍歷穿肄。
執(zhí)行渲染樹構建、布局和繪制所需的時間將取決于文檔大小际看、應用的樣式咸产,以及運行文檔的設備:文檔越大,瀏覽器需要完成的工作就越多仲闽;樣式越復雜脑溢,繪制需要的時間就越長(例如,單色的繪制開銷“較小”赖欣,而陰影的計算和渲染開銷則要“大得多”)屑彻。
查看哪些樣式觸發(fā) Layout:https://csstriggers.com/
- 屏幕旋轉
- 瀏覽器視窗改變
- 與大小位置相關的 CSS 屬性改變
最后 Paint
布局完成后,瀏覽器會立即發(fā)出“Paint Setup”和“Paint”事件顶吮,將渲染樹轉換成屏幕上的像素(社牲,也就是填充)
資源對渲染的影響
- img
- css
- js
- font
CSS 資源
瀏覽器會在何時渲染頁面:加載完部分 DOM 和 CSSOM
<style></style>
<link />
- 上面 2 種形式都會阻止初次渲染
- 瀏覽器會在解析完 CSS 后,在進行渲染悴了,為了防止樣式突變帶來的抖動
- 不管 CSS 出現(xiàn)在文檔哪里膳沽,都會阻塞整個文檔初次渲染
- 通過 link 標簽,阻塞時間更長让禀,因為有個網(wǎng)絡請求時間
重點:關鍵資源
- document.write 寫入 link 標簽挑社,阻止渲染
- css 是不是關鍵資源,看媒體查詢
- 如果不是當前網(wǎng)頁所應用的類型文件巡揍,雖然也會加載痛阻,但是不會阻塞初次渲染
- 通過 DOM api 添加 link 不會阻塞渲染
<link rel="preload" href="xxx" onload="this.rel='stylesheet'">
JS 資源
- JS 阻塞 HTML 渲染
- 因為 js 有修改 dom 的能力,所以瀏覽器會在執(zhí)行 js 期間腮敌,暫停 html 渲染
- CSS 阻塞 JS
- 因為 JS 能讀取或者修改 CSS阱当,所以要等到 CSS 加載完在執(zhí)行
- 當 HTML 被 JS 阻塞了俏扩,雖然停止構建 DOM,但是瀏覽器還是會識別 JS 后面的資源弊添,并提前加載他們录淡,
- 這是瀏覽器的資源加載策略
重點:關鍵資源
不是關鍵資源
- 放到底部,‘延時’加載
- 使用 defer 延遲腳本執(zhí)行油坝。擁有 defer 的腳本嫉戚,會被推遲到 HTML 文檔解析完成后,在執(zhí)行澈圈;并且執(zhí)行的順序是按照 HTML 文檔中出現(xiàn)的順序彬檀。
- 不會阻塞初次渲染
- 放的越前面,越能提前加載
- 不好的地方:執(zhí)行順序瞬女。如果前面加載 1M 的 js 文件窍帝,這個不加載完,后面的就算加載完也執(zhí)行不了
- 使用 async 異步加載腳本
- 不會阻塞初次渲染诽偷,也不會被 CSS 阻塞
- 腳本加載完就執(zhí)行坤学,所以跟在 HTML 文檔中的順序無關
- 適用于無依賴的 js
[圖片上傳失敗...(image-cddec-1526004305369)]
字體
- 阻塞初次渲染,頁面空白报慕。所以要異步加載 css拥峦,因為字體是定義在 css 里的
圖片:不會阻塞
優(yōu)化關鍵渲染路徑
目標:以下壓縮到最低
- 關鍵資源數(shù)
- 關鍵資源體積
- 關鍵資源網(wǎng)絡來回數(shù)
- 延遲或異步加載資源,從而減少關鍵資源數(shù)
- 減小資源大小
- 針對關鍵資源卖子,減少網(wǎng)絡請求時間
構建 DOM 是增量構建
瀏覽器無需等待 HTML 加載完畢略号,就開始構建 DOM
使用 Timeline 注意事項
- 禁用緩存(Network 里 Disable cache),以便測試首次瀏覽性能
- 關閉 Chrome 擴展或者直接使用隱身模式
- 模擬真實網(wǎng)絡情況
- Chrome Canary(Chrome 開發(fā)版本)