合並壓縮css和Js的方式
[文章作者:磨延城 轉載請註明原文出處: https://mo2g.com/view/74/ ]
本篇博客從減少瀏覽器加載外部資源連接數的思考角度著手,要想深入了解其他加快網頁顯示速度的原理,估計又得花不少時間,這需要把前端跟後端都說解釋清楚.有時間我會分開寫其他部分的內容.這裏為了節省時間,只介紹如何減少網頁需要加載的外部資源,加快瀏覽器的響應速度.
本篇博客從減少瀏覽器加載外部資源連接數的思考角度著手,要想深入了解其他加快網頁顯示速度的原理,估計又得花不少時間,這需要把前端跟後端都說解釋清楚。有時間我會分開寫其他部分的內容。這裏為了節省時間,只介紹如何減少網頁需要加載的外部資源,加快瀏覽器的響應速度。
如果一個頁面比較復雜,要展示的內容 比較多,就會包含很多外部資源、css樣式還有js腳本,比如某個門戶網站的的html代碼如下:
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 |
< html >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" />
< title >XXX最大的門戶網站</ title >
<!-- 外部css樣式資源 開始--> < link type = "text/css" rel = "stylesheet" href = "1.css" />
< link type = "text/css" rel = "stylesheet" href = "2.css" />
...
< link type = "text/css" rel = "stylesheet" href = "n-1.css" />
< link type = "text/css" rel = "stylesheet" href = "n.css" />
<!-- 外部css樣式資源 結束-->
</ head > < body >
<!-- 頁面展示圖片 開始-->
< img src = "1.jpg" >
...
< img src = "n.jpg" >
<!-- 頁面展示圖片 結束-->
<!-- 外部js腳本資源 開始-->
< script scr = "1.js" ></ script >
...
< script scr = "n.js" ></ script >
<!-- 外部js腳本資源 結束-->
</ body >
</ html >
|
這些大型門戶網站一個頁面需要加載的外部資源總數,經常超過100個。騰訊QQ首頁,就加載高達了192個外部資源。相信這個數字是經過騰訊的前端團隊盡了最大努力才壓縮下來的結果,如果沒做過處理,會怎樣?
請看下邊的表格,分別顯示了各個瀏覽器在同一時間,能向同一域名請求的最大並發連接數。
瀏覽器 | HTTP 1.1 | HTTP 1.0 |
IE 6、7、8 | 2~6 | 4~6 |
Firefox | 2~6 | 6~8 |
Safari | 4 | 4 |
Chrome | 4~6 | 4~6 |
如果瀏覽器支持8個並發鏈接,每個外部資源加載時間為400ms,那麽160個外部資源連接,理論上就需要8000ms(160 ÷ 8 × 400)的加載時間,大約8秒才能顯示完整的頁面。但實際的情況更加復雜,最基本的問題就是要加載的外部資源數據包的大小,這一因素直接影響了加載時間,要想保證每個外部資源的加載時間為400ms或者更短的時間,這又牽扯到CDN分布式存儲。所以,在資金不足的情況下,我們能做的就是減少外部資源的連接數,還有就是精簡和壓縮靜態數據。
為了解決這一問題,我為mPHP核心框架寫了一個PHP函數file_merger,用來合並多個CSS樣式文件或者JS腳本文件,並對生成的合成文件進行壓縮,從而更進一步的減小外部資源的數據大小。
使用環境如下:
測試環境地址:http://localhost/
測試環境目錄結構:
/static/css/,css樣式目錄存在1.css,2.css兩個文件
/static/js/,js腳本目錄下存在1.js,2.js
/static/merger/,合成文件保存目錄
file_merger函數的使用例子如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php
include ‘file_merger.php‘ ;
$CFG [ ‘debug‘ ] = 0; //當值為1的時候,不進行合並壓縮,按常規調用
$CFG [ ‘java‘ ] = 0; //當值為1的時候,使用yuicompressor壓縮;0使用PHP正則表達式簡單壓縮
$arrCss [] = ‘1.css‘ ;
$arrCss [] = ‘2.css‘ ;
$arrJs [] = ‘1.js‘ ;
$arrJs [] = ‘2.js‘ ;
$css = file_merger( $arrCss , ‘main.css‘ );
$js = file_merger( $arrJs , ‘main.js‘ );
echo $css ;
echo $js ;
/*
函數執行成功後,會在指定的合成文件保存目錄生成main.css,main.js兩個文件,並會輸出結果如下
<link rel="stylesheet" type="text/css" href="http://localhost/static/merger/main.css?1389454147">
<script type="text/javascript" src="http://localhost/static/merger/main.js?1389454147"></script>
測試代碼的時候可以把$CFG[‘debug‘]設置為1;
當為1的時候,不會生成合成文件,同時會得到如下輸出結果,方便調試:
<link href="http://localhost/static/css/1.css?1389454824" rel="stylesheet" type="text/css">
<link href="http://localhost/static/css/2.css?1389454824" rel="stylesheet" type="text/css">
<script type="text/javascript" src="http://localhost/static/js/1.js?1389454824"></script>
<script type="text/javascript" src="http://localhost/static/js/2.js?1389454824"></script>
*/
|
file_merger有兩種壓縮方式,一種是使用雅虎基於java開發的yuicompressor,第二種就是我基於PHP正則表達式編寫的壓縮規則。優先推薦使用yuicompressor的壓縮方式,但如果你的服務器環境不支持java,也可以使用第二種方法。
下邊是file_merger函數的實現代碼,如果使用過程中有什麽問題,可以給我留言。
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 |
<?php
/*
作者:moyancheng
最後更新時間:2013-05-17
最後更新時間:2013-12-13
功能:將多個js或css,合並為一個js或css,並進行壓縮
$arrPath:合並文件數組
$out:輸出文件
$cache:是否緩存,默認為false,會在文件名後邊加上時間戳,如main.js?1389424132
*/
function file_merger( $arrFile , $out , $cache =false) {
global $CFG ;
$url = ‘http://localhost/static/‘ ;//靜態資源url地址,根據自己的情況修改
$static = ‘/static/‘ ; //靜態資源在服務器上的存儲路徑,根據自己的情況修改
$dir = "{$static}merger/" ; //合成文件在服務器上的存儲路徑,根據自己的情況修改
$return = "{$url}merger/{$out}" ;
$out = "{$dir}{$out}" ; //
$time = $_SERVER [ ‘REQUEST_TIME‘ ];
if ( substr ( $arrFile [0],-2) == ‘js‘ ) {
$type = ‘js‘ ;
} elseif ( substr ( $arrFile [0],-3) == ‘css‘ ) {
$type = ‘css‘ ;
}
//當文件不存在,或者調試模式,就執行下邊的程序
if ( ! is_file ( $out ) || $CFG [ ‘debug‘ ]) {
//調試模式,按常規加載js,css
if ( $CFG [ ‘debug‘ ] ) {
$out = ‘‘ ;
foreach ( $arrFile as $key => $file ) {
if ( $type == ‘js‘ ) {
$out .= "<script type=\"text/javascript\" src=\"{$url}js/{$file}?{$time}\"></script>\n" ;
} elseif ( $type == ‘css‘ ) {
$out .= "<link href=\"{$url}css/{$file}?{$time}\" rel=\"stylesheet\" type=\"text/css\">\n" ;
}
}
return $out ;
} else {
//正式環境啟動壓縮
ob_start();
foreach ( $arrFile as $key => $file ) {
include $static . "{$type}/{$file}" ;
}
$str = ob_get_clean();
$tmp = $dir . ‘tmp‘ ;
if ( $CFG [ ‘java‘ ]) {
//java程序精簡文件
file_put_contents ( $tmp , $str );
if ( $type == ‘js‘ ) {
$exec = "java -jar {$static}yuicompressor-2.4.2.jar --type js --charset utf-8 -v $tmp > $out" ; //壓縮JS
} elseif ( $type == ‘css‘ ) {
$exec = "java -jar {$static}yuicompressor-2.4.2.jar --type css --charset utf-8 -v $tmp > $out" ; //壓縮CSS
}
` $exec ` ;
} else {
//php程序精簡文件
$str = preg_replace( ‘#/\*.+?\*/#s‘ , ‘‘ , $str ); //過濾註釋 /* */
$str = preg_replace( ‘#(?<!http:)(?<!\\\\)(?<!\‘)(?<!")//(?<!\‘)(?<!").*\n#‘ , ‘‘ , $str );//過濾註釋 //
$str = preg_replace( ‘#[\n\r\t]+#‘ , ‘ ‘ , $str ); //回車 tab替換成空格
$str = preg_replace( ‘#\s{2,}#‘ , ‘ ‘ , $str ); //兩個以上空格合並為一個
file_put_contents ( $out , $str );
}
}
}
unset( $CFG );
if ( $cache ) {
if ( $type == ‘js‘ ) return "<script type=\"text/javascript\" src=\"{$return}\"></script>\n" ;
elseif ( $type == ‘css‘ ) return "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$return}\">\n" ;
} else {
if ( $type == ‘js‘ ) return "<script type=\"text/javascript\" src=\"{$return}?{$time}\"></script>\n" ;
elseif ( $type == ‘css‘ ) return "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$return}?{$time}\">\n" ;
}
}
|
[文章作者:磨延城 轉載請註明原文出處: https://mo2g.com/view/74/ ]
本篇博客從減少瀏覽器加載外部資源連接數的思考角度著手,要想深入了解其他加快網頁顯示速度的原理,估計又得花不少時間,這需要把前端跟後端都說解釋清楚.有時間我會分開寫其他部分的內容.這裏為了節省時間,只介紹如何減少網頁需要加載的外部資源,加快瀏覽器的響應速度.
本篇博客從減少瀏覽器加載外部資源連接數的思考角度著手,要想深入了解其他加快網頁顯示速度的原理,估計又得花不少時間,這需要把前端跟後端都說解釋清楚。有時間我會分開寫其他部分的內容。這裏為了節省時間,只介紹如何減少網頁需要加載的外部資源,加快瀏覽器的響應速度。
如果一個頁面比較復雜,要展示的內容 比較多,就會包含很多外部資源、css樣式還有js腳本,比如某個門戶網站的的html代碼如下:
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 |
< html >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" />
< title >XXX最大的門戶網站</ title >
<!-- 外部css樣式資源 開始-->
< link type = "text/css" rel = "stylesheet" href = "1.css" />
< link type = "text/css" rel = "stylesheet" href = "2.css" />
...
< link type = "text/css" rel = "stylesheet" href = "n-1.css" />
< link type = "text/css" rel = "stylesheet" href = "n.css" />
<!-- 外部css樣式資源 結束-->
</ head >
< body >
<!-- 頁面展示圖片 開始-->
< img src = "1.jpg" >
...
< img src = "n.jpg" >
<!-- 頁面展示圖片 結束-->
<!-- 外部js腳本資源 開始-->
< script scr = "1.js" ></ script >
...
< script scr = "n.js" ></ script >
<!-- 外部js腳本資源 結束-->
</ body >
</ html >
|
這些大型門戶網站一個頁面需要加載的外部資源總數,經常超過100個。騰訊QQ首頁,就加載高達了192個外部資源。相信這個數字是經過騰訊的前端團隊盡了最大努力才壓縮下來的結果,如果沒做過處理,會怎樣?
請看下邊的表格,分別顯示了各個瀏覽器在同一時間,能向同一域名請求的最大並發連接數。
瀏覽器 | HTTP 1.1 | HTTP 1.0 |
IE 6、7、8 | 2~6 | 4~6 |
Firefox | 2~6 | 6~8 |
Safari | 4 | 4 |
Chrome | 4~6 | 4~6 |
如果瀏覽器支持8個並發鏈接,每個外部資源加載時間為400ms,那麽160個外部資源連接,理論上就需要8000ms(160 ÷ 8 × 400)的加載時間,大約8秒才能顯示完整的頁面。但實際的情況更加復雜,最基本的問題就是要加載的外部資源數據包的大小,這一因素直接影響了加載時間,要想保證每個外部資源的加載時間為400ms或者更短的時間,這又牽扯到CDN分布式存儲。所以,在資金不足的情況下,我們能做的就是減少外部資源的連接數,還有就是精簡和壓縮靜態數據。
為了解決這一問題,我為mPHP核心框架寫了一個PHP函數file_merger,用來合並多個CSS樣式文件或者JS腳本文件,並對生成的合成文件進行壓縮,從而更進一步的減小外部資源的數據大小。
使用環境如下:
測試環境地址:http://localhost/
測試環境目錄結構:
/static/css/,css樣式目錄存在1.css,2.css兩個文件
/static/js/,js腳本目錄下存在1.js,2.js
/static/merger/,合成文件保存目錄
file_merger函數的使用例子如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php
include ‘file_merger.php‘ ;
$CFG [ ‘debug‘ ] = 0; //當值為1的時候,不進行合並壓縮,按常規調用
$CFG [ ‘java‘ ] = 0; //當值為1的時候,使用yuicompressor壓縮;0使用PHP正則表達式簡單壓縮
$arrCss [] = ‘1.css‘ ;
$arrCss [] = ‘2.css‘ ;
$arrJs [] = ‘1.js‘ ;
$arrJs [] = ‘2.js‘ ;
$css = file_merger( $arrCss , ‘main.css‘ );
$js = file_merger( $arrJs , ‘main.js‘ );
echo $css ;
echo $js ;
/*
函數執行成功後,會在指定的合成文件保存目錄生成main.css,main.js兩個文件,並會輸出結果如下
<link rel="stylesheet" type="text/css" href="http://localhost/static/merger/main.css?1389454147">
<script type="text/javascript" src="http://localhost/static/merger/main.js?1389454147"></script>
測試代碼的時候可以把$CFG[‘debug‘]設置為1;
當為1的時候,不會生成合成文件,同時會得到如下輸出結果,方便調試:
<link href="http://localhost/static/css/1.css?1389454824" rel="stylesheet" type="text/css">
<link href="http://localhost/static/css/2.css?1389454824" rel="stylesheet" type="text/css">
<script type="text/javascript" src="http://localhost/static/js/1.js?1389454824"></script>
<script type="text/javascript" src="http://localhost/static/js/2.js?1389454824"></script>
*/
|
file_merger有兩種壓縮方式,一種是使用雅虎基於java開發的yuicompressor,第二種就是我基於PHP正則表達式編寫的壓縮規則。優先推薦使用yuicompressor的壓縮方式,但如果你的服務器環境不支持java,也可以使用第二種方法。
下邊是file_merger函數的實現代碼,如果使用過程中有什麽問題,可以給我留言。
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 |
<?php
/*
作者:moyancheng
最後更新時間:2013-05-17
最後更新時間:2013-12-13
功能:將多個js或css,合並為一個js或css,並進行壓縮
$arrPath:合並文件數組
$out:輸出文件
$cache:是否緩存,默認為false,會在文件名後邊加上時間戳,如main.js?1389424132
*/
function file_merger( $arrFile , $out , $cache =false) {
global $CFG ;
$url = ‘http://localhost/static/‘ ;//靜態資源url地址,根據自己的情況修改
$static = ‘/static/‘ ; //靜態資源在服務器上的存儲路徑,根據自己的情況修改
$dir = "{$static}merger/" ; //合成文件在服務器上的存儲路徑,根據自己的情況修改
$return = "{$url}merger/{$out}" ;
$out = "{$dir}{$out}" ; //
$time = $_SERVER [ ‘REQUEST_TIME‘ ];
if ( substr ( $arrFile [0],-2) == ‘js‘ ) {
$type = ‘js‘ ;
} elseif ( substr ( $arrFile [0],-3) == ‘css‘ ) {
$type = ‘css‘ ;
}
//當文件不存在,或者調試模式,就執行下邊的程序
if ( ! is_file ( $out ) || $CFG [ ‘debug‘ ]) {
//調試模式,按常規加載js,css
if ( $CFG [ ‘debug‘ ] ) {
$out = ‘‘ ;
foreach ( $arrFile as $key => $file ) {
if ( $type == ‘js‘ ) {
$out .= "<script type=\"text/javascript\" src=\"{$url}js/{$file}?{$time}\"></script>\n" ;
} elseif ( $type == ‘css‘ ) {
$out .= "<link href=\"{$url}css/{$file}?{$time}\" rel=\"stylesheet\" type=\"text/css\">\n" ;
}
}
return $out ;
} else {
//正式環境啟動壓縮
ob_start();
foreach ( $arrFile as $key => $file ) {
include $static . "{$type}/{$file}" ;
}
$str = ob_get_clean();
$tmp = $dir . ‘tmp‘ ;
if ( $CFG [ ‘java‘ ]) {
//java程序精簡文件
file_put_contents ( $tmp , $str );
if ( $type == ‘js‘ ) {
$exec = "java -jar {$static}yuicompressor-2.4.2.jar --type js --charset utf-8 -v $tmp > $out" ; //壓縮JS
} elseif ( $type == ‘css‘ ) {
$exec = "java -jar {$static}yuicompressor-2.4.2.jar --type css --charset utf-8 -v $tmp > $out" ; //壓縮CSS
}
` $exec ` ;
} else {
//php程序精簡文件
$str = preg_replace( ‘#/\*.+?\*/#s‘ , ‘‘ , $str ); //過濾註釋 /* */
$str = preg_replace( ‘#(?<!http:)(?<!\\\\)(?<!\‘)(?<!")//(?<!\‘)(?<!").*\n#‘ , ‘‘ , $str );//過濾註釋 //
$str = preg_replace( ‘#[\n\r\t]+#‘ , ‘ ‘ , $str ); //回車 tab替換成空格
$str = preg_replace( ‘#\s{2,}#‘ , ‘ ‘ , $str ); //兩個以上空格合並為一個
file_put_contents ( $out , $str );
}
}
}
unset( $CFG );
if ( $cache ) {
if ( $type == ‘js‘ ) return "<script type=\"text/javascript\" src=\"{$return}\"></script>\n" ;
elseif ( $type == ‘css‘ ) return "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$return}\">\n" ;
} else {
if ( $type == ‘js‘ ) return "<script type=\"text/javascript\" src=\"{$return}?{$time}\"></script>\n" ;
elseif ( $type == ‘css‘ ) return "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$return}?{$time}\">\n" ;
}
}
|
合並壓縮css和Js的方式