一、瀏覽器兼容
1.1、概要
世界上沒有任何一個瀏覽器是一樣的,同樣的代碼在不一樣的瀏覽器上運行就存在兼容性問題。不同瀏覽器其內核亦不盡相同,相同內核的版本不同,相同版本的內核瀏覽器品牌不一樣,各種運行平台還存在差異、屏幕分辨率不一樣,大小不一樣,比例不一樣。兼容性主要考慮三方面:
1)、CSS兼容
2)、JavaScript兼容
3)、HTML兼容
這三類也是前端的主要組成部分,都存在一定的兼容性問題,知己知彼,百戰百勝,我們先了解瀏覽器的發動機—內核。
多年前我們一直為IE6兼容煩惱,為它沒少加班;盼走了IE6現在又出現了IE8,看來兼容沒有盡頭...
1.2、瀏覽器內核
Trident
Microsoft公司瀏覽器內核,IE6、IE7、IE8(Trident 4.0)、IE9(Trident 5.0)、IE10(Trident 6.0)及許多品牌瀏覽器的內核。其中部分瀏覽器的新版本是“雙核”甚至是“多核”,其中一個內核是Trident,然后再增加一個其他內核。
Gecko
Firefox內核,Netscape6開始采用的內核,后來的Mozilla FireFox(火狐瀏覽器) ,Mozilla Firefox、Mozilla SeaMonkey、waterfox(Firefox的64位開源版)、Iceweasel、Epiphany(早期版本)、Flock(早期版本)、K-Meleon使用的內核。
Presto
Opera前內核,已廢棄,Opera現已改用Google Chrome的Blink內核。
Webkit
Safari內核,Chrome內核原型,開源,它是蘋果公司自己的內核,也是蘋果的Safari瀏覽器使用的內核。 傲游瀏覽器3、Apple Safari、(Win/Mac/iPhone/iPad)、Symbian手機瀏覽器、Android 默認瀏覽器
Blink
Blink是一個由Google和Opera Software開發的瀏覽器排版引擎,Google計划將這個渲染引擎作為Chromium計划的一部分,這一渲染引擎是開源引擎WebKit中WebCore組件的一個分支,並且在Chrome(28及往后版本)、Opera(15及往后版本)。
edge
微軟專門為新IE打造的引擎,速度快,目前已經基於此引擎開發了瀏覽器,目前IE11使用該內核,估計以后微軟的新瀏覽器會繼續采用該內核。
1.3、瀏覽器市場份額(Browser Market Share)
通過瀏覽器的市份額我們可以在處理瀏覽器兼容性時會更加關注市場份額高的瀏覽器,適當的時候可以放棄市場份額占有量小的瀏覽器。
國際:
查詢地址:https://www.netmarketshare.com
2016年12月PC瀏覽器數據
2016年12月平板+移動數據
2016年瀏覽器份額變化
國內:
查詢地址:http://tongji.baidu.com/data/browser
2017年11月
2017PC+移除
2017手機+平板
2017年瀏覽器份額變化
國內:
查詢地址:http://tongji.baidu.com/data/browser
從上圖可以看出,我們在針對PC Web開發時需要重點關注Chrome、IE瀏覽器,開發Mobile項目時要重點關注Chrome瀏覽器與Safari。
1.4、兼容的一般標准
1)、在不同的主流的瀏覽器上表現效果一致
2)、能適應不同的屏幕大小
3)、能適應不同的分辨率與色彩深度
瀏覽器兼容在線測試:
IE測試可以安裝:IETester在本地測試。
1.5、CSS Reset
每種瀏覽器都有一套默認的樣式表,即user agent stylesheet,網頁在沒有指定的樣式時,按瀏覽器內置的樣式表來渲染。這是合理的,像word中也有一些預留樣式,可以讓我們的排版更美觀整齊。不同瀏覽器甚至同一瀏覽器不同版本的默認樣式是不同的。但這樣會有很多兼容問題,CSSReset可以將所有瀏覽器默認樣式設置成一樣。
如全局重置*{ padding: 0; margin: 0; border:}雖然能全部重置,但由於性能較低,不推薦使用。因為*需要遍歷整個DOM樹,當頁面節點較多時,會影響頁面的渲染性能。
這個網站http://cssreset.com/有最新的CSSReset提供給大家參考。
Normalize (號稱是CSS reset的替代方案,保留了一些內置的樣式,並不是清除所有)
http://nicolasgallagher.com/about-normalize-css/
https://github.com/necolas/normalize.css
示例:請看第2章的內容
1.6、CSS Hack
CSS Hack就是針對不同的瀏覽器或不同版本瀏覽器寫特定的CSS樣式達到讓瀏覽器兼容的過程。
1.6.1、條件注釋法
IE條件注釋(Conditional comments)是IE瀏覽器私有的代碼,在其它瀏覽器中被視為注釋。
<!--[if IE]>用於 IE <![endif]--> <!--[if IE 6]>用於 IE6 <![endif]--> <!--[if IE 7]>用於 IE7 <![endif]--> <!--[if IE 8]>用於 IE8 <![endif]--> <!--[if IE 9]>用於 IE9 <![endif]--> <!--[if gt IE 6]> 用於 IE6 以上版本<![endif]--> <!--[if lte IE 7]> 用於 IE7或更低版本 <![endif]--> <!--[if gte IE 8]>用於 IE8 或更高版本 <![endif]--> <!--[if lt IE 9]>用於 IE9 以下版本<![endif]--> <!--[if !IE 8]> -->用於非 IE <!-- <![endif]-->
gt : greater than,選擇條件版本以上版本,不包含條件版本 >
lt : less than,選擇條件版本以下版本,不包含條件版本 <
gte : greater than or equal,選擇條件版本以上版本,包含條件版本>=
lte : less than or equal,選擇條件版本以下版本,包含條件版本 <=
! : 選擇條件版本以外所有版本,無論高低
*只有IE瀏覽器認識條件注釋、其它瀏覽器會跳過
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <!--[if gt IE 6]> <style> body{ background:lightblue; } </style> <![endif]--> <!--[if lt IE 8]> <script type="text/javascript"> alert("您的瀏覽器Out了,請下載更新。"); </script> <![endif]--> </head> <body> <!--[if gt IE 6]> <h2>大於IE6版本的瀏覽器</h2> <![endif]--> </body> </html>
效果:
IE8
chrome
ie6
1.6.2、樣式內屬性標記法
在CSS樣式的屬性名前或值后面添加特殊的字符讓不同的瀏覽器解析。
http://browserhacks.com/在線查詢, 這一個功能強大的提供各種針對性兼容辦法的網站,非常實用。
“-″下划線是IE6專有的hack
“\9″ IE6/IE7/IE8/IE9/IE10都生效
“\0″ IE8/IE9/IE10都生效,是IE8/9/10的hack
“\9\0″ 只對IE9/IE10生效,是IE9/10的hack
這里以IE6雙邊距問題為例。
代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> #div1{ width: 100px; height: 100px; background: lightgreen; float: left; margin-left: 100px; _margin-left: 50px; } </style> </head> <body> <div id="div1"></div> </body> </html>
效果:
1.6.3、選擇器前綴法
*html *前綴只對IE6生效
*+html *+前綴只對IE7生效
@media screen\9{...}只對IE6/7生效
@media \0screen {body { background: red; }}只對IE8有效
@media \0screen\,screen\9{body { background: blue; }}只對IE6/7/8有效
@media screen\0 {body { background: green; }} 只對IE8/9/10有效
@media screen and (min-width:0\0) {body { background: gray; }} 只對IE9/10有效
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {body { background: orange; }} 只對IE10有效
《hack速查表》:

<!DOCTYPE html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>hack速查表</title> <style type="text/css"> /*reset*/ * { margin: 0; padding: 0; } body { font: normal 12px/2 Tahoma, Arial, "\5b8b\4f53", Helvetica, sans-serif; height: 100%; text-align: center; background: #fff; } h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: normal; } /* Tables still need 'cellspacing="0"' in the markup. */ table { border-collapse: collapse; border-spacing: 0; } ul, ol { list-style: none; } em { font-style: normal; color: #f00; } h1 { font-size: 2em; font-weight: 700; } .hack { width: 1000px; margin: 0 auto; text-align: left; } .hack table { width: 100%; margin: 10px 0; } .hack td, .hack th { height: 30px; padding: 0 5px; border: 1px solid #ccc; } .hack th { color: #cc0bf6; } .hack th.eq, .hack td.eq { width: 350px; color: #333; } .hack th.identifier, .hack td.hack-data { width: 350px; color: #61602f; } .hack td.no { color: #fff; text-align: center; background-color: red; } .hack td.yes { color: #fff; text-align: center; background-color: green; } .hack p b { color: green; } .hack p b.red { color: red; } .hack h2 { margin: 10px 0 0 0; font-size: 1.5em; font-weight: 700; } .hack-list { margin: 10px 0; } .hack-list li { margin-bottom: 5px; zoom: 1; } .hack-list span { float: left; width: 15px; font-family: "\5b8b\4f53"; } .hack-list-inf { padding: 0 0 0 15px; } .hack-list em { display: inline-block; margin: 0 5px; } </style> </head> <body> <h1>hack速查表</h1> <div class="hack"> <p>建議:以標准瀏覽器為准書寫代碼,如遇到兼容問題,嘗試其他方法解決問題,在萬不得已怕情況下,采用HACK解決。</p> <p>以下是我總結的HACK書寫方法:</p> <p>瀏覽器:僅限IE6+,FF,safari,chrome,opera;(截止到2011.10.12非IE均為最新版本)。</p> <p>測試環境:windows系統;</p> <p>DOCTYPE: <!doctype html>.</p> <table cellpadding="0"> <thead> <tr> <th class="identifier">標志符</th> <th class="eq">示例</th> <th>IE6</th> <th>IE7</th> <th>IE8</th> <th>IE9</th> <th>FF</th> <th>OP</th> <th>SA</th> <th>CH</th> </tr> </thead> <tbody> <tr> <td class="hack-data">*</td> <td>.eq {*color:#000;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">_</td> <td>.eq {_color:#000;}</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">+</td> <td>.eq {+color:#000;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">-</td> <td>.eq {-color:#000;}</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">></td> <td>.eq {>color:#000;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">\0</td> <td>.eq {color:#000\0;}</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">\9</td> <td>.eq {color:#000\9;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">\9\0</td> <td>.eq {color:#000\0;}</td> <td class="no">N</td> <td class="no">N</td> <td>N\Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">:root .xx{xxx:xxx\9;}</td> <td>:root .eq {color:#a00\9;}</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">*+</td> <td>.eq {*+color:#000;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">*-</td> <td>.eq {*-color:#000;}</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">*html</td> <td><span class="hack-data">*html</span> .eq {color:#000;}</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">*+html</td> <td><span class="hack-data">*+html</span> .eq {color:#000;}</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">html*</td> <td>html* .eq {color:#000;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">[;</td> <td>.eq {color:red;[;color:blue;}</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">html>body</td> <td>html>body .eq {color:blue;}</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">html>/**/body</td> <td>html>/**/body .eq {color:blue;}</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">html/**/>body</td> <td>html/**/>body .eq {color:blue;}</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">@media all and (min-width:0px){}</td> <td><span class="hack-data">@media all and (min-width:0px){.eq {color:#000;}}</span></td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">*:first-child+html</td> <td>*:first-child+html .eq {color:blue;}</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">*:first-child+html{} *html</td> <td>*:first-child+html{} *html .eq {color:blue;}</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">@-moz-document url-prefix(){}</td> <td>@-moz-document url-prefix(){ .eq {color:blue;}}</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">@media screen and (-webkit-min-device-pixel-ratio:0){}</td> <td>@media screen and (-webkit-min-device-pixel-ratio:0){.eq {color:blue;}}</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> <tr> <td class="hack-data">@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0){}</td> <td><span class="hack-data">@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0){.eq {color:blue;}}</span></td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="no">N</td> <td class="no">N</td> </tr> <tr> <td class="hack-data">body:nth-of-type(1)</td> <td>body:nth-of-type(1) .eq {color:blue;}</td> <td class="no">N</td> <td class="no">N</td> <td class="no">N</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> <td class="yes">Y</td> </tr> </tbody> <tfoot> <tr> <th class="identifier">標志符</th> <th class="eq">示例</th> <th>IE6</th> <th>IE7</th> <th>IE8</th> <th>IE9</th> <th>FF</th> <th>OP</th> <th>SA</th> <th>CH</th> </tr> </tfoot> </table> <p>FF:firefox; OP:opera; SA:safari; CH:chrome; <b>Y</b>代表支持,<b class="red">N</b>代表不支持。</p> <h2>注意事項:</h2> <ul class="hack-list"> <li><span>·</span> <div class="hack-list-inf">由於各瀏覽器更新神速,所以有些HACK可能會有變化,所以請大家注意。</div> </li> <li><span>·</span> <div class="hack-list-inf"><em>[;</em>此種方式會影響后續樣式,不可取。</div> </li> <li><span>·</span> <div class="hack-list-inf"><em>\9\0</em>並非對所有屬性都能區分IE8和IE9.比如:background-color可以,但background不可以,還有border也不可以。所以在實際用時要測試下。</div> </li> <li><span>·</span> <div class="hack-list-inf">當同時出現<em>\0</em>;<em>*</em>;<em>_</em>;時,推薦將\0寫在*和_前面。例如:color:red\0;*color:blue;_color:green;可行,否則IE7和IE6里的效果會失效。但border例外,放在前后都可以。保險起見,還是放在前面。 </div> </li> </ul> <h2>推薦寫法:</h2> <h3>demo:</h3> <pre> .eq { color:#f00;/*標准瀏覽器*/ color:#f30\0;/*IE8,IE9,opera*/ *color:#c00;/*IE7及IE6*/ _color:#600;/*IE6專屬*/ } :root .eq {color:#a00\9;}/*IE9專屬*/ @media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0){.eq {color:#450;}}/*opera專屬*/ @media screen and (-webkit-min-device-pixel-ratio:0){.eq {color:#879;}}/*webkit專屬*/ @-moz-document url-prefix(){ .eq {color:#4dd;}}/*firefox專屬*/ </pre> </div> </body>
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> @media screen\0 { body { background: lightblue; } } </style> </head> <body> </body> </html>
運行結果:
1.7、文檔模式 (X-UA-Compatible)
文檔模式是IE8瀏覽器以后的一種獨有技術,他可以通過meta指定當前文檔的渲染模式,如可以把IE8降級成IE6、IE7使用。文檔模式的主要作用是影響瀏覽器顯示網頁HTML的方式,用於指定IE的頁面排版引擎(Trident)以哪個版本的方式來解析並渲染網頁代碼。
<meta http-equiv="X-UA-Compatible" content="IE=6" >
<meta http-equiv="X-UA-Compatible" content="IE=7" >
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" >
<meta http-equiv="X-UA-Compatible" content="IE=edge" >最新IE
“X-UA-Compatible”的值有兩種方式:Emulate+IE版本號,單純版本號
EmulateIE8:如果聲明了文檔類型,則以IE8標准模式渲染頁面,否則將文檔模式設置為IE5
9:強制以IE9標准模式渲染頁面,忽略文檔類型聲明
x-ua-compatible 頭標簽大小寫不敏感,必須用在 head 中,必須在除 title 外的其他 meta 之前使用。
<meta http-equiv="x-ua-compatible" content="IE=7,9,10" >
<meta http-equiv ="X-UA-Compatible" content = "IE=edge,chrome=1" />
Google Chrome Frame(谷歌內嵌瀏覽器框架GCF)
插件可以讓用戶的IE瀏覽器外不變,但用戶在瀏覽網頁時,實際上使用的是Google Chrome瀏覽器內核
未指定文檔模式時使用默認的文檔模式示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>X-UA-Compatible</title> <style> #div1 { width: 100px; height: 100px; background: lightgreen; float: left; margin-left: 100px; _margin-left: 50px; } </style> </head> <body> <div id="div1"></div> </body> </html>
運行結果:
強制指定文檔模式為IE6,在IE8下會自動變成怪異模式,簡單說IE8被當作IE6在用。
多數情況下我們不會這樣降級使用,一般會將IE選擇為最新版本的文檔模式(注意不是文檔類型),如果IE瀏覽器使用了GCF技術我們應該強制使用最新版內核,寫入如下:
<meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1" />
現在多數網站這是這種寫法如baidu。
1.8、javascript兼容
這里有兩層意思,第一可以使用javascript操作樣式與標簽,強制瀏覽器兼容,比如先使用javascript判斷瀏覽器類型,再操作樣式與標簽。
第二指javascript存在兼容問題,如一個對象在某些瀏覽器下沒有辦法使用,要讓javascript更加兼容,可以采取如下辦法:
1、使用第三方提代的javascript庫,如jQuery,Zepto, Prototype,dojo、YUI、ExtJS
像jQuery這種成熟的javascript庫經過多次的版本迭代,已經變得非常成熟,世界上的網站到現在近60%都使用到了jQuery,他的兼容性不錯。
2、瀏覽器檢測、重新封裝
使用javascript判斷瀏覽器類型,對一些特點的方法或對象重新封裝后使用屏蔽瀏覽的不兼容性。可以使用User-Agent、或特定對象。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h2 id="msg"></h2> <script type="text/javascript"> //用於檢測瀏覽器是否為IE var isIE=function(){ return !!window.ActiveXObject; } function show(info){ document.getElementById("msg").innerHTML+=info+"<br/>" } //獲得用戶代理對象,瀏覽器與操作系統信息 show(navigator.userAgent); show(isIE()?"是IE瀏覽器":"不是IE瀏覽器"); </script> </body> </html>
效果:
在user-agent中包含有不少的客戶端信息,可以解析出判斷瀏覽器部分的內容。
檢測IE各個版本,非IE返回0
var ieVersion = /*@cc_on (function() {switch(@_jscript_version) {case 1.0: return 3; case 3.0: return 4; case 5.0: return 5; case 5.1: return 5; case 5.5: return 5.5; case 5.6: return 6; case 5.7: return 7; case 5.8: return 8; case 9: return 9; case 10: return 10;}})() || @*/ 0; alert(ieVersion); var isIE = !!window.ActiveXObject; alert(isIE);
二、前端性能優化
2.1、概要
在保證功能的前提下,性能也非常關鍵。從上圖可以看出如果性能太差,響應速度慢將帶非常差的用戶體驗,會失去大量用戶。好的性能要依托如下幾個方面:
1)、服務器端
2)、網絡速度,客戶端與服務器之間的每個網絡環節
3)、客戶端軟件與硬件配置
4)、前端的性能,資源的數量,大小,javascript的時間與空間復雜度等
要提高前端的性能可以從如下幾個方面入手:
1)、盡量減少HTTP請求數量
2)、壓縮
3)、緩存
4)、使用內容發布網絡(CDN的使用)
5)、DNS Prefetch
6)、將CSS樣式表放在頂部
7)、將javascript腳本放在底部
8)、使用外部javascript和CSS
9)、避免重定向
2.2、減少HTTP請求數量
前端優化的黃金准則指導着前端頁面的優化策略:只有10%-20%的最終用戶響應時間花在接受請求的HTML文檔上,剩下的80%-90%時間花在為HTML文檔所引用的所有組件(圖片、腳本、樣式表等)進行的HTTP請求上。
1、圖片地圖
2、CSS Sprite
3、Data URI Scheme(內聯資源)
4、樣式表的合並
5、使用Web Font字體圖標
2.2.1、圖片地圖
圖片地圖與稱熱點圖片,不算新技術,早在HTML4.0中就存在了,就是在圖片的指定區域指定超鏈接。這樣做的目的是將原本需要物理拆分的圖片合並在一起,通過熱點單獨指定鏈接,間接的減少了客戶端請求服務器圖片的數量。
示例代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <img src="img/banner.jpg" width="600" usemap="#Map"/> <map name="Map"> <area shape="rect" coords="22,35,149,148" href="#" onclick="return show('鳥')"> <area shape="circle" coords="505,88,75" href="#" onclick="return show('獎杯')"> <area shape="rect" coords="168,39,392,70" href="#" onclick="return show('文字')"> </map> <script type="text/javascript"> function show(arg){ alert(arg); return false; } </script> </body> </html>
運行效果:
2.2.2、精靈圖片(Sprite)
就是把多張細小的圖片拼成一張大圖片,然后通過CSS來控制在什么地方具體顯示這整張圖片的什么位置,使用CSS裁剪出想要的圖片,這樣可以減少客戶端請求小圖片的次數。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>CSS Sprite</title> <style type="text/css"> #icon{ height: 64px; width: 56px; background: url(img/allbgs.png) no-repeat #fff; background-position: -128px 0; } </style> </head> <body> <h2>CSS Sprite</h2> <div id="icon"></div> </body> </html>
詳細請查看我的另一篇文章:《CSS3與頁面布局學習總結(五)——Web Font與Sprite》
2.2.3、字體圖標(Web Font)
使用@font-face能夠加載服務器端的字體文件,讓客戶端顯示客戶端所沒有安裝的字體,可以實現矢量圖標,一次加載反復使用多個圖標,相當於圖標都變成了字體。可以將多個小圖標定義在一個字體中,減少圖標的請求次數。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>font-face</title> <style type="text/css"> @font-face { font-family: 'iconfont'; /*字體名稱*/ src: url('font/fontello.eot?53711433'); /*字體文件路徑*/ src: url('font/fontello.eot?53711433#iefix') format('embedded-opentype'), url('font/fontello.woff2?53711433') format('woff2'), url('font/fontello.woff?53711433') format('woff'), url('font/fontello.ttf?53711433') format('truetype'), url('font/fontello.svg?53711433#fontello') format('svg'); font-weight: normal; /*加粗*/ font-style: normal; /*字形,如斜體*/ } .ok{ font-family: iconfont; font-size: 16px; color: blue; } </style> </head> <body> <i class="ok"></i>贊 <i class="ok"></i>贊 </body> </html>
運行效果:
具體請查看我的另一篇文章:《CSS3與頁面布局學習總結(五)——Web Font與Sprite》
2.2.4、內聯資源(Data URI Scheme)
所謂的內聯資源就是將一些小的資源文件序列化成base64的編碼,放在CSS樣式或頁面中,在客戶端再解析,優點是合並了小的文件,減少請求,把二進制變成了字符串方便存儲,但是會出一個沒有意義的長字符串影響開發時閱讀代碼,另外在某些情況下將失去圖片的緩存。
data類型的Url格式,是1998年在RFC2397中提出,現在多數瀏覽器支持,IE8支持。可以在CSS,HTML中嵌入小的非字符數據。
直接引用:
<img src="data:image/jpeg;base64,/9j/4AAQSk.."/>
樣式中引用:
background: url(data:image/gif;base64,R0lGOD==)
示例:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>內聯數據</title> <style type="text/css"> .cls1 { width: 200px; height: 200px; background: url(data:image/jpeg;base64,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); } </style> </head> <body> <img src="data:image/jpeg;base64,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" /> <div class="cls1"> </div> </body> </html>
效果:
如果需要將圖片或其它資源文件轉成base64編碼,可以使用轉換工具、在線轉換或使用Less等方法。
當然字體也可以轉換,可以參考前面的文章。
目前,Data URI scheme支持的類型有:
data:,文本數據
data:text/plain,文本數據
;javascript:;,HTML代碼
;javascript:;;base64,base64編碼的HTML代碼
data:text/css,CSS代碼
data:text/css;base64,base64編碼的CSS代碼
data:text/javascript,Javascript代碼
data:text/javascript;base64,base64編碼的Javascript代碼
data:image/gif;base64,base64編碼的gif圖片數據
data:image/png;base64,base64編碼的png圖片數據
data:image/jpeg;base64,base64編碼的jpeg圖片數據
data:image/x-icon;base64,base64編碼的icon圖片數據
javascript使用:
<script src="data:text/javascript;base64,YWxlcnQoJ0hlbGxvIEJhc2U2NCcp" type="text/javascript" charset="utf-8"></script>
2.2.5、合並資源
將多個小的離散的css、js文件合並,注意粒度,把多個請求變成1個請求
手動合並:復制粘貼
工具合並
copy a.js+b.js+c.js abc.js /b
Jscompres
CssGaga
2.3、壓縮
用戶請求的資源越小速度將越快,網絡帶寬占用越小,但是壓縮將占用更多的CPU資源,壓縮與解壓也是需要成本的。
2.3.1、GZIP壓縮
GZIP,即網頁壓縮,是由WEB服務器和瀏覽器之間共同遵守的協議
Gzip通常可以減少70%網頁內容的大小,包括腳本、樣式表、圖片等文件
2.3.2、開啟Tomcat Gzip壓縮
使用gzip壓縮可以減少數據傳輸大小,加快網頁加載速度。很多大站都開啟了gzip壓縮,不過也有很多網站並沒有開啟gzip壓縮,gzip壓縮后對SEO不友好,但從帶寬和流量的角度來看,還是有必要開啟gzip壓縮的。
對於tomcat7服務器,打開conf文件夾下的server.xml 文件,找到
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
修改為:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla,traviata" compressableMimeType="text/html,text/xml,text/javascript,application/x-javascript,application/javascript,text/css,text/plain"/>
compression="on" 開啟壓縮
compressionMinSize="2048"大於2KB的文件才進行壓縮(《高性能網站建設指南》建議1KB或者2KB以上)
noCompressionUserAgents="gozilla, traviata",對於這兩種瀏覽器,不進行壓縮
compressableMimeType="text/html,text/xml,application/javascript,text/css,text/plain,text/json"表明支持的文件格式的壓縮
測試運行:
保存退出,重啟tomcat服務器即可。可以使用下面網站測一下gzip是否開啟:
http://www.gidnetwork.com/tools/gzip-test.php
2.3.3、開啟IIS Gzip壓縮
IIS設置示例:
未啟用gzip時的文件大小:
啟用gzip時的文件大小:
約8.6倍,當然這里只是一個人為構造的示例,壓縮對字符很有效,但是圖片因為已經是壓縮格式效果不明顯,另外還要注意為了提高性能,注釋在發布后應該刪除。
2.3.4、壓縮javascript、css
可以在IDE中安裝插件,也可以使用單獨的工具,或者在前端自動化中設置壓縮步驟。
2.3.5、優化圖像
選擇合適的圖像壓縮格式,常見是gif、jpg、png
離線工具:jpegmini.exe
在線工具:http://img.hust.cc/
未壓縮前的圖片,311KB:
壓縮后的圖片,124KB:
比較一下,很難發現他們的質量有什么區別,但是有2.5倍的體積差別,使用的壓縮工具是:
https://tinypng.com/
http://zhitu.isux.us/
2.3.6、壓縮HTML
去除html中的多余空格、注釋等內容(演示)
后台動態壓縮,頁面渲染時壓縮
這里使用一個asp.net中的示例,在頁面輸出前在服務將內容壓縮,代碼如下:
using System; using System.Collections.Generic; using System.Configuration; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Text.RegularExpressions; using System.IO; /// <summary> ///BP 的摘要說明 /// </summary> public class BasePage : Page { public BasePage() { } protected override void OnInit(EventArgs e) { base.OnInit(e); } protected override void Render(HtmlTextWriter writer) { StringWriter sw = new StringWriter(); HtmlTextWriter htw = new HtmlTextWriter(sw); base.Render(htw); string op = sw.ToString(); op = Regex.Replace(op, "<!--.*-->", ""); op = Regex.Replace(op, @"\s+", " "); op = Regex.Replace(op, @">\s+<", "><"); op = op.Replace(@"//<![CDATA[", "//<![CDATA[" + Environment.NewLine); op = op.Replace(@"//.*\s+", ""); writer.Write(op); } }
2.4、緩存
2.4.1、http頭部緩存
<meta http-equiv="Expires" content="Tue, 01 Dec 2015 13:30:26 GMT" />
Expires是Web服務器響應消息頭字段,在響應http請求時告訴瀏覽器在過期時間前瀏覽器可以直接從瀏覽器緩存取數據,而無需再次請求新內容,可以使用客戶端緩存的內容,但是請求還是會發生,狀態為304。瀏覽器會默認開啟緩存功能。
因為Expires是HTTP 1.0中的內容,現在默認瀏覽器均默認使用HTTP 1.1,所以它的作用基本忽視,在1.1中我們使用Cache-control,詳細如下:
Public 指示響應可被任何緩存區緩存。
Private 指示對於單個用戶的整個或部分響應消息,不能被共享緩存處理。這允許服務器僅僅描述當用戶的部分響應消息,此響應消息對於其他用戶的請求無效。
no-cache 指示請求或響應消息不能緩存(HTTP/1.0用Pragma的no-cache替換)根據什么能被緩存
no-store 用於防止重要的信息被無意的發布。在請求消息中發送將使得請求和響應消息都不使用緩存。根據緩存超時
max-age 指示客戶機可以接收生存期不大於指定時間(以秒為單位)的響應。
min-fresh 指示客戶機可以接收響應時間小於當前時間加上指定時間的響應。
max-stale 指示客戶機可以接收超出超時期間的響應消息。如果指定max-stale消息的值,那么客戶機可以接收超出超時期指定值之內的響應消息。
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta http-equiv="Expires" content="Mon, 20 Jul 2009 23:00:00 GMT" />
2.4.2、本地存儲
LocalStorage、SessionStorage、Web SQL Database
2.4.3、離線緩存
ApplicationCache,在斷開服務器時仍然可以使用客戶端的緩存文件,繼續瀏覽。
2.4.4、動態頁面靜態化
將動態內容,需要復雜計算的內容變成靜態的如HTML、JavaScript
不能靜態化的部分可以使用ajax。
2.5、內容分發網絡 (CDN)
CDN的全稱是Content Delivery Network,即內容分發網絡。其基本思路是盡可能避開互聯網上有可能影響數據傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定,它是一個經策略性部署的整體系統,包括分布式存儲、負載均衡、網絡請求的重定向和內容管理4個要件。
比如我們在項目中使用jQuery ,加載本地服務器的jQuery可能不如資源公共庫中做過CDN優化的資源快。
http://cdn.code.baidu.com/ 百度靜態資源公共庫
2.6、DNS Prefetch
DNS Prefetch 是一種 DNS 預解析技術。當你瀏覽網頁時,瀏覽器會在加載網頁時對網頁中的域名進行解析緩存,這樣在你單擊當前網頁中的連接時就無需進行 DNS 的解析,減少用戶等待時間,提高用戶體驗。
1)、通過 link 標簽
< link rel="dns-prefetch" href="http://api.twitter.com" />
2)、通過 meta 標簽
< meta http-equiv="x-dns-prefetch-control" content="on" />
3)、設置 Http header 的 x-dns-prefetch-control 屬性為 on 進行控制。
Firefox: 3.5+ Chrome: Supported
Safari 5+ IE: 9
2.7、小節
優化是沒有止境的,只有更快沒有最快,下面兩篇文章只介紹了更多關於前端優化的方法。
英文原文:https://developer.yahoo.com/performance/rules.html
中文翻譯:http://www.cnblogs.com/developersupport/p/webpage-performance-best-practices.html
《高性能網站建設指南》這本書中提出了一些規則:
規則1——減少HTTP請求
規則2——使用內容發布網絡
規則3——添加Expires頭
規則4——壓縮組件
規則5——將樣式表放在頂部
規則6——將腳本放在底部
規則7——避免CSS表達式
規則8——使用外部JavaScript和CSS
規則9——減少DNS查找
規則10——精簡JavaScript
規則11——避免重定向
規則12——移除重復腳本
規則13——配置ETag
規則14——使AjaX可緩存
三、示例下載
https://github.com/zhangguo5/CSS3_8
https://git.coding.net/zhangguo5/CSS301.git
四、視頻
https://www.bilibili.com/video/av16530230/
五、作業
5.1、請完成一個響應式登錄頁面,要求同時兼容chrome瀏覽器、Firefox瀏覽器、Safari瀏覽器、IE6/7/8/9/10/11,兼容不同的分辨率,特別是手機
5.2、請完成小米商城、必須兼容IE8、Chrome瀏覽器、FireFox、IE11,兼容不同的PC分辨率
5.3、請完成如下頁面布局,(https://red.jd.com/)
要求:打開頁面時只產生一個HTTP請求,請求大小不超過10K,緩存