JS的相關概念

weixin_33968104發表於2017-11-28

1. CSS和JS在網頁中的放置順序是怎樣的?

  • CSS最好放入header中,即放在網頁內容(html標籤中包含的文字和圖片等)和js指令碼之前
    <link href="index.css" rel="stylesheet">

  • S最好放在最後,即放在網頁內容(html標籤中包含的文字和圖片等)和js指令碼之後
    <script src="index.js"></script>

2. 解釋白屏和FOUC

  • 白屏問題
  1. 白屏的根本原因是瀏覽器在渲染的時候沒有請求到或請求時間過長造成的。
  2. 瀏覽器對於圖片和CSS,在載入時會併發載入(比如一個域名下同時載入多個檔案),瀏覽器對於JavaScript,在載入時會禁用併發,並且阻止其後的檔案及元件的下載。所以將js放在頁面的頂部也可能會導致白屏。
  3. 不同瀏覽器的處理CSS和HTML的方式是不同的:
    比如,IE、chrome瀏覽器的渲染機制,採用的是等CSS全部載入解析完後再渲染展示頁面。

Firefox則是在CSS未載入前先展示html的內容,等CSS載入後重新對樣式進行修改。
由此我們可以推斷出的結果是:
白屏的出現情況往往因為CSS樣式被置於底部(最後載入),當新視窗開啟,重新整理等的時候,頁面會出現白屏。
如果使用 @import標籤,它引用的檔案則會等頁面全部下載完畢再被載入,也可能出現白屏。
所以解決的辦法是css使用 link 標籤將樣式表放在頂部,防止白屏問題出現。白屏不是bug,而是由於瀏覽器的渲染機制。

  • FOUC
    FOUC (Flash of Unstyled Content) 無樣式內容閃爍:
    如果把樣式放在底部,對於IE瀏覽器,在某些場景下(點選連結,輸入URL,使用書籤進入等),會出現 FOUC 現象(逐步載入無樣式的內容,等CSS載入後頁面才突然展現出樣式)。對於 Firefox 會一直表現出 FOUC 。
  • 指令碼會阻塞後面內容的呈現
  • 指令碼會阻塞其後元件的下載

對於圖片和CSS, 在載入時會併發載入(如一個域名下同時載入兩個檔案)。但在載入 JavaScript 時,會禁用併發,並且阻止其他內容的下載。
所以所以儘量把 JavaScript 放入頁面body底部

3. async和defer的作用是什麼?有什麼區別

defer和async是script標籤的兩個屬性,用於在不阻塞頁面文件解析的前提下,控制指令碼的下載和執行。

  • 頁面的載入和渲染過程:
  1. 瀏覽器通過HTTP協議請求伺服器,獲取HMTL文件並開始從上到下解析,構建DOM;
  2. 在構建DOM過程中,如果遇到外聯的樣式宣告和指令碼宣告,則暫停文件解析,建立新的網路連線,並開始下載樣式檔案和指令碼檔案;
  3. 樣式檔案下載完成後,構建CSSDOM;指令碼檔案下載完成後,解釋並執行,然後繼續解析文件構建DOM
  4. 完成文件解析後,將DOM和CSSDOM進行關聯和對映,最後將檢視渲染到瀏覽器視窗,在這個過程中,指令碼檔案的下載和執行是與文件解析同步進行,也就是說,它會阻塞文件的解析,如果控制得不好,在使用者體驗上就會造成一定程度的影響。
    所以我們需要清楚的瞭解和使用defer和async來控制外部指令碼的執行。
  • 作用

defer:用於開啟新的執行緒下載指令碼檔案,並使指令碼在文件解析完成後執行。
async:新增屬性,用於非同步下載指令碼檔案,下載完畢立即解釋執行程式碼。

  • 區別
  1. <script src="script.js"></script>
    沒有 defer 或 async,瀏覽器會立即載入並執行指定的指令碼,“立即”指的是在渲染該 script 標籤之下的文件元素之前,也就是說不等待後續載入的文件元素,讀到就載入並執行。

  2. <script async src="script.js"></script>
    有 async,載入和渲染後續文件元素的過程將和 script.js 的載入與執行並行進行(非同步)。

  3. <script defer src="myscript.js"></script>
    有 defer,載入後續文件元素的過程將和 script.js 的載入並行進行(非同步),但是 script.js 的執行要在所有元素解析完成之後,DOMContentLoaded 事件觸發之前完成。

4. 瀏覽器的渲染機制

首先我們要了解幾個概念
DOM
Document Object Model,瀏覽器將HTML解析成樹形的資料結構;輸出的樹,也就是解析樹,是由DOM元素及屬性節點組成的。DOM是文件物件模型的縮寫,它是html文件的物件表示,作為html元素的外部介面供js等呼叫。

CSSOM
CSS Object Model,瀏覽器將CSS解析成樹形的資料結構

Render Tree
DOM和CSSOM合併後生成Render Tree

4857510-426f6b0b1226a8a2

Layout
計算出Render Tree每個節點的具體位置

Painting
通過顯示卡,將Layout後的節點內容分別呈現到螢幕上

具體的流程:
當我們的瀏覽器獲得html檔案後,會自上而下的載入,並在載入過程中進行解析和渲染。

載入說的是獲取資原始檔的過程,如果在載入過程中,遇到外部css檔案盒圖片,瀏覽器會另外發出一個請求,來獲取css檔案盒相應的圖片,這個請求是非同步的,並不會影響html檔案。

遇到JavaScript檔案,html檔案會颳起渲染的執行緒,等待JavaScript載入完畢後,html檔案再繼續渲染。

因為javascript可能會修改DOM,導致後續的html資源白白載入,所以html必須等待javascript檔案載入完畢後,再繼續渲染。這也就是為什麼javascript檔案要寫在底部body標籤前的原因。

html的渲染過程就是將html程式碼按照深度優先遍歷來生成DOM樹。

css檔案下載完後也會進行渲染,生成相應的CSSOM。

當所有的css檔案下載完且所有的CSSOM構建結束後,就會和DOM一起生成Render Tree。

瀏覽器就會進入Layout環節,將所有的節點位置計算出來。

通過Painting環節將所有的節點內容呈現到螢幕上。

常規流程

  • 瀏覽器下載的順序是從上到下,渲染的順序也是從上到下,下載和渲染是同時進行的。
  • 在渲染到頁面的某一部分時,其上面的所有部分都已經下載完成(並不是說所有相關聯的元素都已經下載完)。
  • 如果遇到語義解釋性的標籤嵌入檔案(JS指令碼,CSS樣式),那麼此時IE的下載過程會啟用單獨連線進行下載。
  • 並且在下載後進行解析,解析過程中,停止頁面所有往下元素的下載。
    樣式表在下載完成後,將和以前下載的所有樣式表一起進行解析,解析完成後,將對此前所有元素(含以前已經渲染的)重新進行渲染。
    JS、CSS中如有重定義,後定義函式將覆蓋前定義函式。

瀏覽器的主要元件包括:

  • 使用者介面-包括位址列、後退/前進按鈕、書籤目錄等,也就是你所看到的除了用來顯示你所請求頁面的主視窗之外的其他部分。

  • 瀏覽器引擎-用來查詢及操作渲染引擎的介面。

  • 渲染引擎-用來顯示請求的內容,例如,如果請求內容為html,它負責解析html及css,並將解析後的結果顯示出來。

  • 網路- 用來完成網路呼叫,例如http請求,它具有平臺無關的介面,可以在不同平臺上工作。

  • UI後端-用來繪製類似組合選擇框及對話方塊等基本元件,具有不特定於某個平臺的通用介面,底層使用作業系統的使用者介面。

  • JS直譯器-用來解釋執行JS程式碼。

  • 資料儲存-屬於持久層,瀏覽器需要在硬碟中儲存類似cookie的各種資料,HTML5定義了web database
    技術(localstorage),這是一種輕量級完整的客戶端儲存技術

相關文章