DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁SEO優化 >> SEO優化集錦 >> 減少HTTP請求(大型網站優化技術)
減少HTTP請求(大型網站優化技術)
編輯:SEO優化集錦     

在網站開發過程中,對於頁面的加載效率一般都想盡辦法求快。那麼,怎麼讓才能更快呢?減少頁面請求 是一個優化頁面加載速度很好的方法。上一篇博文我們講解了 “利用將小圖標合成一張背景圖來減少HTTP請求”,那麼,這一篇博文將講解  “ 將圖片轉成二進制並生成Base64編碼,可以在網頁中通過url查看圖片”。

一、為何選擇將圖片轉成二進制並生成Base64編碼,可以在網頁中通過url查看圖片的方法減少HTTP請求數?

為什麼我會講解 “將圖片轉成二進制並生成Base64編碼,可以在網頁中通過url查看圖片” 這一種方式來減少HTTP請求,進而優化頁面呢?這裡呢,是涉及到移動端的圖標使用。上一篇博文所講的方法能否使用於手機端的網頁呢?

但是,它會出現一個問題:背景圖+css顯示圖標時,圖標本身無法縮放,比如背景圖中64px*64px的圖標,顯示到界面時必須設置icon的大小也是64*64。在PC網頁中這通常不會有什麼問題,但在移動端設備上就完全行不通。同樣是4英寸的手機屏幕,其分辨率有可能是320*400,也可能是640*800,甚至也可能是1920*1080。這樣64px*64px的圖標在不同的設備上看起來的大小就會差別非常明顯。

幸運的是,手機上的浏覽器基本對此做了優化,會把設備模擬成更低的分辨率。比如在1136*640的IPHONE 5中獲取$(window).width(),取出來的是320而不是640,這樣一個寬度為160px的圖片占用的是屏幕寬度的一半,而不是1/4。手機設備這樣處理是為了解決兼容性問題。除了網頁,包括手機上app的界面,在retina屏幕上和非retina屏幕上的大小是完全一樣的,都是因為對分辨率做了處理。

但是,移動設備這樣的處理方式並不能完全解決問題,因為機器的假設性猜測在很多時候是不合適的,尤其是在android設備中。為了更好地控制元素顯示的大小,解決的辦法就是用pt代替ps,px是對應屏幕的分辨率,而pt是針對人眼睛實際感覺的大小,無論在何種分辨率的設備上,72pt固定是1英寸。

HTML的img標簽元素的src屬性不只是可以指定url,也可以指定圖片的二進制數據流。然後通過img元素的自動縮放功能,指定img的大小,就可以實現在不同分辨率的設備上顯示一致的圖標大小。

二、使用Base64編碼減少頁面請求數

當我們的一個頁面中要傳入很多圖片時,特別是一些小圖標,十幾K、幾K,甚至是字節級別大小的小圖標,這些小圖標都會增加HTTP請求,假如多了,就會給服務器帶來很大的壓力。比如要下載一些一兩K大的小圖標,其實請求時帶上的額外信息有可能比圖標的大小還要大。所以,在請求越多時,在網絡傳輸的數據自然就越多了,傳輸的數據自然也就變慢了。而這裡,我們采用Base64的編碼方式將圖片直接嵌入到網頁中,而不是從外部載入,這樣就減少了HTTP請求。當然了,它有一個小缺點,就是使當前頁面的大小變大了(對於優化來說,其實這個可以忽略,影響不大)。看一下下圖,小圖標大小為2.4k,等待響應時間是14ms,而接受數據,也就是下載時間約為0ms;可想而知,在有大量小圖標下載的時候,這樣的方式去優化能大大提高網站的性能(在jquery mobile和天貓的手機站上面都有用到此技術)。

HTTP請求 網站開發 網站優化

三、開發思路

將小圖標放在以icon_開頭的文件夾裡(以區分不用生成base64的圖片的文件夾)—>用程序去遍歷文件夾圖片 —>將每張圖片的base64編碼放在一個js對象裡—>在HTML頁面的img標簽裡 使用屬性 icon-data = ‘圖標名(不帶後綴)’來顯示圖片 —> JS文件寫一個函數對icon-data屬性進行轉換,轉換成src屬性,然後值就通過icon-data的屬性值獲得圖標名,然後進行相應的替換得到相應圖標的base64編碼 —> 顯示圖片

四、代碼實現

XHTML 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 <?php     $pathinfo=pathinfo($_SERVER['SCRIPT_FILENAME']);     define('ROOT',$pathinfo['dirname']);       functiongenerateIcon_mobile(){         $imgRoot=ROOT."/img/mobile";         $iterator=newDirectoryIterator($imgRoot);         foreach($iteratoras$file){             if($file->isDot())continue;             $filename=$file->getFilename();               //識別出是否以icon_開頭的文件夾,如果是,則對此文件夾的圖標進行base64編碼處理             if($file->isDir()&&0===strncasecmp('icon_',$filename,5)){                 generateIconMobileCallback("$imgRoot/$filename",ROOT."/js/mobile");             }         }       }       functiongenerateIconMobileCallback($iconDir,$styleSaveDir){         //保存成js的文件名         $saveName=array_pop(explode('/',$iconDir));         //JS文件保存路徑         $styleSavePath=$styleSaveDir.'/'.$saveName.'.js';           //將當前目錄下的所有文件及MD5組成一個識別字符串         $fileMap=array();         $iterator=newDirectoryIterator($iconDir);         foreach($iteratoras$file){             if($file->isDot())continue;             $fileName=$file->getFilename();             if($file->isDir()){                 generateIconMobileCallback($iconDir.'/'.$fileName,$styleSaveDir.'/'.$fileName);             }else{                 $fileMap[$fileName]=md5_file($file->getRealPath());             }         }         ksort($fileMap);         $fileMapStr=json_encode($fileMap);           //確保目錄可寫         ensure_writable_dir($styleSaveDir);           //js文件句柄         $wirteHandle=fopen($styleSavePath,'w');         //當前小圖標文件夾的相對路徑         $iconSaveRelative=substr($iconDir,strlen(ROOT));         //寫入,初始化保存數據的對象         fwrite($wirteHandle,"/** icon in dir: $iconSaveRelative/ */ \nif(typeof(\$iconData) == 'undefined') \$iconData={};");         foreach($fileMapas$fileName=>$md5){             //當前圖片的絕對路徑             $fullPathName="$iconDir/$fileName";             //取得路徑信息             $pathInfo=pathinfo($fullPathName);             //取得文件名(沒有後綴)             $fileNameNoExt=$pathInfo['filename'];             //取得圖片信息             $imageSize=getimagesize($fullPathName);               //取得文件的後綴             switch($imageSize[2]){                 caseIMAGETYPE_GIF:                     $imageType='gif';                     break;                 caseIMAGETYPE_JPEG:                     $imageType='jpg';                     break;                 caseIMAGETYPE_PNG:                     $imageType='png';                     break;                   default:                     $imageType='jpg';                     break;             }               //取得圖片資源             $readHandle=fopen($fullPathName,'r');             //將圖片轉成二進制並生成Base64編碼             $base64=base64_encode(fread($readHandle,filesize($fullPathName)));             //關閉資源             fclose($readHandle);             //將Base64編碼寫入js文件中             fwrite($wirteHandle,"\n\$iconData.$fileNameNoExt=\"data:image/$imageType;base64,$base64\";");         }         //最後換個行         fwrite($wirteHandle,"\n");         //關閉資源         fclose($wirteHandle);           //處理成功的圖標文件夾給予提示         echo'<p>'.$iconSaveRelative.' saved</p>';       }       /**     * 確保文件夾存在並可寫     *     * @param string $dir     */     functionensure_writable_dir($dir){         if(!file_exists($dir)){             mkdir($dir,0766,true);             @chmod($dir,0766);             @chmod($dir,0777);         }         elseif(!is_writable($dir)){             @chmod($dir,0766);             @chmod($dir,0777);             if(!@is_writable($dir)){                 thrownewBusinessLogicException("目錄不可寫",$dir);             }         }     }     generateIcon_mobile(); ?>   <!DOCTYPE html> <html> <head>     <title></title> </head> <body> <br> <br> <br>   <div>我們直接引入所生成的js文件,測試一下是否成功</div> <br> <div>直接在img標簽裡加入 icon-data = '圖標文件名'  例如  <\img icon-data="tryit">,查看效果</div> <br> <br> <br>     <img icon-data="tryit">     <script src="js/mobile/icon_pink.js"></script>     <script src="js/mobile/jquery.all.min.js"></script>     <script src="js/mobile/attrHandle.js"></script> </body> </html>

然後這裡附上屬性轉換的JS代碼

  JavaScript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $(function(){     setIconData(); });   functionsetIconData(){     if(typeof($iconData!='undefined')){         $('img[icon-data]').each(function(){             varself=$(this);             varname=self.attr('icon-data');             if(typeof($iconData[name])!='undefined'){                 self.attr('src',$iconData[name]);                 self.removeAttr('icon-data');             }         });     } }

 

五、實現效果

  這是頁面輸入效果,小圖標正常顯示出來了

 

HTTP請求 網站開發 網站優化

 

這裡我們自動生成的JS文件是這樣子的格式:

HTTP請求 網站開發 網站優化

 

頁面調用的代碼:

HTTP請求 網站開發 網站優化

 

JS對img的icon-data屬性轉換處理的代碼:

HTTP請求 網站開發 網站優化

 

我們對比下用base64編碼和不用base64時所花費的時間:

先看不用的速度

HTTP請求 網站開發 網站優化

再看我們用了base64編碼的速度   HTTP請求 網站開發 網站優化

 

假如一個頁面有很多小圖標,那麼這種方式對網站的性能優化會有大大的提升。如今此種優化方案是用在我現在的項目中移動端,而上一篇博文講解的生成背景圖的優化方案用在我們項目中的PC端。優化效果是很明顯的!當然了,base64編碼這種方法也可以用在PC端,我們的項目為啥將它用在手機端,本博文開頭部分也有對其做解釋。這裡測試我就直接在PC端測試,手機端測試也是一個樣的。

這裡我補充一點:

(1)所生成的base64的js文件是在開發中就生成的了,而不是在用戶訪問時才去生成,我把HTML代碼和PHP代碼寫在一個文件裡是方便,在真實項目中是分開的;

(2)使用此種優化技術有它的優點,當然也會有它的缺點,只有適合自己項目的優化技術才是好技術;

(3)此中優化技術建議使用在手機端(可以解決背景圖優化方式所不能解決的問題),而PC端的則用合並小圖標生成背景圖的方式(看此文:http://www.cnblogs.com/it-cen/p/4618954.html);

(4)此種優化技術一般用於小圖標(十幾K以下),也就是HTTP響應時間遠遠大於下載時間的時候,用此方法優化會看到明顯的效果;

(5)當然可以配合其他優化技術一起使用,效果更明顯,比如緩存等。

這一次就分享那麼多給大家,代碼我都貼上了,而且很多都標上了注釋,方便大家理解。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved