版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、網站性能,刻不容緩??!三大因素:CSS、IMAGES、JS,主講人:侯彪,CSS也有性能開銷華麗的外衣--IMAGESJS優(yōu)化幾則雜談---DOM的加載也有SEO的技巧,CSS也有性能開銷,網站性能一說讓多數的人第一時間想起的是javascript,但對于一個WEB來說同樣重要的CSS呢?你會考慮到他的性能開銷嗎?ul#my_list > li{color:#f00}理解一下CSS選擇符的概念,把樣式表放在標簽中以提升
2、頁面的逐步渲染速度。不要在IE中使用CSS Expression,因為他會被執(zhí)行到很多次,你想知道是多少嗎?好的,以萬為單位,甚至可以搞死你的IE!避免或杜絕使用行內樣式,因為這會增加下載頁面的大小,并搞亂你的CSS權重。,在前輩們的指點下,關于CSS的最佳性能實踐大致總結了如下幾點:,CSS也有性能開銷,怎么樣這些很容易理解吧。不過……以上幾點已經不能滿足我們追求性能的野心了。于是更多的CSS性能規(guī)則開始展現他們的力量!,CSS
3、也有性能開銷,ID選擇符 #toc{margin-left:20px}類選擇符 .chapter{font-weight:bold}類型選擇符 a{text-decoration:none}相鄰兄弟選擇符 h1 + #toc{margin-top:40px}子選擇 #toc > li{font-weight:bold}后代選擇符 #toc a{color:#333}通配選擇符 *{font-family:
4、Arial}屬性選擇符 [href="#index"]{font-style:italic}偽類和偽元素 a:hover{text:decoration:underline},CSS也有性能開銷,最右邊優(yōu)先!??!#toc > li{font-weight:bold}瀏覽器并不是從左到右的順序來解析CSS選擇符,所以,看看上面這個本以為很高效的選擇符,瀏覽器先要遍歷DOM中所有的li標簽,并確定他的父
5、級元素為#toc。#toc a{color:#333}看看這個 豈不是更糟糕!,CSS也有性能開銷,知道了選擇符的匹配順序,我們便有了如下的更具體的優(yōu)化法則!避免使用通配規(guī)則 *不要限定ID選擇符 div#wrap不要限定類選擇符 li.ele to .list_ele讓規(guī)則越具體越好 ol li a to .list_link避免使用后代選擇符 ul li避免使用子選擇符 ul > li > a質疑子選擇
6、符的所有用途 盡可能使用具體的類依靠繼承,華麗的外衣--IMAGES,搞清楚你要處理的圖片類型圖形 VS 圖像(照片),華麗的外衣--IMAGES,圖形:一般來說,網站的LOGO,草圖,手稿圖和部分ICON圖標都屬于圖形,這些通常由連續(xù)的線條或其他尖銳的顏色過渡,顏色數量相對較少。,華麗的外衣--IMAGES,圖像(照片):百萬數量級的顏色,包含平滑的顏色過渡和漸變,比如網站的KV輪播圖,數碼相機拍出來的產品圖。,華麗的外衣--
7、IMAGES,華麗的外衣--IMAGES,華麗的外衣--IMAGES,華麗的外衣--IMAGES,三種不同的圖片格式JPEG GIF PNG(此處只考慮PNG8)相關的系統知識這里不再闡述,有興趣的自己上百度GOOGLE一下以下介紹重點的屬性!,華麗的外衣--IMAGES,JPEG:有損:它是一種有損的格式,用戶可以設置自定義質量級別,這個級別決定了有多少圖像信息會被拋棄。級別從0-100,但即便是100也同樣會有一定程度的質量
8、損耗。當我們要對一個圖像反復編輯時,比如隨時都會往里邊繼續(xù)加新圖的CSS精靈,最好使用無損的格式來保存中間結果,然后在最終結果的時候存為JPEG格式,否則你將在每次保存為JPEG的時候都損耗一些質量。,華麗的外衣--IMAGES,JPEG:但也有少數操作是無損的:以90的倍數進行旋轉的時候裁剪水平翻轉或垂直翻轉從標準模式切換到漸進模式 反之亦然編輯圖像的元數據此格式不支持透明和動畫,華麗的外衣--IMAGES,GIF:
9、GIF是無損的,也就是說你可以打開任意一個GIF文件,做一些修改,保存關閉時不會損失任何質量。透明,允許一個二進制透明,每個像素要么完全透明 要么完全不透明 這就意味著他不支持alpha透明。取而代之的是,調色板中的某個顏色可以被標記為表示透明,而透明像素則會被分配為這個顏色值,所以,如果你為GIF設置了透明像素,那么就會消耗一個調色板條目。,華麗的外衣--IMAGES,GIF:動畫,GIF支持“逐幀動畫”。應用最廣的當屬LOADI
10、NG256色限制。逐行掃描,當生成一個GIF文件時,會使用一個壓縮算法LZW來減小文件的大小,壓縮GIF文件時,會從上到下一行一行的對像素進行掃描,這種情況下,當圖像在水平方向有很多重復顏色時,可以獲得更好的壓縮效果。如下圖:,華麗的外衣--IMAGES,1.77 KB,華麗的外衣--IMAGES,3.84 KB,華麗的外衣--IMAGES,PNG:為了彌補GIF文件的缺點,并規(guī)避LZW算法的專利問題(2004年已經過了保護期)P
11、NG文件誕生!你可以使用PNG8代替不需要動畫的GIF并用PNG24或32來代替JPEG!PNG是無損的圖像格式。多次編輯不會降低其質量,這使得采用PNG格式來存儲中間格式非常合適。比如我們網站的品牌旗艦館的LOGO就是用PNG8來保存的,每次有新品牌的時候直接在PNG上操作,存儲完畢不會有任何的消耗,如果是JPEG那保存幾次就完了。如下圖:,華麗的外衣--IMAGES,華麗的外衣--IMAGES,今天又添加了新的品牌 使用PNG無損
12、直接在原圖上進行添加,華麗的外衣--IMAGES,PNG:透明。PNG8支持和GIF一樣的二進制透明,PNG24支持alpha透明逐行掃描。和GIF格式一樣,但是壓縮比更高!如下圖,華麗的外衣--IMAGES,2.14 KB,華麗的外衣--IMAGES,就圖像格式而言,GIF通常用于顯示圖形,JPEG更適合顯示圖片,而PNG則兩者都適合。和GIF相比:用PNG來代替GIF(不帶動畫)會更好,文件大小也更小,并且具備除動畫以外的所
13、有GIF特性,所以應該盡量以PNG8代替GIF。有一個例外就是顏色數很少的小圖像,這時GIF的壓縮比可能更高一些,但是這樣的小圖片應該被放在了CSS精靈中,因為HTTP的請求增加已經遠遠超過節(jié)省的那點帶寬,而且用PNG來保存CSS精靈可以獲得更高的壓縮比。,華麗的外衣--IMAGES,和JPEG相比:當圖像中的顏色超過256時,需要使用真彩色圖像格式---PNG24或JPEG。JPEG的壓縮比更高,而且一般來說JPEG也是照片存儲
14、的實際標準。但由于JPEG是有損的而且在清晰的顏色過渡周圍會有大色塊,因此以下2種情況更適合PNG,華麗的外衣--IMAGES,和JPEG相比:當圖像的顏色略超過256種,可以在不損耗任何可見質量的前提下,將圖像轉換為PNG8,雖然有時存儲為PNG8會使得顏色數量減少,但是有時就算本身有1000種顏色,當你存儲為256種顏色的時候也看不出什么特別明顯的變化。如下圖,華麗的外衣--IMAGES,JPEG 80品質190 KB,華麗的外衣
15、--IMAGES,JPEG 100品質351 KB,華麗的外衣--IMAGES,PNG8 114 KB,華麗的外衣--IMAGES,和JPEG相比:當圖片很容易因為壓縮產生大色塊并且大色塊變得不可接受時。如下圖,華麗的外衣--IMAGES,JS優(yōu)化幾則,4種數據存儲位置局部變量最快循環(huán)JS與DOM那扯不斷理還亂的關系,JS優(yōu)化幾則,4種數據存儲位置直接量 數字 字符串 boolen 對象 數組 函數 正則 null undef
16、ined變量 var...數組元素 數字為索引對象成員 字符串為索引直接量和局部變量的訪問速度快于后邊2個FF3是個例外,他優(yōu)化了數組項的存取,但是通常的建議是,如果在乎速度 那么盡量使用直接量或局部變量 減少數組項和對象成員的使用。,JS優(yōu)化幾則,局部變量最快每個JS函數都是表示為一個對象,更確切的說是function對象的一個實例,function對象同其他對象一樣,擁有可以編程訪問的屬性,和一些列不能通過代碼僅供JS引
17、擎存取的內部屬性。其中一個內部屬性是【scope】內部屬性【scope】包含了一個 函數被創(chuàng)建的作用域中 對象的集合,這個集合被稱為函數的作用域鏈,它決定哪些數據能被函數訪問。當一個函數創(chuàng)建后,它的作用域鏈會被 創(chuàng)建此函數的作用域中 可訪問的數據對象 所填充。function add(a,b){ var sum = a + b; return sum; }函數add創(chuàng)建時,他的作用域鏈中填入了一個單獨的可變對象,這個全局對象表示所
18、有全局范圍定義的變量。包含WINDOW,DOCUMENT,NAVIGATOR等等全局對象。,JS優(yōu)化幾則,局部變量最快下面開始執(zhí)行 var num = add(10,20);執(zhí)行此函數會創(chuàng)建一個稱為 運行期上下文 的內部對象。一個運行期上下文定義了一個函數執(zhí)行時的環(huán)境。函數每次執(zhí)行時對應的執(zhí)行期上下文都是獨一無二的,所以多次調用同一個函數就會導致創(chuàng)建多個運行期上下文。當函數執(zhí)行完畢,對應的運行期上下文就被銷毀。每個運行期上下文都有
19、自己的作用域鏈,用于標識符解析。當運行期上下文被創(chuàng)建時,它的作用域鏈初始化為當前運行函數的[scope]屬性中所包含的對象。這些值按照他們出現在函數中的順序,被復制到運行期上下文的作用域鏈中。這個過程一旦OK,一個被稱為 活動對象 的新對象就為運行期上下文創(chuàng)建好了?;顒訉ο笞鳛楹瘮颠\行期的可變對象,包含了所有局部變量,命名參數,參數集合 以及 this。然后此對象被推入作用域鏈的前端。當運行期上下文被銷毀,活動對象也隨之銷毀。,JS優(yōu)化
20、幾則,局部變量最快在函數執(zhí)行過程中,每遇到一個變量,都會經歷一次標識符解析過程以決定從哪里獲取或存儲數據。該過程搜索運行期上下文的作用域鏈,查找同名的表示符。搜索過程從作用域鏈頂部開始,也就是當前運行函數的活動對象。如果找到了,就使用這個標識符對應的變量;如果沒找到,繼續(xù)搜索作用域鏈中的下一個對象。搜索過程會持續(xù)進行,直到標識符被找到,或者沒有可用于搜索的對象為止,這種情況下標識符被認定是為定義的。is not defined 。函數
21、執(zhí)行過程中,每個標識符都要經歷這樣的搜索過程。正是這個搜索過程影響著他的性能!如果名字相同的2個變量存在于作用域鏈的不同部分,那么標識符就是遍歷作用域鏈時最先找到的那個,也可以說,第一個找到的遮蔽了第二個。,JS優(yōu)化幾則,局部變量最快在運行期上下文的作用域鏈中,一個標識符所在的位置越深,它的讀寫速度也就越慢。SO 函數中讀取局部變量總是最快的,而全局變量是最慢的,因為全局的總是存在于運行期上下文作用域鏈的最末端!一個好的經驗法則就
22、是,如果一個跨作用域的值在函數中被引用一次以上,那么就把它存儲到局部變量里。臨時改變作用域鏈 with與try catch 但是不推薦使用,除非你的項目實在有需求。,JS優(yōu)化幾則,局部變量最快說了以上這么多 就是想總結2個字!!那就是,JS優(yōu)化幾則,局部變量最快,JS優(yōu)化幾則,循環(huán)著重介紹for while循環(huán)先來了解下2個循環(huán)的表現看下邊代碼及運行時間,JS優(yōu)化幾則,循環(huán),JS優(yōu)化幾則,循環(huán)總結就是 在乎先后順序 用for
23、 ++ 不在乎的話用for --,JS優(yōu)化幾則,循環(huán)其他優(yōu)化法則減少迭代的工作量,很明顯,如果一次循環(huán)迭代要花很長時間去執(zhí)行,那么多次循環(huán)需要花更多時間,一個提升循環(huán)整體速度的好方法是限制循環(huán)中耗時操作的數量。for(var i = 0; i < items.length; i++){ //do something; }上述循環(huán)中看似很正常,但是有很嚴重的性能問題!每次運行循環(huán)體時都會產生如下操作:一次控制條件中的屬性查
24、找(items.length)一次控制條件中的數值大小比較(i < items.length)一次控制條件結果是否為true的比較(i < items.length == true)一次自增操作,JS優(yōu)化幾則,循環(huán)前面我們說過 讀取局部變量是最快的,這個循環(huán)體的每次運行運行都要查找items.length 這樣做很耗時,這樣做很耗時,因為這個值在循環(huán)過程中是不變的僅供比較,所以我們把它傳遞到局部變量會更快也更合情合理
25、。如下:for(var i = 0, l = items.length; i < l; i++){ //do something }重寫后的循環(huán)只在循環(huán)運行前對長度進行一次屬性查找,這使得控制條件可直接讀取局部變量,所以速度更快??於嗌伲孔约簻y試,肯定高于你的預期!,JS優(yōu)化幾則,循環(huán)另一個方法就是在 順序不是很重要的情況下 可以使用倒序循環(huán) 比如循環(huán)為每個DOM元素addEventListener。倒序循環(huán)是編程語言中一種
26、通用的優(yōu)化方法。for(var i = items.length; i--;){ //do something }現在每個控制條件只是簡單的與0比較??刂茥l件與true值比較,任何非零數會自動轉換為true,而零值等同于false。實際上控制條件從2次比較(迭代數少于總數嗎?是否為true?)減少到1次(它是處兒嗎?)。這樣就更進一步提高了循環(huán)速度。通過這2個很不起眼的小辦法就可以看出 循環(huán)速度比最初的提高了50%以上!對比原始版
27、本 現在每次運行循環(huán)體時只需要如下幾步一次控制條件的比較(i == true)一次減法操作(i--),JS優(yōu)化幾則,JS與DOM那扯不斷理還亂的關系用JS腳本來操作DOM的代價很昂貴,它是富WEB應用中最常見的性能瓶頸。關于JS與DOM的關系一說,微軟有個很好的比喻,把DOM與JS各自想象為一個島嶼,他們之間用高速橋連接,JS每次訪問DOM都要途徑這座橋,并交納過路費,訪問DOM的次數越多,付出的代價越昂貴,因此,要盡可能的減少過
28、橋的次數。訪問DOM的代價已經這么昂貴 那就更不用說修改DOM了,但是我們以往的以后的項目又不可完全避免產生這樣的過路費,所以有必要掌握以下的常識!,JS優(yōu)化幾則,1.避免在循環(huán)體中對DOM元素反復操作! for( var i = 0; i < 10; i++){ document.getElementById("a").innerHTML += i; } 這段簡單的代碼有很嚴重的性能問
29、題!每次循環(huán)該元素都被訪問2次,1次讀取innerHTML內容,1次重寫它。 轉變! var content = ""; for(var i = 0; i < 10; i++){ content += i; } document.getElementById("a").innerHTML = content; 插一句 innerHTML對比docum
30、ent.createElement 性能相差無幾,在最新版的webkit瀏覽器中 innerHTML略慢 其他情況下建議用innerHTML,JS優(yōu)化幾則,2.重繪重排 重繪重排都是代價昂貴的操作,他們會導致WEB應用程序和UI反應遲鈍,因此應該盡量減少這類過程的發(fā)生。 當DOM的變化影響了元素的幾何屬性-widht height border,瀏覽器需要重新計算元素的幾何屬性,同樣其他元素的幾何屬性和位置也會因此受到影
31、響。瀏覽器會使渲染樹中受到影響的部分失效,并重新構造渲染樹。這個過程就是重排(Reflow)。完成重排后瀏覽器會重新繪制受影響的部分到屏幕中,該過程為重繪(Repaint) 并不是所有的DOM變化都會影響幾何屬性。例如改變一個元素的background-color,這種情況下只會發(fā)生一次重繪而不需要重排。因為元素的布局并沒有改變。 以下情況會觸發(fā)重排:,JS優(yōu)化幾則,1.添加刪除可見的DOM元素 2.元素位置改變
32、 3.元素尺寸改變 border-width margin padding width height 4.內容改變,文字行數變化 圖片大小尺寸變化 5.頁面渲染器初始化 6.瀏覽器窗口尺寸改變resize(function(){}),JS優(yōu)化幾則,3.如何最大程度的減少重排和重繪 首先。使元素脫離文檔流 其次。對其應用多重改變 最后。把元素帶回文檔中 該過程會觸發(fā)兩次重排
33、第一步和第三步,如果你忽略這2個步驟,那么你在第二步里的每一個修改操作觸發(fā)一次重排。 三種方法可以使DOM脫離文檔 1.隱藏元素,應用修改,重新顯示 display:none display:block 2.使用文檔片段,在當前DOM之外構建一個子樹,再把它拷貝回文檔。 document.createDocumentFragment() 3.將原始元素拷貝到一個脫離文檔的節(jié)點中,修改副本,完成后再
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
評論
0/150
提交評論