不管是在工做中,仍是在面试中,web前端性能的优化都是很重要的,那么咱们进行优化须要从哪些方面入手呢?本文将遵循yahoo前端性能团队总结的35条黄金定律。javascript
减小页面的HTTP请求数是个起点,这是提高站点首次访问速度的重要指导原则。css
相关的方案以下:html
合并文件前端
CSS Spritesjava
图像映射。web
能够把多张图片合并成单张图片,总大小是同样的,但减小了请求数并加速了页面加载。图片映射只有在图像在页面中连续的时候才有用,好比导航条。给image map设置坐标的过程既无聊又容易出错,用image map来作导航也不容易,因此不推荐用这种方式。面试
具体用法见 HTML图像映射ajax
行内图片(Base64编码)express
相关方案以下:浏览器
DNS缓存
减小不一样的主机名,从而减小DNS查找
减小不一样主机名的数量同时也减小了页面可以并行下载的组件数量,避免DNS查找削减了响应时间,而减小并行下载数量却增长了响应时间。这是同时减小DNS查找和容许高并发下载的折中方案。
当客户端收到服务器的跳转回复时,客户端再次根据服务器回复中的location指定的地址再次发送请求,例如如下跳转回复。
HTTP/1.1 301 Moved Permanently
Location: http://example.com/newuri
Content-Type: text/html
复制代码
当客户端遇到这种回复的时候,用户只能等待客户端再次发送请求,有的网站甚至会一直跳n次,跳到他想带你去的地方…固然在这个时候用户看不到任何页面内容,只有浏览器的进度条一直在刷新。
重定向会拖慢用户体验,在用户和HTML文档之间插入重定向会延迟页面上的全部东西,页面没法渲染,组件也没法开始下载,直到HTML文档被送达浏览器。因此要避免页面跳转。
Ajax能够帮助咱们异步的下载网页内容,可是有些网页内容即便是异步的,用户仍是在等待它的返回结果,例如ajax的返回是用户联系人的下拉列表。因此咱们仍是要注意尽可能应用如下规则提升ajax的响应速度。
相关方案以下:
Expires
或Cache-Control
报文头使响应能够被客户端缓存这里讨论延迟加载须要咱们知道咱们的网页最初加载须要的最小内容集是什么。剩下的内容就能够推到延迟加载的集合中。
Javascript是典型的能够延迟加载内容。一个比较激进的作法是开发网页时先确保网页在没有Javascript的时候也能够基本工做,而后经过延迟加载脚原本完成一些高级的功能。
与延迟加载目的相反,提早加载的是为了提早加载接下来网页中访问的资源
下面是提早加载的类型:
网页中元素过多对网页的加载和脚本的执行都是沉重的负担,500个元素和5000个元素在加载速度上会有很大差异。
想知道你的网页中有多少元素,经过在浏览器中的一条简单命令就能够算出,
document.getElementsByTagName('*').length
多少算是多了呢?雅虎在写这篇文章的时候号称主页只有700多元素,但如今接近多了一倍。咱们的网页至少别比雅虎还多吧。。。
浏览器通常对同一个域的下载链接数有所限制,按照域名划分下载内容能够浏览器增大并行下载链接,可是注意控制域名使用在2-4个之间,否则dns查询也是个问题。
通常网站规划会将静态资源放在相似于static.example.com,动态内容放在www.example.com上。这样作还有一个好处是能够在静态的域名上避免使用cookie。后面咱们会在cookie的规则中提到。
使用iframe要注意理解iframe的优缺点
优势:
缺点:
404咱们都不陌生,表明服务器没有找到资源,咱们要特别要注意404的状况不要在咱们提供的网页资源上,客户端发送一个请求可是服务器却返回一个无用的结果,时间浪费掉了。
更糟糕的是咱们网页中须要加载一个外部脚本,结果返回一个404,不只阻塞了其余脚本下载,下载回来的内容(404)客户端还会将其当成Javascript去解析。
CSS表达式能够动态的设置CSS属性,在IE5-IE8
中支持,其余浏览器中表达式会被忽略
。例以下面表达式在不一样时间设置不一样的背景颜色。
background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
复制代码
CSS表达式的问题在于它被从新计算的次数远比咱们想象的要多,不只在网页绘制或大小改变时计算,即便咱们滚动屏幕或者移动鼠标的时候也在计算,所以咱们仍是尽可能避免使用它来防止使用不当而形成的性能损耗。
若是想达到相似的效果咱们能够经过简单的脚本作到
var currentTime = new Date().getHours();
if (currentTime%2) {
if (document.body) {
document.body.style.background = "#B8D4FF";
}
}
else {
if (document.body) {
document.body.style.background = "#F08A00";
}
}
复制代码
避免使用@import的缘由很简单,由于它至关于将css放在网页内容底部。
AlphaImageLoad也是IE5.5 - IE8
中支持,这种滤镜的使用会致使图片在下载的时候阻塞网页绘制,另外使用这种滤镜会致使内存使用量的问题。IE9中已经再也不支持。
经样式表(css)放在网页的HEAD中会让网页显得加载速度更快,由于这样作可使浏览器逐步加载已将下载的网页内容。这对内容比较多的网页尤为重要,用户不用一直等待在一个白屏上,而是能够先看已经下载的内容。
若是将样式表放在底部,浏览器会拒绝渲染已经下载的网页,由于大多数浏览器在实现时都努力避免重绘,样式表中的内容是绘制网页的关键信息,没有下载下来以前只好对不起观众了。
重复的脚本不只浪费浏览器的下载时间,并且浪费解析和执行时间。通常用来避免引入重复脚本的作法是使用统一的脚本管理模块,这样不只能够避免重复脚本引入,还能够兼顾脚本依赖管理和版本管理。
经过Javascript访问DOM元素没有咱们想象中快,元素多的网页尤为慢,对于Javascript对DOM的访问咱们要注意应更迅速,应该:
这里说智能的事件处理须要开发者对事件处理有更深刻的了解,经过不一样的方式尽可能少去触发事件,若是必要就尽早的去处理事件。
有时候感受页面反映不够灵敏,是由于有太多频繁执行的事件处理器被添加到了DOM树的不一样元素上,这就是推荐使用事件委托的缘由。若是一个div里面有10个按钮,应该只给div容器添加一个事件处理器,而不是给每一个按钮都添加一个。事件可以冒泡,因此能够捕获事件并得知哪一个按钮是事件源。
HTTP/1.1官方文档建议浏览器每一个主机名下并行下载的文件数不要超过两个,若是图片来自多个主机名,并行下载的数量就能够超过两个。若是脚本正在下载,浏览器就不开始任何其它下载任务,即便是在不一样主机名下的。由于浏览器要在脚本下载以后依次解析和执行。
所以对于脚本提速,咱们能够考虑如下方式,
defer
关键字,能够指定脚本在文档加载后执行。async
关键字,可让脚本异步执行。使用外部Javascript和CSS文件可使这些文件被浏览器缓存,从而在不一样的请求内容之间重用。
同时将Javascript和CSS从inline变为external也减少了网页内容的大小。
使用外部Javascript和CSS文件的决定因素在于这些外部文件的重用率,若是用户在浏览咱们的页面时会访问屡次相同页面或者能够重用脚本的不一样页面,那么外部文件形式能够为你带来很大的好处。
但对于用户一般只会访问一次的页面,例如microsoft.com首页,那inline的javascript和css相对来讲能够提供更高的效率。
精简就是将Javascript或CSS中的空格和注释全去掉,
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
复制代码
精简后版本
body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}
复制代码
统计代表精简后的文件大小平均减小了21%,即便在应用Gzip的文件也会减小5%。
例如个人网站上有5个CSS,4个Javascirpt,下面是分别通过bundling和minify以后的结果。
没有任何处理以前
捆绑Javascript和CSS以后
精简Javascript和CSS以后
当美工完成了网站的图片设计后,咱们能够在上传图片以前对其作如下优化
检查GIF图片中图像颜色的数量是否和调色板规格一致。若是你发现图片中只用到了4种颜色,而在调色板的中显示的256色的颜色槽,那么这张图片就还有压缩的空间。
可使用imagemagick检查:identify -verbose image.gif
尝试把GIF格式转换成PNG格式,看看是否节省空间。大多数状况下是能够压缩的。
能够安全地把GIF格式转换为PNG格式:convert image.gif image.png
在全部的PNG图片上运行pngcrush(或者其它PNG优化工具)。
例如: pngcrush image.png -rem alla -reduce -brute result.png
在全部的JPEG图片上运行jpegtran。这个工具能够对图片中的出现的锯齿等作无损操做,同时它还能够用于优化和清除图片中的注释以及其它无用信息
jpegtran -copy none -optimize -perfect src.jpg dest.jpg
不要经过图片缩放来适应页面,若是你须要小图片,就直接使用小图片吧。
网站图标文件favicon.ico,无论你服务器有仍是没有,浏览器都会去尝试请求这个图标。因此咱们要确保这个图标
Cookie被用来作认证或个性化设置,其信息被包含在http报文头中,对于cookie咱们要注意如下几点,来提升请求的响应速度,
大多数网站的静态资源都不必cookie,咱们能够采用不一样的domain来单独存放这些静态文件,这样作不只能够减小cookie大小从而提升响应速度,还有一个好处是有些代理拒绝缓存带有cookie的内容,若是能将这些静态资源cookie去除,那就能够获得这些代理的缓存支持。
常见的划分域名的方式是将静态文件放在static.example.com,动态内容放在www.example.com。
也有一些网站须要在二级域名上应用cookie,全部的子域都会继承,这种状况下通常会再购买一个专门的域名来存放cookie-free的静态资源。例如Yahoo!的yimg.com,YouTube的ytimg.com等。
这限制是由于iphone,他只能缓存小于25K,注意这是解压后的大小。因此单纯gzip不必定够用,精简文件工具要用上了。
把页面内容打包成复合文本就如同带有多附件的Email,它可以使你在一个HTTP请求中取得多个组件。当你使用这条规则时,首先要肯定用户代理是否支持(iPhone不支持)。
Gzip一般能够减小70%网页内容的大小,包括脚本、样式表、图片等文件。Gzip比deflate更高效,主流服务器都有相应的压缩支持模块。
值得注意的是pdf文件能够从须要被压缩的类型中剔除,由于pdf文件自己已经压缩,gzip对其效果不大,并且会浪费CPU。
空的图片src仍然会使浏览器发送请求到服务器,这样彻底是浪费时间,并且浪费服务器的资源。尤为是你的网站天天被不少人访问的时候,这种空请求形成的伤害不容忽略。
主要以两种形式出现:
straight HTML
<img src=””>
JavaScript
var img = new Image();
img.src = “”;
复制代码
虽然标题叫配制ETags,可是这里你要根据具体状况进行一些判断。首先Etag简单来讲是经过一个文件版本标识使得服务器能够轻松判断该请求的内容是否有所更新,若是没有就回复304 (not modified),从而避免下载整个文件。
可是Etags的版本信息即便主流服务器也未能很好地支持跨服务器的判断,好比你从一个服务器集群中一台获得Etags,而后发送到了另外一台那么校验颇有可能会失败。
浏览器在实现XMLHttpRequest POST的时候分红两步,先发header,而后发送数据。而GET却能够用一个TCP报文完成请求。另外GET从语义上来说是去服务器取数据,而POST则是向服务器发送数据,因此咱们使用Ajax请求数据的时候尽可能经过GET来完成。
网页后台程序中咱们知道有个方法叫Response.Flush()
,通常咱们调用它都是在程序末尾,但注意这个方法能够被调用屡次。目的是能够将现有的缓存中的回复内容先发给客户端,让客户端“有活干”。
那在何时调用这个方法比较好呢?通常状况下咱们能够在对于须要加载比较多外部脚本或者样式表时能够提早调用一次,客户端收到了关于脚本或其余外部资源的连接能够并行的先发请求去下载,服务器接下来把后续的处理结果发给客户端。
再次强调第一条黄金定律,减小网页内容的下载时间。提升下载速度还能够经过CDN(内容分发网络)来提高。CDN经过部署在不一样地区的服务器来提升客户的下载速度。若是你的网站上有大量的静态内容,世界各地的用户都在访问,那CDN是必不可少的。事实上大多数互联网中的巨头们都有本身的CDN。咱们本身的网站能够先经过免费的CDN供应商来分发网页资源。
这条规则分为两个方面: