頁面渲染與其效能的提升
不論js程式碼是內聯還是包含在一個不相干的外部檔案中,頁面下載和解析過程肯定會停下,等待指令碼執行完成這些處理,然後才能繼續進行。——大多數瀏覽器使用單程序處理JavaScript的多個任務,同一時間只能有一個任務執行。
載入過程中遇到外部css檔案,瀏覽器另外發出一個請求,來獲取css檔案。
遇到圖片資源,瀏覽器也會另外發出一個請求,來獲取圖片資源。這是非同步請求,並不會影響html文件進行載入,但是當文件載入過程中遇到js檔案,html文件會掛起渲染(載入解析渲染同步)的執行緒,不僅要等待文件中js檔案載入完畢,還要等待解析執行完畢,才可以恢復html文件的渲染執行緒。
CSS:可以同時下載多個CSS檔案。 如果我們把CSS樣式放在頁面底部,雖然使頁面內容能更快的載入(因為將載入css 檔案的時間放在最後,從而使頁面內容先顯示出來),但這樣的內容是沒有樣式的,在CSS檔案載入進來後,瀏覽器再對DOM使用樣式,會出現我們常說的“無樣式之閃爍”。 更討厭的是,上下都放置CSS樣式,瀏覽器會首先按照上面的進行渲染,等到下面的樣式上來,再按照下面的樣式進行迴流和重繪,使用者感覺很差。原因:JS有可能會修改DOM,最為經典的document.write,這意味著,在JS執行完成前,後續所有資源的下載可能是沒有必要的,這是js阻塞後續資源下載的根本原因。
辦法:可以將外部引用的js檔案放在</body>
前。
注意兩個詞“repaint"和"reflow"。 repaint(重繪)是在一個元素的外觀被改變,但沒有改變佈局的情況下發生。——如果只是改變某個元素的背景色、文字顏色、邊框顏色等等不影響它周圍或內部佈局的屬性,將只會引起瀏覽器repaint。 reflow(迴流):瀏覽器發現某個部分發生了點變化影響了佈局,需要倒回去重新渲染,這個回退的過程就叫回流。
do { $mrc = curl_multi_exec($mh, $active); }while($mrc==CURLM_CALL_MULTI_PERFORM); while ($active && $mrc == CURLM_OK){ if (curl_multi_select($mh) != -1){ do { $mrc = curl_multi_exec($mh,$active); }while($mrc==CURLM_CALL_MULTI_PERFORM); } }
或者
<?php while (count($sockets)) { $read = $write = $sockets; $n = stream_select($read,$write, $e, $timeout); if ($n > 0) { foreach ($read as $r) { $id = array_search($r, $sockets); $data = fread($r, 8192); if (strlen($data) == 0) { fclose($r); unset ($sockets[$id]); }else { $retdata[$id] .= $data; } } $retdata[$id] = preg_replace('/^HTTP(.*?)\r\n\r\n/is',<em>, $retdata[$id]);</em> foreach ($write as $w) { if (!is_resource($w))continue; $id = array_search($w, $sockets); fwrite($w, "GET /" . $url[$id] . "HTTP/1.0\r\nHost: " . $hosts[$id] ."\r\n\r\n"); $status[$id] = 1; } }else { break; } }
JavaScript:
1、把指令碼進行壓縮(移除不必要的字元,註釋以及空行)。
2、對部分js檔案進行合併,以減少http的請求個數,以減少伺服器端的壓力——但是要量力而行,因為如果你的js檔案很大,下載很慢的話,很多功能都不能正常進行,我們可以按照業務進行合併。
3、使用外部js檔案。因為現在很多瀏覽器都有快取,明顯會減少http請求數。
4、將指令碼放在頁面底部。先讓使用者看到內容,然後再載入js,這樣使用者會感覺頁面載入速度很快。
CSS:
1、合併多個css檔案,以減少http的請求個數,以減少伺服器端的壓力。
2、使用外部css檔案。主要原因是瀏覽器快取,以減少http請求。
3、放在頁面頂部(head標籤處),防止出現“無樣式內容的閃爍”。
怎樣儘可能的縮短瀏覽器上頁面渲染的時間,可以從以下幾個方面入手:
1.寫出高效的css程式碼
2.避免使用css表示式
3.把css檔案放在頁面頂部
4.指定頁面圖片的尺寸
5.頁面頭部標明文件編碼
一,寫出高效的css程式碼
首先弄清瀏覽器解析html程式碼的過程:構建一個dom樹,頁面要顯示的各元素都會建立到這個dom樹當中。每當一個新元素加入到這個dom樹當中,瀏覽器便會通過css引擎查遍css樣式表,找到符合該元素的樣式規則應用到這個元素上。css引擎查詢樣式表,對每條規則都按從右到左的順序去匹配。
瞭解過程後,我們可以看出可以從兩方面優化我們的css程式碼:1,定義的css樣式規則條數越少越好,所以趕緊刪除css檔案中不必要的樣式定義;2,優化每條規則的選擇符書寫方式,儘量讓css引擎一看就知道這個規則是否需要應用到當前這個元素上,讓引擎少走不必要的彎路。
如以下幾種效率不高的css書寫方式:
a, 用萬用字元作為關鍵選擇符(關鍵選擇符指的是每條規則最右側的選擇符)
複製程式碼程式碼如下:
body * {...}
.hide-scrollbars * {...}
b, 用標籤做關鍵選擇符
複製程式碼程式碼如下:
ul li a {...}
#footer h3 {...}
* html #atticPromo ul li a {...}
c, 畫蛇添足的寫法
複製程式碼程式碼如下:
ul#top_blue_nav {...}
form#UserLogin {...}
d, 給非連線標籤新增 :hover 偽類,這會對用了strict doctype的頁面在IE7和IE8下變的很慢。
複製程式碼程式碼如下:
h3:hover {...}
.foo:hover {...}
#foo:hover {...}
div.faa :hover {...}
優化建議:
a, 避免使用萬用字元;
b, 讓css引擎快速辨別該規則是否適用於當前元素:多用id或class選擇符,少用標籤選擇符;
c, 不要畫蛇添足把id和class或標籤和class等連著寫;
d, 儘量避免使用後代選擇符,去除不必要的祖先元素,可以考慮使用class選擇符來替換後代選擇符;
複製程式碼程式碼如下:
/*給無序和有序的li定義不同顏色,你可能會這樣寫:*/
ul li {color: blue;}
ol li {color: red;}
/*給li新增class,這樣定義效率會更高:*/
.unordered-list-item {color: blue;}
.ordered-list-item {color: red;}
e, 避免給非連線標籤新增 :hover 偽類。
二,避免使用css表示式
css表示式僅在ie瀏覽器下才起作用,微軟已在ie8後不推薦使用,因為它會嚴重影響頁面效能:任何時候,不管任何一個事件被觸發,例如視窗的 resize 事件,滑鼠的移動等等,css表示式都會重新計算一遍。
三,把css檔案放在頁面頂部
把外聯或內聯樣式表放在body部分會影響頁面渲染的速度,因為瀏覽器只有在所有樣式表下載完成後才會繼續下載頁面其他內容。另外,內聯樣式表(放在<style>內的樣式)有可能會引起頁面重新渲染或顯示隱藏頁面中的某些元素,建議不要使用內聯樣式表。
四,指定頁面圖片的尺寸
指定頁面圖片尺寸,要符合圖片的真實尺寸(不要通過指定尺寸來縮放圖片),可以避免尺寸改變導致的頁面結構效果的變化,所以對加快頁面渲染速度有益。
五,頁面頭部標明文件編碼
HTML文件是以包含文件編碼資訊的資料流方式在網路間傳輸。頁面的編碼資訊一般會在HTTP響應的頭部資訊或在文件內的HTML標記中指明。客戶端瀏覽器只有在確定了頁面編碼後才能正確的渲染頁面,所以在繪製頁面或執行任何的javascript程式碼前,大部分的瀏覽器(ie6、ie7、ie8除外)都會緩衝一定位元組的資料來從中查詢編碼資訊,不同的瀏覽器當中預緩衝的位元組數是不一樣的。如果瀏覽器在接收到了設定的預緩衝資料量後還沒有找到頁面的編碼資訊,便會根據各自指定的預設編碼開始渲染頁面,如果這時再獲取到頁面編碼資訊,而又跟現在所用編碼不一致,那整個頁面就得重新渲染,某些情況下甚至需要重新獲取資料。所以,對於大小超過1KB的頁面(根據在各瀏覽器的測試情況,預緩衝資料量最多的也就1KB)應當儘早標明編碼資訊。
優化建議:
a, 儘量在HTTP頭部資訊中標明頁面編碼(這個需要在伺服器端設定)。像Firefox瀏覽器,如果在HTTP頭部資訊就獲取到了編碼資訊,便會預緩衝更少的資料從而減少不必要的資料緩衝時間;
b, 在HTML的 <head> 部分標明編碼資訊;
c, 要習慣給文件指定編碼;
d, 給頁面指定的編碼要符合頁面實際編碼;如果你在HTTP頭部資訊和HTML標記中同時指定了編碼,需確保編碼資訊一致。