1 优化css
1.1 避免使用CSS表达式
用CSS表达式动态设置CSS属性,是一种强大又危险的方式。从IE5开始支持,但从IE8起就不推荐使用了。例如,可以用CSS表达式把背景颜色设置成按小时交替的
- 尽量减少标签选择器的使用
- 尽可能少使用id选择器,多使用样式选择器(通用性强)
- 减少选择器前缀,例如.headerBox .nav .left a{} 选择器是从右向左查询的
- 避免使用css表达式
background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
复制代码
1.2 减少页面中的冗余代码
尽可能提高方法的重复使用率:“低耦合高内聚”
1.3 选择舍弃@import
前面提到了一个最佳实践:为了实现逐步渲染,CSS应该放在顶部。 在IE中用
@import
与在底部用效果一样,所以最好不要用它。
1.4 避免使用滤镜
IE专有的AlphaImageLoader
滤镜可以用来修复IE7之前的版本中半透明PNG图片的问题。在图片加载过程中,这个滤镜会阻塞渲染,卡住浏览器,还会增加内存消耗而且是被应用到每个元素的,而不是每个图片,所以会存在一大堆问题。
最好的方法是干脆不要用AlphaImageLoader
,而优雅地降级到用在IE中支持性很好的PNG8图片来代替。如果非要用AlphaImageLoader
,应该用下划线hack:_filter
来避免影响IE7及更高版本的用户。
1.5 把样式表放在顶部
把样式表放到文档的HEAD部分能让页面看起来加载地更快。这是因为把样式表放在head里能让页面逐步渲染。
关注性能的前端工程师想让页面逐步渲染。也就是说,我们想让浏览器尽快显示已有内容,这在页面上有一大堆内容或者用户网速很慢时显得尤为重要。给用户显示反馈(比如进度指标)的重要性已经被广泛研究过,并且被记录下来了。在我们的例子中,HTML页面就是进度指标!当浏览器逐渐加载页面头部,导航条,顶部logo等等内容的时候,这些都被正在等待页面加载的用户当作反馈,能够提高整体用户体验。
1.6 压缩 css
- 使用在线网站进行压缩
- 使用html-minifier 对html 中的css 进行压缩
- 使用clean-css 对css进行压缩
- webpack,gulp打包工具
2 优化图片
2.1 图片格式
尝试把GIF格式转换成PNG格式,看看是否节省空间。在所有的PNG图片上运行pngcrush(或者其它PNG优化工具)
2.2 优化CSS Sprite
采用css雪碧图(css sprit/css 图片精灵)技术,吧一些小图合并在一张大图上面,使用的时候,通过北京图片定位,定位到具体的某一张小图上
- 在Sprite图片中横向排列一般都比纵向排列的最终文件小
- 组合Sprite图片中的相似颜色可以保持低色数,最理想的是256色以下PNG8格式
- “对移动端友好”,不要在Sprite图片中留下太大的空隙。虽然不会在很大程度上影响图片文件的大小,但这样做可以节省用户代理把图片解压成像素映射时消耗的内存。100×100的图片是1万个像素,而1000×1000的图片就是100万个像素了。
.pubBg{
background:url('../img/sprit.png') no-repeat;
background-size:x y; // 和原图的大小保持一致
}
.box{
background-position:x y; // 通过背景定位,定位到具体的位置,展示不同的图片极客
}
复制代码
页面中没法送一次http请求,都需要完成请求+响应这个完整的http事务,会消耗一些时间,也可能会导致http链接通道的堵塞,为了提高页面的加载速度和运行的性能,我们应该减少http的请求次数和减少请求内容的大小。
2.3 图像映射
可以把多张图片合并成单张图片,总大小是一样的,但减少了请求数并加速了页面加载。图片映射只有在图像在页面中连续的时候才有用,比如导航条。给image map设置坐标的过程既无聊又容易出错,用image map来做导航也不容易,所以不推荐用这种方式。
2.4 行内图片(Base64编码)
用data: URL模式来把图片嵌入页面。这样会增加HTML文件的大小,把行内图片放在(缓存的)样式表中是个好办法,而且成功避免了页面变“重”。但目前主流浏览器并不能很好地支持行内图片。
减少页面的HTTP请求数是个起点,这是提升站点首次访问速度的重要指导原则。
2.5 不要用HTML缩放图片
不要因为在HTML中可以设置宽高而使用本不需要的大图。如果需要
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />
复制代码
那么图片本身(mycat.jpg)应该是100x100px的,而不是去缩小500x500px的图片。
2.6 用小的可缓存的favicon.ico(P.S. 收藏夹图标)
favicon.ico是放在服务器根目录的图片,它会带来一堆麻烦,因为即便你不管它,浏览器也会自动请求它,所以最好不要给一个404 Not Found响应。而且只要在同一个服务器上,每次请求它时都会发送cookie,此外这个图片还会干扰下载顺序,例如在IE中,当你在onload中请求额外组件时,将会先下载favicon。
所以为了缓解favicon.ico的缺点,应该确保:
- 足够小,最好在1K以下
- 设置合适的有效期HTTP头(以后如果想换的话就不能重命名了),把有效期设置为几个月后一般比较安全,可以通过检查当前favicon.ico的最后修改日期来确保变更能让浏览器知道。
2.7 压缩image
- 使用雪花图
- 使用雪花图 www.spritecow.com/
- 使用雪花图 www.spritecow.com/
- 使用矢量图
- 使用矢量图字体 fontawesome.dashgame.com/
- 使用阿里矢量图库 www.iconfont.cn/
- 使用矢量图转成字体 icomoon.io/
- 使用矢量图字体 fontawesome.dashgame.com/
- 使用base64转换
- 使用网站压缩
- 使用无损压缩 tinypng.com/
- png转换webp zhitu.isux.us/
- 使用无损压缩 tinypng.com/
- 合理使用格式图片
- jpg有损压缩,压缩率搞,不支持透明
- png支持透明,浏览器兼容好
- webp压缩程度更好,在ios webview有兼容性问题
- svg矢量图,代码内嵌,相对于较小,图片样式相对简单的场景
- jpg有损压缩,压缩率搞,不支持透明
在使用webp的过程中,会产生一些浏览器兼容问题
function checkWebp() {
try{
return (document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0);
}catch(err) {
return false;
}
}
$(document).ready(function() {
var webp_good = checkWebp();
if(webp_good == false) {
$('img').each(function() {
var src = $(this).attr('src');
if(typeof src != 'undefined') {
src = src.replace('/format,webp', '/format,jpg'); //将webp格式转换成jpg格式
$(this).attr('src', src);
}
var original = $(this).attr('original'); //针对用了懒加载的情况
if(typeof original != 'undefined') {
original = original.replace('/format,webp', '/format,jpg'); //将webp格式转换成jpg格式
$(this).attr('original', original);
}
})
}
})
复制代码
2.8 图片懒加载
采用图片懒加载技术,在页面开始加载时候,不请求真实的图片地址,而是默认图占位,当页面加载完成后,在根据相关的条件依次加载真实的图片(减少页面首次加载http请求的次数)
真实项目中,我们开始图片都不加载,页面首次加载完成,先把第一屏幕中看见的图片进行加载,随着页面的滚动,在下面区域中能够呈现出来的图片进行加载
- 根据图片懒加载技术,我们还可以扩充出,数据懒加载
开始加载页面的时候,我们只把首屏或者前两屏的数据从服务器进行请求(有些网站首屏数据是后台渲染好,整体返回给客户端呈现的)
- 当页面下拉,滚动到哪个区域,在把这个区域需要的数据进行请求(请求回来数据绑定以及图片延迟加载等)
- 分页展示技术采用的也是数据懒加载思想实现的:如果我们开始请求获取的数据是很多的数据,我们最好分批请求,开始只请求第一页的数据,当页面点击第二页(微博是下拉到一定距离后,再请求第二页数据)的时候请求第二页数据。
3 优化js
3.1 去除重复脚本
页面含有重复的脚本文件会影响性能,这可能和你想象的不一样。在对美国前10大web站点的评审中,发现只有2个站点含有重复脚本。两个主要原因增加了在单一页面中出现重复脚本的几率:团队大小和脚本数量。在这种情况下,重复脚本会创建不必要的HTTP请求,执行无用的JavaScript代码,而影响页面性能。
IE会产生不必要的HTTP请求,而Firefox不会。在IE中,如果一个不可缓存的外部脚本被页面引入了两次,它会在页面加载时产生两个HTTP请求。即使脚本是可缓存的,在用户重新加载页面时也会产生额外的HTTP请求。
除了产生没有意义的HTTP请求之外,多次对脚本求值也会浪费时间。因为无论脚本是否可缓存,在Firefox和IE中都会执行冗余的JavaScript代码。
避免不小心把相同脚本引入两次的一种方法就是在模版系统中实现脚本管理模块。典型的脚本引入方法就是在HTML页面中用SCRIPT标签: