一、簡單介紹一下什麼是浏覽器核心。
浏覽器最重要或者說核心的部分是“Rendering Engine”,可大概譯為“解釋引擎”,不過我們一般習慣将之稱為“浏覽器核心”。負責對網頁文法的解釋(如HTML、JavaScript)并渲染(顯示)網頁。
是以,通常所謂的浏覽器核心也就是浏覽器所采用的渲染引擎,渲染引擎決定了浏覽器如何顯示網頁的内容以及頁面的格式資訊。
不同的浏覽器核心對網頁編寫文法的解釋也有不同,是以同一網頁在不同的核心的浏覽器裡的渲染(顯示)效果也可能不同,這也是網頁編寫者需要在不同核心的浏覽器中測試網頁顯示效果的原因。
浏覽器核心很多,如果加上所有的幾乎沒有什麼人在用的非商業的免費核心,那麼可能大約有10款以上甚至更多,不過通常我們比較常見的大約隻有以下四種,下面先簡單介紹一下。
Trident:
IE浏覽器使用的核心,該核心程式在1997年的IE4中首次被采用,是微軟在Mosaic代碼的基礎之上修 改而來的,并沿用到目前的IE9。
Trident實際上是一款開放的核心,其接口核心設計的相當成熟,是以才有許多 采用IE核心而非IE的浏覽器湧現(如 Maxthon、The World 、TT、GreenBrowser、AvantBrowser等)。
此外, 為了友善也有很多人直接簡稱其為IE核心(當然也不排除有部分人是因為不知道核心名稱而隻好如此說)。
由于IE本身的“壟斷性”(雖然名義上IE并非壟斷,但實際上,特别是從Windows 95年代一直到XP初期,就市場占有率來說IE的确借助Windows的東風處于“壟斷”的地位)而使得Trident核心的長期一家獨大,微軟很長時間都并沒有更新Trident核心,這導緻了兩個後果——一是Trident核心曾經幾乎與W3C标準脫節(2005年),二是Trident核心的大量 Bug等安全性問題沒有得到及時解決,然後加上一些緻力于開源的開發者和一些學者們公開自己認為IE浏覽器不安全的觀點,也有很多使用者轉向了其他浏覽器,Firefox和Opera就是這個時候興起的。非Trident核心浏覽器的市場占有率大幅提高也緻使許多網頁開發人員開始注意網頁标準和非IE浏覽器的浏覽效果問題。
Gecko:
Netscape6開始采用的核心,後來的Mozilla FireFox (火狐浏覽器) 也采用了該核心,Gecko的特點 是代碼完全公開,是以,其可開發程度很高,全世界的程式員都可以為其編寫代碼,增加功能。
因為這是個開源 核心,是以受到許多人的青睐,Gecko核心的浏覽器也很多,這也是Geckos核心雖然年輕但市場占有率能夠迅速 提高的重要原因。
事實上,Gecko引擎的由來跟IE不無關系,前面說過IE沒有使用W3C的标準,這導緻了微軟内部一些開發人員的不滿;他們與當時已經停止更新了的 Netscape的一些員工一起創辦了Mozilla,以當時的Mosaic核心為基礎 重新編寫核心,于是開發出了Geckos。
不過事實上,Gecko 核心的浏覽器仍然還是Firefox (火狐) 使用者最多, 是以有時也會被稱為Firefox核心。
此外Gecko也是一個跨平台核心,可以在Windows、 BSD、Linux和Mac OS X 中使用。
Presto:
目前Opera采用的核心,該核心在2003年的Opera7中首次被使用,該款引擎的特點就是渲染速度的優化達到了極緻,也是目前公認網頁浏覽速度最快的浏覽器核心,然而代價是犧牲了網頁的相容性。
實際上這是一個動态核心,與前面幾個核心的最大的差別就在腳本處理上,Presto有着天生的優勢,頁面的全部或者部分都能夠在回應腳本事件時等情況下被重新解析。
此外該核心在執行Javascrīpt的時候有着最快的速度,根據在同等條件下的測試,Presto核心執行同等Javascrīpt所需的時間僅有Trident和Gecko核心的約1/3(Trident核心最慢,不過兩者相差沒有多大)。 那次測試的時候因為Apple機的硬體條件和普通PC機不同是以沒有測試WebCore核心。
隻可惜Presto是商業引擎,使用Presto的除開Opera以外,隻剩下NDSBrowser、Wii Internet Channle、Nokia 770網絡浏覽器等,這很大程度上限制了Presto的發展。
Webkit:
蘋果公司自己的核心,也是蘋果的Safari浏覽器使用的核心。
Webkit引擎包含WebCore排版引擎及JavaScriptCore解析引擎,均是從KDE的KHTML及KJS引擎衍生而來,它們都是自由軟體,在GPL條約下授權,同時支援BSD系統的開發。 是以Webkit也是自由軟體,同時開放源代碼。在安全方面不受IE、Firefox的制約,是以Safari浏覽器在國内還是很安全的。
限于Mac OS X的使用不廣泛和Safari浏覽器曾經隻是Mac OS X的專屬浏覽器,這個核心本身應該說市場範圍并不大;但似乎根據最新的浏覽器調查表明,該浏覽器的市場甚至已經超過了Opera的Presto了——當然這一方面得益于蘋果轉到x86架構之後的人氣暴漲,另外也是因為Safari 3終于推出了Windows版的緣故吧。
Mac下還有OmniWeb、Shiira等人氣很高的浏覽器。
google的chrome也使用webkit作為核心。
WebKit 核心在手機上的應用也十分廣泛,例如 Google 的手機 Gphone、 Apple 的 iPhone, Nokia’s Series 60 browser 等所使用的 Browser 核心引擎,都是基于 WebKit。
// 比如檢測一下獵豹浏覽器(雙核) http://ie.icoa.cn/
PC的浏覽器核心主要就是這幾個,那手機浏覽器是基于什麼核心呢?
目前微軟的Trident在移動終端上主要為WP系統内置浏覽器,Webkit核心的适用範圍則較為廣泛,Android原生浏覽器、蘋果的Safari、谷歌的Chrome(Android4.0使用)都是基于Webkit開源核心開發的。
從實際情況出發:
對于Android手機而言,使用率最高的就是Webkit核心,我們看到很多手機浏覽器廠商都宣稱有着自主核心,比如手機UC就号稱采用了U3核心、而華為也經常标榜自己的天天浏覽器采用了T9核心,事實上,他們都是基于開源核心Webkit進行二次開發的,并不是完全的自主核心。
而在iOS以及WP7平台上,由于系統封閉,不允許除系統自帶浏覽器核心以外的浏覽器核心進入,是以各家浏覽器的開發均為在Safari或者IE核心的基礎上進行二次開發,優化功能和自制UI。
比如海豚、遨遊等浏覽器就是直接采用系統自帶浏覽器的核心,這點從這幾款浏覽器的HTML5評分與系統自帶浏覽器評分結果完全一緻就可以看出。
核心并無手機與PC的區分,手機浏覽器的核心與PC浏覽器類似,例如:
- IE手機版和PC版都是Trident核心的;
- Opera手機版和PC版都是Presto核心的(自從2013年2月13日Opera宣布放棄Presto核心轉向Webkit核心後,已出現部分Webkit核心的Opera手機浏覽器測試版);
- Firefox手機版和PC版都是Gecko核心的;
- Chrome、Safari手機版和PC版都是Webkit核心的。
至于國内的UC和QQ等手機浏覽器也都是根據Webkit修改過來的核心。
--------------- 另一個關于浏覽器核心的說明 -----------------
可以直接去 維基百科 看看
一、排版引擎
首先厘清一下浏覽器核心是什麼東西。
英文叫做:Rendering Engine,中文翻譯很多,排版引擎、解釋引擎、渲染引擎,現在流行稱為浏覽器核心,至于為什麼流行這麼稱呼,請自行領悟。
Rendering Engine,顧名思義,就是用來渲染網頁内容的,将網頁的内容和排版代碼轉換為可視的頁面。因為是排版,是以肯定會排版錯位等問題。為什麼會排版錯位呢?有的是由于網站本身編寫不規範,有的是由于浏覽器本身的渲染不标準。
現在有幾個主流的排版引擎,因為這些排版引擎都有其代表的浏覽器,是以常常會把排版引擎的名稱和浏覽器的名稱混用,比如常的說IE核心、Chrome核心。其實這樣子是不太合理的,因為一個完整的浏覽器不會隻有一的排版引擎,還有自己的界面架構和其它的功能支撐,而排版引擎本身也不可能實作浏覽器的所有功能。下面羅列一下幾款主流的排版引擎和浏覽器。
1、Trident(Windows)
IE浏覽器所使用的核心,也是很多浏覽器所使用的核心,通常被稱為IE核心。基于Trident核心的浏覽器非常多,這是因為Trident核心提供了豐富的調用接口。老的Trident核心(比如常說的IE6核心)一直是不遵循W3C标準的,但是由于它的市場佔有率最大,是以後果就是大量的網站隻支援老的Trident核心,依據W3C标準寫的網頁在老的Trident核心下面又出現偏差。目前可供調用的最新版的Trident核心是IE9所用的核心,相較之前的版本對W3C标準的支援增強了很多。
Trident核心的浏覽器:
IE6、IE7、IE8(Trident 4.0)、IE9(Trident 5.0)、IE10(Trident 6.0);
世界之窗1、世界之窗2、世界之窗3;
360安全浏覽器1、360安全浏覽器2、360安全浏覽器3、360安全浏覽器4、360安全浏覽器5;
傲遊1、傲遊2;搜狗浏覽器1;騰訊TT;阿雲浏覽器(早期版本)、百度浏覽器(早期版本)、瑞星安全浏覽器、Slim Browser;
GreenBrowser、愛帆浏覽器(12 之前版本)、115浏覽器、155浏覽器;
閃遊浏覽器、N氧化碳浏覽器、糖果浏覽器、彩虹浏覽器、瑞影浏覽器、勇者無疆浏覽器、114浏覽器、螞蟻浏覽器、飛騰浏覽器、速達浏覽器、佐羅浏覽器;
2、Gecko(跨平台)
Netscape6啟用的核心,現在主要由Mozilla基金會進行維護,是開源的浏覽器核心,目前最主流的Gecko核心浏覽器是Mozilla Firefox,是以也常常稱之為火狐核心。因為Firefox的出現,IE的霸主地位逐漸被削弱,Chrome的出現則是加速了這個程序。非Trident核心的興起正在改變着整個網際網路,最直接的就是推動了編碼的标準化,也使得微軟在競争壓力下不得不改進IE。不過比較可惜的是,雖然是開源的,也開發了這麼多年,基于Gecko的浏覽器并不多見,除了一些簡單的改動(坑爹的X浏覽器)或者是重新編譯(绫川ayakawa、tete009),深度定制或者增強型外殼的還比較少見。另外就是有一些其它軟體借用了Gecko核心,比如音樂管理軟體SongBird。
常見的Gecko核心的浏覽器
Mozilla Firefox、Mozilla SeaMonkey
Epiphany(早期版本)、Flock(早期版本)、K-Meleon
3、KHTML(Linux)
KDE開發的核心,速度快捷,容錯度低。這個核心可能不見得很多人知道,但是後面再看下去你就明白了。
常見的KHTML核心的浏覽器:Konqueror
4、WebKit(跨平台)
由KHTML發展而來,也是蘋果給開源世界的一大貢獻。是目前最火熱的浏覽器核心,火熱倒不是說市場佔有率,而是應用的面積和勢頭。因為是脫胎于KHTML,是以也是具有高速的特點,同樣遵循W3C标準。
常見的WebKit核心的浏覽器:Apple Safari、Symbian系統浏覽器
5、Chromium(跨平台)
維基百科裡面并沒有将Chromium從WebKit分出來,這個區分完全是基于我個人的惡趣味。記得以前看過一個大牛的博文說過,Chromium把WebKit的代碼梳理得可讀性提高很多,是以以前可能需要一天進行編譯的代碼,現在隻要兩個小時就能搞定。這個我自己也沒有考究過,但是估計可信。這個也能解釋為什麼Gecko和WebKit出來了這麼久,第三方編譯、定制的版本并不多,但是由Chromium衍生出來的浏覽器早就滿坑滿谷了。
常見的Chromium核心的浏覽器:Chromium、Google Chrome、SRWare Iron、Comodo Dragon
6、Presto(跨平台)
Opera的核心,準确地說,是Opera 7.0及以後版本的核心,Opera 3.5-6.1版本使用的核心叫做Elektra。不用說,Presto對W3C标準的支援也是很良好的。雖然我很喜歡Opera,但是我對Presto的渲染速度一直有保留态度。之前在OperaChina論壇看見有人說過,Presto優先解析文字,保證可閱讀性,媒體資源的渲染放後。
常見的Presto核心的浏覽器:Opera
7、其它
http://zh.wikipedia.org/wiki/排版引擎
二、JavaScript引擎
說完了排版引擎,接下來說說JavaScript引擎。顧名思義,JavaScript引擎就是用來渲染JavaScript的。
為什麼要單獨拿出來說呢?因為它涉及到跑分。經常看見很多文章在報道說哪個浏覽器更快,其實大部分說的就是JavaScript的渲染速度,而不是頁面的載入速度。在網速許可的情況下,其實各個浏覽器的頁面載入速度差别不大(Opera遜色一些)。那是不是說對比JavaScript的渲染速度其實沒有意義?也不是這麼說,因為現在JavaScript在頁面中的比重會越來越大,越來越多的動态頁面開始大量借助JavaScript,比如現在主流的SNS、郵箱、網頁遊戲,是以JavaScript的渲染速度也是一個很重要的名額。
JavaScript的渲染速度越快,動态頁面的展示也越快。Opera在JavaScript引擎的跑分上面一直都是很牛逼的,一般來說最新測試版之間PK,Opera基本都會奪冠。
1、Chakra
查克拉,IE9啟用的新的JavaScript引擎。
2、SpiderMonkey/TraceMonkey/JaegerMonkey
SpiderMonkey應用在Mozilla Firefox 1.0-3.0,TraceMonkey應用在Mozilla Firefox 3.5-3.6版本,JaegerMonkey應用在Mozilla Firefox 4.0及後續的版本。
3、V8
應用于Chrome、傲遊3。
4、Nitro
應用于Safari 4及後續的版本。
5、Linear A/Linear B/Futhark/Carakan
Linear A應用于Opera 4.0-6.1版本,Linear B應用于Opera 7.0~9.2版本,Futhark應用于Opera 9.5-10.2版本,Carakan應用于Opera 10.5及後續的版本。
6、KJS
KHTML對應的JavaScript引擎。
三、幾個測試
1、V8引擎
http://v8.googlecode.com/svn/data/benchmarks/v6/run.html
現在很多“雙核”浏覽器都用它來跑分測試JavaScript引擎,分數越高越好。
2、Acid3
http://acid3.acidtests.org/
标準支援測試,分數越高越好,滿分是100分。
3、HTML5
http://www.html5test.com/
測試浏覽器對HTML5标準的支援,分數越高越好。
四、幾個奇葩
1、IETab
在沒有第三方編譯版本的時候,IETab一直是Mozilla Firefox、Chrome等非Trident核心的浏覽器的安裝量最大的擴充之一,友善使用者在不開啟IE的情況下調用Trident核心通路一些相容性比較差的網站。
2、Trident/Gecko雙核浏覽器
雖然IETab能實作部分需求,但是深度訂制的畢竟還是不一樣,是以Trident/Gecko雙核浏覽器就誕生了,Sleipnir、Avant 12(Orca)是這類裡面比較常見的。Avant 12因為有Orca的前期積累,是以輕車熟路,後面還打算加入Chromium,變成三核浏覽器,但是偏偏現在Mozilla Firefox和Chrome都在瘋狂刷版本号,肯定有一部分精力要花在跟進版本上。
3、Trident/WebKit雙核浏覽器
現在國内最主流的“雙核”浏覽器基本都是這個架構,360極速浏覽器、世界之窗浏覽器極速版、傲遊3搜狗浏覽器3、QQ浏覽器、楓樹浏覽器、快快浏覽器、百度浏覽器、阿雲浏覽器(後期版本)、太陽花浏覽器,其中最奇葩的是傲遊3。其它雙核浏覽器都是基于Chromium的,而傲遊是基于WebKit的,但是偏偏又用的是V8引擎。
4、Trident/Gecko/WebKit三核浏覽器
目前能見的應該就是日本的Lunascape,Avant增加了WebKit核心之後也會歸類到這裡。說實話,Lunascape真的很難用,真的很奇葩。各個核心相對獨立,外殼本身不夠強化,穩定性不高,是以還不如用回單核浏覽器。
五、幾個小點
1、Chrome/Chromium
很多人都會說自己用的雙核浏覽器是Chrome/IE雙核的,或者說是基于Chrome的。其實這種說法并不正确,因為Chrome本身并不開源,其它廠商是不能去定制Chrome的。能被修改、定制的是Chromium,Chrome的開源開發版本,代碼和Build都提供下載下傳。Chromium/Chrome兩個單詞都是鉻,分别是拉丁文和英文,除了名字之外,很有很多不同,你可以自己對比一下。
Chromium一天最多可以更新十幾二十個版本,實驗性的新特性都會現在這裡放出,但是Chromium本身其實并不穩定。
Chrome總共有四個更新分支:Canary、Dev、Beta、Stable,穩定性依次增強。
2、MyIE、MyIE2、傲遊、GreenBrowser
自行搜尋,一段曆史。
3、頁面相容性判斷
在確定IE浏覽器沒有損壞的基礎上,搭配一款非Trident核心的浏覽器進行判斷,如果可以的話,最好所有核心都配齊了。
控制變量就能找到問題所在,是浏覽器本身的問題,還是頁面編碼有問題。對于使用者來說就能更好地去選擇自己該用什麼浏覽器通路什麼頁面,對于開發者來說應該要寫出無差别代碼。
4、一直被模仿,一直被超越的Opera
Opera其實很好看也很好用,而且極度創新,但是市場占有率一直很低。很多很好用的新特性總是被抄襲,是以大家笑稱Opera“一直被模仿,一直被超越”。坊間傳聞多标簽頁浏覽器就是Opera發明的,但是貌似有人考究了這個傳聞其實不屬實。不過快速撥号、Turbo浏覽等功能就是紮紮實實Opera首創的。你可以不用Opera,但是你會損失很多樂趣。
5、這年頭流行刷版本号
現在版本号最高的浏覽器是Chrome,穩定版的版本号是14,也是現在主流浏覽器裡面誕生時間最短的,真是一個刷版本号高手。早期的Chrome版本更疊還會增加一些比較重要的新特性,比如擴充支援,現在的版本更疊基本上并沒有伴随什麼大的更新。現在很多僞高端使用者就會整天追着第三方編譯版本趕緊跟進版本号,但是其實真正的意義并不大。
多虧了Chrome的“提攜”,今年Firefox也在猛刷版本号,年初還是3.x,現在正式版已經是7.0.1,每夜版已經到了10.0。Opera積累了多年才到11.50,測試版是12.0。IE的正式版是9,平台預覽版是10。
6、檢視源代碼、開發者工具
一般來說,檢視源代碼和使用開發者工具是比較實用的,可能用的機會并不多,但是在判斷一些問題的時候其實是很有用的。通過檢視源代碼或者使用開發者工具,可以大緻了解這些網站裡面的一些元素或者加載的腳本或者是規則,對于判斷相容性問題有一定的幫助,也可以用來準确捕捉頁面元素。
7、幾個主要的浏覽器官網以及版本下載下傳
(1)Internet Explorer
官網:
http://windows.microsoft.com/zh-CN/internet-explorer/products/ie/home
IE7下載下傳:
http://www.microsoft.com/downloads/zh-cn/details.aspx?displaylang=zh-cn&FamilyID=9ae91ebe-3385-447c-8a30-081805b2f90b
IE8下載下傳:
http://windows.microsoft.com/zh-CN/internet-explorer/downloads/ie-8
IE9下載下傳:
http://windows.microsoft.com/zh-CN/internet-explorer/downloads/ie-9/worldwide-languages
(2)Mozilla Firefox
官網:
http://firefox.com.cn/
7.x Release:
http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest/win32/zh-CN/
8.x Candidates:
http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/8.0b1-candidates/build1/win32/zh-CN/
9.x Aurora:
http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-mozilla-aurora/
10.x Nightly:
http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-trunk/
(3)Apple Safari
官網:
http://www.apple.com.cn/safari/
下載下傳:
http://www.apple.com.cn/safari/download/
(4)Chromium
官網:
http://www.chromium.org/
下載下傳:
http://build.chromium.org/f/chromium/snapshots/Win_Webkit_Latest/
(5)Google Chrome
官網:
http://www.google.com/chrome?hl=zh-cn
Stable線上安裝包:
http://www.google.com/chrome/eula.html?hl=zh-cn
Beta線上安裝包:
http://www.google.com/chrome/eula.html?hl=zh-CN&extra=betachannel
Dev線上安裝包:
http://www.google.com/chrome/eula.html?hl=zh-CN&extra=devchannel
Canary線上安裝包:
http://www.google.com/chrome/eula.html?hl=zh-CN&extra=canarychannel
Stable離線安裝包:
http://www.google.com/chrome/eula.html?hl=zh-CN&standalone=1
Beta離線安裝包:
http://www.google.com/chrome/eula.html?hl=zh-CN&standalone=1&extra=betachannel
Dev離線安裝包:
http://www.google.com/chrome/eula.html?hl=zh-CN&standalone=1&extra=devchannel
Canary離線安裝包:
http://www.google.com/chrome/eula.html?hl=zh-CN&standalone=1&extra=canarychannel
(6)Opera
官網:
http://www.opera.com/
正式版:
http://www.opera.com/download/
測試版:
http://snapshot.opera.com/windows/latest
----------------- 隔 ----------------
二、浏覽器渲染原理
Web頁面運作在各種各樣的浏覽器當中,浏覽器載入、渲染頁面的速度直接影響着使用者體驗簡單地說,頁面渲染就是浏覽器将html代碼根據CSS定義的規則顯示在浏覽器視窗中的這個過程。
先來大緻了解一下浏覽器都是怎麼幹活的:
1. 使用者輸入網址(假設是個html頁面,并且是第一次通路),浏覽器向伺服器送出請求,伺服器傳回html檔案;
2. 浏覽器開始載入html代碼,發現<head>标簽内有一個<link>标簽引用外部CSS檔案;
3. 浏覽器又發出CSS檔案的請求,伺服器傳回這個CSS檔案;
4. 浏覽器繼續載入html中<body>部分的代碼,并且CSS檔案已經拿到手了,可以開始渲染頁面了;
5. 浏覽器在代碼中發現一個<img>标簽引用了一張圖檔,向伺服器送出請求。此時浏覽器不會等到圖檔下載下傳完,而是繼續渲染後面的代碼;
6. 伺服器傳回圖檔檔案,由于圖檔占用了一定面積,影響了後面段落的排布,是以浏覽器需要回過頭來重新渲染這部分代碼;
7. 浏覽器發現了一個包含一行Javascript代碼的<script>标簽,趕快運作它;
8. Javascript腳本執行了這條語句,它指令浏覽器隐藏掉代碼中的某個(style.display=”none”)。杯具啊,突然就少了這麼一個元素,浏覽器不得不重新渲染這部分代碼;
9. 終于等到了</html>的到來,浏覽器淚流滿面……
10. 等等,還沒完,使用者點了一下界面中的“換膚”按鈕,Javascript讓浏覽器換了一下<link>标簽的CSS路徑;
11. 浏覽器召集了在座的各位
<span><ul><li>們,“大夥兒收拾收拾行李,咱得重新來過……”,浏覽器向伺服器請求了新的CSS檔案,重新渲染頁面。
浏覽器每天就這麼來來回回跑着,要知道不同的人寫出來的html和css代碼品質參差不齊,說不定哪天跑着跑着就挂掉了。
好在這個世界還有這麼一群人——頁面重構工程師,平時挺不起眼,也就幫視覺設計師們切切圖啊改改字,其實背地裡還是幹了不少實事的。
說到頁面為什麼會慢?那是因為浏覽器要花時間、花精力去渲染,尤其是當它發現某個部分發生了點變化影響了布局,需要倒回去重新渲染,内行稱這個回退的過程叫reflow。
reflow幾乎是無法避免的。現在界面上流行的一些效果,比如樹狀目錄的折疊、展開(實質上是元素的顯示與隐藏)等,都将引起浏覽器的 reflow。
滑鼠滑過、點選……隻要這些行為引起了頁面上某些元素的占位面積、定位方式、邊距等屬性的變化,都會引起它内部、周圍甚至整個頁面的重新渲染。
通常我們都無法預估浏覽器到底會reflow哪一部分的代碼,它們都彼此互相影響着。
reflow問題是可以優化的,我們可以盡量減少不必要的reflow。
比如開頭的例子中的<img>圖檔載入問題,這其實就是一個可以避免的reflow——給圖檔設定寬度和高度就可以了。
這樣浏覽器就知道了圖檔的占位面積,在載入圖檔前就預留好了位置。
另外,有個和reflow看上去差不多的術語:repaint,中文叫重繪。
如果隻是改變某個元素的背景色、文字顔色、邊框顔色等等不影響它周圍或内部布局的屬性,将隻會引起浏覽器repaint。
repaint的速度明顯快于 reflow(在IE下需要換一下說法,reflow要比repaint 更緩慢)。
三、從浏覽器的渲染原理講CSS性能
平時我們幾乎每天都在和浏覽器打交道,寫出來的頁面很有可能在不同的浏覽器下顯示的不一樣。苦逼的前端攻城師們為了相容各個浏覽器而不斷地去測試和調試,還在腦子中記下各種遇到的BUG及解決方案,而我們好像并沒有去主動地關注和了解下浏覽器的工作原理。
如果我們對此做一點了解,我想在項目過程中就可以根據它有效的避免一些問題以及對頁面性能做出相應的改進。
今天我們主要根據浏覽器的渲染原理對CSS的書寫性能做一點改進(當然還有JS本篇文章暫不考慮,後面的文章會做介紹),下面讓我們一起來揭開浏覽器的渲染原理這一神秘的面紗吧:
最終決定浏覽器表現出來的頁面效果的差異是:渲染引擎 Rendering Engine(也叫做排版引擎),也就是我們通常所說的“浏覽器核心”,負責解析網頁文法(如HTML、JavaScript)并渲染、展示網頁。相同的代碼在不同的浏覽器呈現出來的效果不一樣,那麼就很有可能是不同的浏覽器核心導緻的。
我們來看一下加載頁面時浏覽器的具體工作流程(圖一):
(圖一)
1、解析HTML以重建DOM樹(Parsing HTML to construct the DOM tree ):渲染引擎開始解析HTML文檔,轉換樹中的标簽到DOM節點,它被稱為“内容樹”。
2、建構渲染樹(Render tree construction):解析CSS(包括外部CSS檔案和樣式元素),根據CSS選擇器計算出節點的樣式,建立另一個樹 —- 渲染樹。
3、布局渲染樹(Layout of the render tree): 從根節點遞歸調用,計算每一個元素的大小、位置等,給每個節點所應該出現在螢幕上的精确坐标。
4、繪制渲染樹(Painting the render tree) : 周遊渲染樹,每個節點将使用UI後端層來繪制。
主要的流程就是:建構一個dom樹,頁面要顯示的各元素都會建立到這個dom樹當中,每當一個新元素加入到這個dom樹當中,浏覽器便會通過css引擎查遍css樣式表,找到符合該元素的樣式規則應用到這個元素上。
注意了:css引擎查找樣式表,對每條規則都按從右到左的順序去比對。
看如下規則:
1 | #nav li {} |
---|
看起來很快,實際上很慢,盡管這讓人有點費解#_#。
我們中的大多數人,尤其是那些從左到右閱讀的人,可能猜想浏覽器也是執行從左到右比對規則的,是以會推測這條規則的開銷并不高。
在腦海中,我們想象浏覽器會像這樣工作:找到唯一的ID為nav的元素,然後把這個樣式應用到直系子元素的li元素上。
我們知道有一個ID為nav的元素,并且它隻有幾個Li子元素,是以這個CSS選擇符應該相當高效。
事實上,CSS選擇符是從右到左進行比對的。了解這方面的知識後,我們知道這個之前看似高效地規則實際開銷相當高,浏覽器必須周遊頁面上每個li元素并确定其父元素的id是否為nav。
1 | *{} |
---|
額,這種方法我剛寫CSS的也寫過,殊不知這種效率是差到極點的做法,因為*通配符将比對所有元素,是以浏覽器必須去周遊每一個元素,這樣的計算次數可能是上萬次!
1 | ul#nav{} ul.nav{} |
---|
在頁面中一個指定的ID隻能對應一個元素,是以沒有必要添加額外的限定符,而且這會使它更低效。同時也不要用具體的标簽限定類選擇符,而是要根據實際的情況對類名進行擴充。例如把ul.nav改成.main_nav更好。
1 | ul li li li .nav_item{} |
---|
對于這樣的選擇器,之前也寫過,最後自己也數不過來有多少後代選擇器了,何不用一個類來關聯最後的标簽元素,如.extra_navitem,這樣隻需要比對class為extra_navitem的元素,效率明顯提升了
對此,在CSS書寫過程中,總結出如下性能提升的方案:
- 避免使用通配規則 如 *{} 計算次數驚人!隻對需要用到的元素進行選擇
- 盡量少的去對标簽進行選擇,而是用class 如:#nav li{},可以為li加上nav_item的類名,如下選擇.nav_item{}
- 不要去用标簽限定ID或者類選擇符 如:ul#nav,應該簡化為#nav
- 盡量少的去使用後代選擇器,降低選擇器的權重值 後代選擇器的開銷是最高的,盡量将選擇器的深度降到最低,最高不要超過三層,更多的使用類來關聯每一個标簽元素
- 考慮繼承 了解哪些屬性是可以通過繼承而來的,然後避免對這些屬性重複指定規則
選用高效的選擇符,可以減少頁面的渲染時間,進而有效的提升使用者體驗(頁面越快,使用者當然越喜歡^_^),你可以看一下CSS selectors Test,這個實驗的重點是評估複雜選擇符和簡單選擇符的開銷。
也許當你想讓渲染速度最高效時,你可能會給每個獨立的标簽配置一個ID,然後用這些ID寫樣式。那的确會超級快,也超級荒唐!這樣的結果是語義極差,後期的維護難到了極點。
但說到底,CSS性能這東西對于小的項目來講可能真的是微乎其微的東西,提升可能也不是很明顯,但對于大型的項目肯定是有幫助的。而且一個好的CSS書寫習慣和方式能夠幫助我們更加嚴謹的要求自己。
--------------------------- 原文 -----------------------------