經常使用哪幾種瀏覽器測試?有哪些瀏覽器內核(Rendering Engine)?javascript
(Q1)瀏覽器:Chrome,IE,FireFox,Safari,Opera。css
(Q2)對應內核:Webkit,Trident,Gecko,Webkit,Presto。(國內的瀏覽器,除了傲遊是直接基於Webkit開發的,其餘基本都是基於谷歌在webkit上開發的Chromium,固然谷歌本身也是用的Chromium。另外值得的一提的是手機的系統(安卓、蘋果)默認瀏覽器都是基於webkit內核的)html
如何理解瀏覽器內核?java
主要分紅兩部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。後來JS引擎愈來愈獨立(好比谷歌的V8引擎),內核就傾向於只指渲染引擎。web
渲染引擎:負責取得網頁的內容(HTML、XML、圖像等等)、整理訊息(例如加入CSS等),以及計算網頁的顯示方式,而後會輸出至顯示器或打印機。瀏覽器的內核的不一樣對於網頁的語法解釋會有不一樣,因此渲染的效果也不相同。全部網頁瀏覽器、電子郵件客戶端以及其它須要編輯、顯示網絡內容的應用程序都須要內核。後端
JS引擎:解析和執行javascript來實現網頁的動態效果。瀏覽器
瀏覽器的渲染過程?緩存
當瀏覽器得到一個html文件時,會「自上而下」加載,並在加載過程當中進行解析渲染。網絡
解析:app
a. 瀏覽器會將HTML解析成一個DOM樹,DOM 樹的構建過程是一個深度遍歷過程:當前節點的全部子節點都構建好後纔會去構建當前節點的下一個兄弟節點。
b. 將CSS解析成 CSS規則樹(Style Rule) 。
c. 根據DOM樹和CSS規則樹來構造 Rendering Tree(渲染樹)。注意:Rendering Tree並不等同於 DOM 樹,由於一些像 Header 或 display:none 的東西就不必放在渲染樹中了。
d. 有了Render Tree,瀏覽器已經能知道網頁中有哪些節點、各個節點的CSS定義以及他們的從屬關係。下一步操做稱之爲Layout(佈局),就是計算出每一個節點在屏幕中的座標。
e. 再下一步就是繪製,即遍歷render樹,並使用UI後端層繪製每一個節點。
關於順序:
上述這個過程是逐步完成的,爲了更好的用戶體驗,渲染引擎將會盡量早的將內容呈現到屏幕上,並不會等到全部的html都解析完成以後再去構建和佈局render樹。它是解析完一部份內容就顯示一部份內容,同時,可能還在經過網絡下載過程遇到的其他內容(好比css、js文件,但遇到js文件會阻塞頁面後續內容,css不會阻塞;另外圖片的下載優先級比較低,通常都會在整個頁面其餘資源下載完了才下載圖片)。
Javascript的加載和執行的特色:
(1)載入後立刻執行;
(2)執行時會阻塞頁面後續的內容(包括頁面的渲染、其它資源的下載)。緣由:由於瀏覽器須要一個穩定的DOM樹結構,而JS中頗有可能有 代碼直接改變了DOM樹結構,好比使用 document.write 或 appendChild,甚至是直接使用的location.href進行跳轉,瀏覽器爲了防止出現JS修 改DOM樹,須要從新構建DOM樹的狀況,因此 就會阻塞其餘的下載和呈現。因此js一般放在頁面尾部,即body結束前。
如何理解Reflow(迴流)和 Repaint(重繪)?
1) 當render tree中的一部分(或所有)由於元素的規模尺寸,佈局,隱藏等改變而須要從新構建。這就稱爲迴流(reflow)。每一個頁面至少須要一次迴流,就是在頁面第一次加載的時候。在迴流的時候,瀏覽器會使渲染樹中受到影響的部分失效,並從新構造這部分渲染樹和layout,完成迴流後,瀏覽器會從新繪製受影響的部分到屏幕中,該過程稱爲重繪。
2) 當render tree中的一些元素須要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響佈局的,好比background-color。則就叫稱爲重繪。
注意:迴流必將引發重繪,而重繪不必定會引發迴流。
3) 當頁面佈局和幾何屬性改變時就須要迴流。下述狀況會發生瀏覽器迴流:
a. 添加或者刪除可見的DOM元素;
b. 元素位置改變;
c. 元素尺寸改變——邊距、填充、邊框、寬度和高度
d. 內容改變——好比文本改變或者圖片大小改變而引發的計算值寬度和高度改變;
e. 頁面渲染初始化;
f. 瀏覽器窗口尺寸改變——resize事件發生時;
4) 聰明的瀏覽器
從上個實例代碼中能夠看到幾行簡單的JS代碼就引發了6次左右的迴流、重繪。並且咱們也知道迴流的花銷也不小,若是每句JS操做都去迴流重繪的話,瀏覽器可能就會受不了。因此不少瀏覽器都會優化這些操做,瀏覽器會維護1個隊列,把全部會引發迴流、重繪的操做放入這個隊列,等隊列中的操做到了必定的數量或者到了必定的時間間隔,瀏覽器就會flush隊列,進行一個批處理。這樣就會讓屢次的迴流、重繪變成一次迴流重繪。
雖然有了瀏覽器的優化,但有時候咱們寫的一些代碼可能會強制瀏覽器提早flush隊列,這樣瀏覽器的優化可能就起不到做用了。當你請求向瀏覽器請求一些 style信息的時候,就會讓瀏覽器flush隊列,好比:
a. offsetTop, offsetLeft, offsetWidth, offsetHeight
b. scrollTop/Left/Width/Height
c. clientTop/Left/Width/Height
d. width,height
e. 請求了getComputedStyle(), 或者 IE的 currentStyle
當你請求上面的一些屬性的時候,瀏覽器爲了給你最精確的值,須要flush隊列,由於隊列中可能會有影響到這些值的操做。即便你獲取元素的佈局和樣式信息跟最近發生或改變的佈局信息無關,瀏覽器都會強行刷新渲染隊列。
5) 如何減小回流、重繪?
① 直接改變className,這樣能多條規則一次性改變;若是動態改變樣式,則使用cssText(考慮沒有優化的瀏覽器)
② 讓要操做的元素進行」離線處理」,處理完後一塊兒更新
a) 使用DocumentFragment進行緩存操做,引起一次迴流和重繪;
b) 使用display:none技術,只引起兩次迴流和重繪;( 只是減小重繪和迴流的次數,display:none 是會引發重繪並回流,相對來講,visibility: hidden只會引發重繪 )
c) 使用cloneNode(true or false) 和 replaceChild 技術,引起一次迴流和重繪;
③ 不要常常訪問會引發瀏覽器flush隊列的屬性,若是你確實要訪問,利用緩存
④ 讓元素脫離動畫流,減小回流的Render Tree的規模。舉例:$("#block1").animate({left:50}); (不過我沒理解)
PS:若是對你有幫助,就順手點個贊吧~