一、浏览器兼容

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

从上图可以看出,我们在针对PC Web开发时需要重点关注Chrome、IE浏览器,开发Mobile项目时要重点关注Chrome浏览器与Safari。

1.4、兼容的一般标准

1)、在不同的主流的浏览器上表现效果一致

2)、能适应不同的屏幕大小

3)、能适应不同的分辨率与色彩深度

浏览器兼容在线测试:

http://browsershots.org/

http://browsershots.org/

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

 CSSReset详细内容请查看:CSS3与页面布局学习笔记(二)——Box Model、边距折叠、内联与块标签、CSSReset

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>
<metacharset="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>
<metacharset="UTF-8">
<title></title>
<styletype="text/css">#div1{width:100px;height:100px;background:lightgreen;float:left;margin-left:100px;_margin-left:50px;
}
</style>
</head>
<body>
<divid="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>
<metahttp-equiv="Content-Type"content="text/html; charset=utf-8" />
<title>hack速查表</title>
<styletype="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>
<divclass="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>
<tablecellpadding="0">
<thead>
<tr>
<thclass="identifier">标志符</th>
<thclass="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>
<tdclass="hack-data">*</td>
<td>.eq {*color:#000;}</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">_</td>
<td>.eq {_color:#000;}</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data"> </td>
<td>.eq { color:#000;}</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">-</td>
<td>.eq {-color:#000;}</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">></td>
<td>.eq {>color:#000;}</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">\0</td>
<td>.eq {color:#000\0;}</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">\9</td>
<td>.eq {color:#000\9;}</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">\9\0</td>
<td>.eq {color:#000\0;}</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<td>N\Y</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">:root .xx{xxx:xxx\9;}</td>
<td>:root .eq {color:#a00\9;}</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">* </td>
<td>.eq {* color:#000;}</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">*-</td>
<td>.eq {*-color:#000;}</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">*html</td>
<td><spanclass="hack-data">*html</span> .eq {color:#000;}</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">* html</td>
<td><spanclass="hack-data">* html</span> .eq {color:#000;}</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">html*</td>
<td>html* .eq {color:#000;}</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">[;</td>
<td>.eq {color:red;[;color:blue;}</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
</tr>
<tr>
<tdclass="hack-data">html>body</td>
<td>html>body .eq {color:blue;}</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
</tr>
<tr>
<tdclass="hack-data">html>/**/body</td>
<td>html>/**/body .eq {color:blue;}</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
</tr>
<tr>
<tdclass="hack-data">html/**/>body</td>
<td>html/**/>body .eq {color:blue;}</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
</tr>
<tr>
<tdclass="hack-data">@media all and (min-width:0px){}</td>
<td><spanclass="hack-data">@media all and (min-width:0px){.eq {color:#000;}}</span></td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
</tr>
<tr>
<tdclass="hack-data">*:first-child html</td>
<td>*:first-child html .eq {color:blue;}</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">*:first-child html{} *html</td>
<td>*:first-child html{} *html .eq {color:blue;}</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">@-moz-document url-prefix(){}</td>
<td>@-moz-document url-prefix(){ .eq {color:blue;}}</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="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>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
</tr>
<tr>
<tdclass="hack-data">@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0){}</td>
<td><spanclass="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>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
</tr>
<tr>
<tdclass="hack-data">body:nth-of-type(1)</td>
<td>body:nth-of-type(1) .eq {color:blue;}</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="no">N</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
<tdclass="yes">Y</td>
</tr>
</tbody>
<tfoot>
<tr>
<thclass="identifier">标志符</th>
<thclass="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>代表支持,<bclass="red">N</b>代表不支持。</p>
<h2>注意事项:</h2>
<ulclass="hack-list">
<li><span>·</span>
<divclass="hack-list-inf">由于各浏览器更新神速,所以有些HACK可能会有变化,所以请大家注意。</div>
</li>
<li><span>·</span>
<divclass="hack-list-inf"><em>[;</em>此种方式会影响后续样式,不可取。</div>
</li>
<li><span>·</span>
<divclass="hack-list-inf"><em>\9\0</em>并非对所有属性都能区分IE8和IE9.比如:background-color可以,但background不可以,还有border也不可以。所以在实际用时要测试下。</div>
</li>
<li><span>·</span>
<divclass="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>

View Code

示例:

<!DOCTYPE html>
<html>
<head>
<metacharset="UTF-8">
<title></title>
<styletype="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>
<metacharset="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>
<divid="div1"></div>
</body>
</html>

运行结果:

强制指定文档模式为IE6,在IE8下会自动变成怪异模式,简单说IE8被当作IE6在用。

多数情况下我们不会这样降级使用,一般会将IE选择为最新版本的文档模式(注意不是文档类型),如果IE浏览器使用了GCF技术我们应该强制使用最新版内核,写入如下:

<metahttp-equiv=X-UA-Compatiblecontent="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>
<metacharset="UTF-8">
<title></title>
</head>
<body>
<h2id="msg"></h2>
<scripttype="text/javascript">
//用于检测浏览器是否为IE
varisIE=function(){return !!window.ActiveXObject;
}functionshow(info){
document.getElementById("msg").innerHTML=info"<br/>"}//获得用户代理对象,浏览器与操作系统信息
show(navigator.userAgent);
show(isIE()?"是IE浏览器":"不是IE浏览器");</script>
</body>
</html>

效果:

在user-agent中包含有不少的客户端信息,可以解析出判断浏览器部分的内容。

二、前端性能优化

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>
<metacharset="UTF-8">
<title></title>
</head>
<body>
<imgsrc="img/banner.jpg"width="600"usemap="#Map"/>
<mapname="Map">
<areashape="rect"coords="22,35,149,148"href="#"onclick="return show('鸟')">
<areashape="circle"coords="505,88,75"href="#"onclick="return show('奖杯')">
<areashape="rect"coords="168,39,392,70"href="#"onclick="return show('文字')">
</map>
<scripttype="text/javascript">
functionshow(arg){
alert(arg);return false;
}</script>
</body>
</html>

运行效果:

2.2.2、精灵图片(Sprite)

就是把多张细小的图片拼成一张大图片,然后通过CSS来控制在什么地方具体显示这整张图片的什么位置,使用CSS裁剪出想要的图片,这样可以减少客户端请求小图片的次数。

示例:

<!DOCTYPE html>
<html>
<head>
<metacharset="UTF-8">
<title>CSS Sprite</title>
<styletype="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>
<divid="icon"></div>
</body>
</html>

Sprite详细内容请看:CSS3与页面布局学习笔记(五)——Web Font与Sprite

2.2.3、字体图标(Web Font)

使用@font-face能够加载服务器端的字体文件,让客户端显示客户端所没有安装的字体,可以实现矢量图标,一次加载反复使用多个图标,相当于图标都变成了字体。可以将多个小图标定义在一个字体中,减少图标的请求次数。

示例:

<!DOCTYPE html>
<html>
<head>
<metacharset="UTF-8">
<title>font-face</title>
<styletype="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>
<iclass="ok">&#59405</i><iclass="ok">&#xe80d</i></body>
</html>

运行效果:

Web Font详细内容请看:CSS3与页面布局学习笔记(五)——Web Font与Sprite

2.2.4、内联资源(Data URI Scheme)

所谓的内联资源就是将一些小的资源文件序列化成base64的编码,放在CSS样式或页面中,在客户端再解析,优点是合并了小的文件,减少请求,把二进制变成了字符串方便存储,但是会出一个没有意义的长字符串影响开发时阅读代码,另外在某些情况下将失去图片的缓存。

data类型的Url格式,是1998年在RFC2397中提出,现在多数浏览器支持,IE8支持。可以在CSS,HTML中嵌入小的非字符数据。

直接引用:
<img src="https://img-blog.csdnimg.cn/2022010615002050370.jpeg"/>

样式中引用:
background: url(data:image/gif;base64,R0lGOD==)

示例:

<!DOCTYPE html>
<html>
<head>
<metacharset="UTF-8">
<title>内联数据</title>
<styletype="text/css">.cls1{width:200px;height:200px;background:url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCABLAEsDASIAAhEBAxEB/8QAHAAAAgMBAQEBAAAAAAAAAAAABgcABAgFAwEC/8QAPRAAAQMCAwUDCQYFBQAAAAAAAQIDBAAFBhESBxMhMYFBcZEVIjJCUVJyocEIFDNhguEkQ2KSsRYjotHw/8QAGwEAAgIDAQAAAAAAAAAAAAAAAwUABwEEBgL/xAAxEQABAwIDBgQEBwAAAAAAAAABAAIDBBEFIUEGEjFRcZETImGhFIGx0QcVMjNiweH/2gAMAwEAAhEDEQA/ANN1KqXO4MW9lLjwWdRySEjPM0FYi2jQLfqQqSwwoeon/dd8BwHWsOcGi5KNBTy1D9yJpceQF0frWhtBWtSUJHMqOQrlTcQW OFaFqfI56PRHeTwpIX7aZLlLUIUdSj2Oyl6vBI4DxoNut7ut0J /TnnUn XnpQP0jhWnJXRt/TmuuoNh6 os6ciMeuZ7D yE8bptNtceYlhVygxzqyy4uAfkpQ4CiC1Yuiy2UuKShxs/wA2OsLTSow9gNM3ZFMuj7QEy5SAIKiPQQ2FZEfEvMdwFKaFMnW2RvIcl I8k5K3aykgjmDWPintAc8ZFR2zVJNJJDSynejNje1iflwzuNeC2bEnw5Y/h5CFn3c8leB41ZrLFm2lXqIUpntMz0D1iN254jh8qYeG9rNud0tuznIiuW7mJzR0WP2o7KmN qS1ez9dTZlm8OYz/wB9k5KlD9nxRFnlpOgHekBDjKwtBJogo6TEEGxXCxwzvrKR/Xp/uSRWVSnQSk8wcjWtsSI12V/ nSvwIrKl7Z 73qcxllokOJ/5GluIjJpVjfh7L554 Yae1/uqddLC9nk4gxDBssTPezHg3q9wesroAT0rm08fsw4bzVOxXJb4DOJEJHbwLih8k NaEEfiSBq7jG8RGHUL59RkOp4ffomLjWLEtmFrfbYgS0ywtDTCM8jpSgjh04msx7V7N5NxGZjSMo88F0ZDgHB6Y/wetHv2gMaPI2iQmIS9TFiUErSDwW6sZuj 3JPjXpjW2tYlwgpUPJxegSoih2nLPLqCRTWQtma5reIVW0LJ8IngqJj5Zhn6XOV/Y90janKpUFLVYaeH2eouVtZcy/FnLX0SkD6U76VeweLurDbCRxLDjx/Uo/8AdNSnUItGAqfxaTxK6V38j7GyrXRG8tslv3mlf4rLeO2t1i64j3nAsfqSDWrFJ1JKfaMqzHtUY3OK1HL02EHqM0/StXEBeMH1XTbBy7uIuZzafqChu3xJE dHgxGy5IkOpaaQO1SjkPma2Lh 0f6awjGs9rbQ65Ci6WwpWlLruRJJPZqXmSfzpG/Zqw15QxK/iKQ3nHtidDOY4F9Y5/pTme9Qo 2t7UHcGXiJaoFujTn1sb5/fOKSGwTkgDT2nInwoVIGxRmV qabVyz4pXsw2lG8WZkaXtr0H1slLizZRjhtK7jcjbVuyZBU4sS8ypas1E j7c6INn9uvFosnk667k7lZMdTbmvzDxyPDhkc/GqGJttt1uUFDLuH7egJcCgUPuZ8iO3vrgRdqUhUppMm1Rm2CsBxSXVEpTnxI7hXuF9Ow3aStPFqXHaxnhVETbCxytpyzQ/tKs3kfEzpaRpjS832cuQzPnJ6H5EUME5JJ9gp27TLOLxhhbzAC34n8QyR6ycvOA708egpLRmy/JaZTxLi0oHUgfWgVEe4/LVNsAxD4ujBcfM3I/Lge3vdaj2TxPu1pjt5ZbmCyjqQCaOKH8ENBuJII5a0oHcB 9EFNgLCyq6R  8uOualZ524xiziBl0JORDrfULzA daGrh4hw1Bu7bm8Qgqc9NLidSF947D Yoc8XisLUzwTE/yytZUltwL3HUWQvs1x3s9wngyBaDeVmQE72UpEN06nlcVerxy4AfkKSmNr47iTFdxvTuYEl8ltJ9RscEJ6JAoxxfszkQ3FOW3Nonkw6rNCvgX9DS8mxJMKQqPLYcYeTzQtOR/fvpVUmUNDHCwCtDZxmFyzSVdLIXSP4h1ri5ucrDXqFQn/gD4hVCr8/8AAHxVRQlS1JQlKlKUckgDMk wCgM4JrXfulNXBGOLQxhyNEvE3cyY4LXnNqVrQPROYB7OHShG3Q4L 0eKxaXfvMFUxDrZSkjSjPUQQRwy5eFdPCeze6XNbbtz1wmVcQylOp5fT1evH8qdmEcBQbTGCER0REH0gk6nV/Ev/wB0pmyOSUDfFgO6rmrrqDDZJTSuLnPvcAjdF9eGnpdEOEkabOF  4pX0 ldevOMy1HYSyygIbTyAr0reXFKVKlSoovy62262W3UJWhXNKhmDQnijBMC6xygMNuo5hpw8U/CrmKLqlYIBFivccj4nB7CQRqOKzre9l8nyimPHm7lgqzWl9BLiB7ABwV8qYGCNm0G0oS6lgtOEec 8Ap5Xd2IHdTJKEFSVlKSpPokjiO6vtCZBGw3aEzrccrq1gZNJcdr9bcVWgQYsJGmO0Ek81Hio95qzUqUZKVKlSpUUX//2Q==);}
</style>
</head>
<body>
<imgsrc="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCABLAEsDASIAAhEBAxEB/8QAHAAAAgMBAQEBAAAAAAAAAAAABgcABAgFAwEC/8QAPRAAAQMCAwUDCQYFBQAAAAAAAQIDBAAFBhESBxMhMYFBcZEVIjJCUVJyocEIFDNhguEkQ2KSsRYjotHw/8QAGwEAAgIDAQAAAAAAAAAAAAAAAwUABwEEBgL/xAAxEQABAwIDBgQEBwAAAAAAAAABAAIDBBEFIUEGEjFRcZETImGhFIGx0QcVMjNiweH/2gAMAwEAAhEDEQA/ANN1KqXO4MW9lLjwWdRySEjPM0FYi2jQLfqQqSwwoeon/dd8BwHWsOcGi5KNBTy1D9yJpceQF0frWhtBWtSUJHMqOQrlTcQW OFaFqfI56PRHeTwpIX7aZLlLUIUdSj2Oyl6vBI4DxoNut7ut0J /TnnUn XnpQP0jhWnJXRt/TmuuoNh6 os6ciMeuZ7D yE8bptNtceYlhVygxzqyy4uAfkpQ4CiC1Yuiy2UuKShxs/wA2OsLTSow9gNM3ZFMuj7QEy5SAIKiPQQ2FZEfEvMdwFKaFMnW2RvIcl I8k5K3aykgjmDWPintAc8ZFR2zVJNJJDSynejNje1iflwzuNeC2bEnw5Y/h5CFn3c8leB41ZrLFm2lXqIUpntMz0D1iN254jh8qYeG9rNud0tuznIiuW7mJzR0WP2o7KmN qS1ez9dTZlm8OYz/wB9k5KlD9nxRFnlpOgHekBDjKwtBJogo6TEEGxXCxwzvrKR/Xp/uSRWVSnQSk8wcjWtsSI12V/ nSvwIrKl7Z 73qcxllokOJ/5GluIjJpVjfh7L554 Yae1/uqddLC9nk4gxDBssTPezHg3q9wesroAT0rm08fsw4bzVOxXJb4DOJEJHbwLih8k NaEEfiSBq7jG8RGHUL59RkOp4ffomLjWLEtmFrfbYgS0ywtDTCM8jpSgjh04msx7V7N5NxGZjSMo88F0ZDgHB6Y/wetHv2gMaPI2iQmIS9TFiUErSDwW6sZuj 3JPjXpjW2tYlwgpUPJxegSoih2nLPLqCRTWQtma5reIVW0LJ8IngqJj5Zhn6XOV/Y90janKpUFLVYaeH2eouVtZcy/FnLX0SkD6U76VeweLurDbCRxLDjx/Uo/8AdNSnUItGAqfxaTxK6V38j7GyrXRG8tslv3mlf4rLeO2t1i64j3nAsfqSDWrFJ1JKfaMqzHtUY3OK1HL02EHqM0/StXEBeMH1XTbBy7uIuZzafqChu3xJE dHgxGy5IkOpaaQO1SjkPma2Lh 0f6awjGs9rbQ65Ci6WwpWlLruRJJPZqXmSfzpG/Zqw15QxK/iKQ3nHtidDOY4F9Y5/pTme9Qo 2t7UHcGXiJaoFujTn1sb5/fOKSGwTkgDT2nInwoVIGxRmV qabVyz4pXsw2lG8WZkaXtr0H1slLizZRjhtK7jcjbVuyZBU4sS8ypas1E j7c6INn9uvFosnk667k7lZMdTbmvzDxyPDhkc/GqGJttt1uUFDLuH7egJcCgUPuZ8iO3vrgRdqUhUppMm1Rm2CsBxSXVEpTnxI7hXuF9Ow3aStPFqXHaxnhVETbCxytpyzQ/tKs3kfEzpaRpjS832cuQzPnJ6H5EUME5JJ9gp27TLOLxhhbzAC34n8QyR6ycvOA708egpLRmy/JaZTxLi0oHUgfWgVEe4/LVNsAxD4ujBcfM3I/Lge3vdaj2TxPu1pjt5ZbmCyjqQCaOKH8ENBuJII5a0oHcB 9EFNgLCyq6R  8uOualZ524xiziBl0JORDrfULzA daGrh4hw1Bu7bm8Qgqc9NLidSF947D Yoc8XisLUzwTE/yytZUltwL3HUWQvs1x3s9wngyBaDeVmQE72UpEN06nlcVerxy4AfkKSmNr47iTFdxvTuYEl8ltJ9RscEJ6JAoxxfszkQ3FOW3Nonkw6rNCvgX9DS8mxJMKQqPLYcYeTzQtOR/fvpVUmUNDHCwCtDZxmFyzSVdLIXSP4h1ri5ucrDXqFQn/gD4hVCr8/8AAHxVRQlS1JQlKlKUckgDMk wCgM4JrXfulNXBGOLQxhyNEvE3cyY4LXnNqVrQPROYB7OHShG3Q4L 0eKxaXfvMFUxDrZSkjSjPUQQRwy5eFdPCeze6XNbbtz1wmVcQylOp5fT1evH8qdmEcBQbTGCER0REH0gk6nV/Ev/wB0pmyOSUDfFgO6rmrrqDDZJTSuLnPvcAjdF9eGnpdEOEkabOF  4pX0 ldevOMy1HYSyygIbTyAr0reXFKVKlSoovy62262W3UJWhXNKhmDQnijBMC6xygMNuo5hpw8U/CrmKLqlYIBFivccj4nB7CQRqOKzre9l8nyimPHm7lgqzWl9BLiB7ABwV8qYGCNm0G0oS6lgtOEec 8Ap5Xd2IHdTJKEFSVlKSpPokjiO6vtCZBGw3aEzrccrq1gZNJcdr9bcVWgQYsJGmO0Ek81Hio95qzUqUZKVKlSpUUX//2Q==" />
<divclass="cls1">
</div>
</body>
</html>

View Code

效果:

如果需要将图片或其它资源文件转成base64编码,可以使用转换工具、在线转换或使用Less等方法。

当然字体也可以转换,可以参考前面的文章。

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 文件,找到

<Connectorport="8080"protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />

修改为:

<Connectorport="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"/>

测试运行:

保存退出,重启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中的示例,在页面输出前在服务将内容压缩,代码如下:

usingSystem;usingSystem.Collections.Generic;usingSystem.Configuration;usingSystem.Web;usingSystem.Web.UI;usingSystem.Web.UI.WebControls;usingSystem.Text.RegularExpressions;usingSystem.IO;/// <summary>
///BP 的摘要说明/// </summary>
public classBasePage : Page
{publicBasePage()
{
}protected override voidOnInit(EventArgs e)
{base.OnInit(e);
}protected override voidRender(HtmlTextWriter writer)
{
StringWriter sw= newStringWriter();
HtmlTextWriter htw= newHtmlTextWriter(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

详细内容请看:HTML5 学习笔记(三)——本地存储(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/ 百度静态资源公共库

http://lib.sinaapp.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

参照:http://www.cnblogs.com/best

CSS3与页面布局学习笔记(八)——浏览器兼容性问题与前端性能优化方案相关推荐

  1. CSS3与页面布局学习笔记(四)——页面布局大全(负边距、双飞翼、多栏、弹性、流式、瀑布流、响应式布局)

    一.负边距与浮动布局 1.1.负边距 所谓的负边距就是margin取负值的情况,如margin:-100px,margin:-100%.当一个元素与另一个元素margin取负值时将拉近距离.常见的功能 ...

  2. CSS3与页面布局学习笔记(一)——概要、选择器、特殊性与刻度单位

    web前端开发者最最注的内容是三个:HTML.CSS与JavaScript,他们分别在不同方面发挥自己的作用,HTML实现页面结构,CSS完成页面的表现与风格,JavaScript实现一些客户端的功能 ...

  3. CSS3与页面布局学习笔记(二)——盒子模型(Box Model)、边距折叠、内联与块标签、CSSReset

    一.盒子模型(Box Model) 盒子模型也有人称为框模型,HTML中的多数元素都会在浏览器中生成一个矩形的区域,每个区域包含四个组成部分,从外向内依次是:外边距(Margin).边框(Border ...

  4. CSS3与页面布局学习笔记(三)——BFC、定位、浮动、7种垂直居中方法

    一.BFC与IFC 1.1.BFC与IFC概要 BFC(Block Formatting Context)即"块级格式化上下文", IFC(Inline Formatting Co ...

  5. CSS3与页面布局学习笔记(六)——CSS3新特性(阴影、动画、渐变、变形( transform)、透明、伪元素等)...

    一.阴影 1.1.文字阴影 text-shadow <length>①: 第1个长度值用来设置对象的阴影水平偏移值.可以为负值 <length>②: 第2个长度值用来设置对象的 ...

  6. CSS3与页面布局学习总结(八)——浏览器兼容与前端性能优化

    一.浏览器兼容 1.1.概要 世界上没有任何一个浏览器是一样的,同样的代码在不一样的浏览器上运行就存在兼容性问题.不同浏览器其内核亦不尽相同,相同内核的版本不同,相同版本的内核浏览器品牌不一样,各种运 ...

  7. CSS3与页面布局学习总结(四)——页面布局大全BFC、定位、浮动、7种垂直居中方法...

    目录 一.BFC与IFC 1.1.BFC与IFC概要 1.2.如何产生BFC 1.3.BFC的作用与特点 二.定位 2.2.relative 2.3.absolute 2.4.fixed 2.5.z- ...

  8. CSS3与页面布局学习总结(五)——Web Font与Sprite

    CSS3与页面布局学习总结(五)--Web Font与Sprite 目录 一.web font 1.1.什么是font-face 1.2.font-face优点 1.3.字体格式 1.4.使用@fon ...

  9. CSS3与页面布局学习总结(二)——Box Model、边距折叠、内联与块标签、CSSReset...

    CSS3与页面布局学习总结(二)--Box Model.边距折叠.内联与块标签.CSSReset 目录 一.盒子模型(Box Model) 1.1.宽度测试 1.2.溢出测试 1.3.box-sizi ...

最新文章

  1. 手动搭建的VGG16网络结构训练数据和使用ResNet50微调(迁移学习)训练数据对比(图像预测+前端页面显示)
  2. Linux操作系统CentOS7.2发行版本的安装与配置
  3. 2021年春季学期-信号与系统-第七次作业参考答案-第九小题
  4. Android中的Android中的Surface和SurfaceView
  5. AjaxControlTookit中的AutoCompleteExtender位置错位问题 ListSearchExtender不支持中文的问题...
  6. 预训练语言模型论文分类整理:综述、基准数据集、PLM的设计和分析
  7. 判断一个字符串是否是回文_Python
  8. 递归法:汉诺塔(快速掌握)
  9. c# 中实用包,实用dll。
  10. java vtd-xml_XML解析技术之VTD-XML 简介及代码实例
  11. ADS史密斯圆阻抗匹配
  12. Kotlin StandardKt
  13. null 和 undefined 的区别
  14. 做跨境人人都是天秤座,三个月都没能建起一个店铺
  15. 解决或者设置网页变灰-CSS-filter属性-哀悼
  16. jsp+ssm计算机毕业设计智能视频推荐网站【附源码】
  17. 前端 点击复制文本 无需插件
  18. 2021-09-10 简单的音乐节奏游戏实现
  19. Python 用print打印五彩斑斓、花里胡哨的文字,让你的print骚起来。
  20. python flask 在线可视化平台系统

热门文章

  1. cm是什么域名_CM域名,什么是CM域名,CM域名注册的优势
  2. JavaScript获取时间戳
  3. 大四学生“毕业焦虑”“迷茫”,想做软件测试岗,要如何系统的学习
  4. 深度解析淘宝直通车和搜索流量的关系,解决新品起爆的痛点和难点
  5. QT6.2.2解决Qxlsx库不能绘制不同列数据的Chart曲线问题
  6. 最新UI界面漫画小程序源码,带后台支持流量主,全自动更新
  7. [原创]java局域网聊天系统
  8. 【SIP基础】SIP协议中网络角色定义
  9. 2022年5月27日记:Linux服务器开发,Darren老师,火焰图的生成原理与构建方式
  10. 电子计算机经历了五代,电子计算机经历了怎样的发展?