1、提升网页加载速度的必要性javascript
国际知名的一组来自Jupiter Research的数据显示:购物者在访问网站过程当中的不满会致使销售损失和品牌受损,其中 77%的人将再也不访问网站 ,62%的人再也不从该网站上购买,48%会转向竞争对手,28%的人对公司产生负面印象。css
此组数据分析显示:Google网站访问速度每慢400 ms就将致使用户搜索请求降低 0.59%;Amazon表示,增长 100ms的网站延迟将致使其收入降低 1%;雅虎网站若是有400ms 延迟会致使流量降低 5-9%…html
大数据分析代表:当网站首页打开时间超过4秒时,约60%的用户会放弃继续访问浏览,83%的用户但愿首页打开时间不要超过4秒。前端
据调查发现,影响用户体验的因素有不少,如购物方便性、网站合理布局等,但最重要的是网站性能和网站可用性能,这两项对用户的影响占到了69%。java
结语:网站网页加载速度越慢,用户体验度就越低,将致使网站拥有者的收益大幅减小。所以,提升网页加载速度就成了前端工程师的必修课之一。jquery
2、前端性能优化angularjs
网页加载顺序:1.DNS查找 > 2.下载并渲染HTML文件 > 3.下载并执行css及js组件 > 4.下载图片web
如下性能优化列表,按照对网页加载速度的提高幅度排序ajax
1. 减小DNS查找express
DNS查找,即浏览器根据url中域名,查找该域名对应的服务器IP地址,而后才能根据服务器IP地址,下载到文件。在DNS查找完成以前,全部的文件下载都没法执行。每一次DNS查找时间约20-120ms。
通常而言,电脑会进行DNS缓存,包括浏览器缓存、系统缓存、路由器缓存、ISP DNS缓存。因此,浏览器DNS查找顺序通常是这样的:浏览器缓存→系统缓存→路由器缓存→ISP DNS 缓存→递归搜索。
递归搜索,即ISP的DNS服务器从根域名开始进行递归查询,查找时间通常为20-120ms。
若没有DNS缓存,才会执行DNS递归搜索。可是显而易见,第一次访问网站首页时,是不会有DNS缓存的,必然会执行DNS查找。而每个DNS查找,须要耗时20-120ms。所以,减小DNS查找能加快网页加载速度。
实例:
在开发页面时,不少时候,咱们都要用到别人已经封装好了的js及css文件,譬如jquery库、angularjs库、时间选择插件、定位插件等等诸多插件,通常而言,网上都有公用的CDN,咱们不须要将这些文件下载到本地,就可使用它们。
譬如:w3c上推荐了谷歌的CDN,腾讯地图也有本身的CDN库,咱们能够经过如下代码,获取到谷歌的jquery库,以及腾讯的前端定位插件。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script><!-- 引用谷歌jQuery库 --> <script type="text/javascript" src="https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script><!-- 引用腾讯前端定位插件 -->
这样写作起来十分方便,咱们能够省去下载文件这一步骤。但实际上,这样作会增长两个DNS查找,即"ajax.googleapis.com"和"3gimg.qq.com"的DNS查找,将会在首次加载网站首页时,拖慢首页加载速度40-240ms,并且每再增长一个DNS查找,还会额外拖慢20-120ms的加载时间,这是极为致命的。
不只如此,这两个文件的下载速度分别取决于谷歌服务器及腾讯服务器的下载速度,这是彻底不可控的。而将本身网站所须要的文件,寄放在别人的服务器上,也是不安全的。例如,某一天谷歌的服务器抽风,没法再下载文件,或是谷歌再也不支持该jquery库,那么咱们的网站将会失去jquery核心库,会直接崩溃。更可怕的是,若谷歌在该jquery库文件中添加某些攻击性手段,将会直接致使网站处于危险状态中。
所以,为了减小DNS查找,为了保障网站的安全,咱们必须将网站所需的文件下载到本地,而不是调用别人支持的CDN。
2. CSS优先加载,JS延迟加载
在解析HTML文件,构建DOM树时,一旦遇到link标记时,即遇到了CSS样式表,将之下载,即可当即构建渲染树,从而当即呈现页面效果。
而一旦遇到script 标记时,即遇到了JS脚本,将当即阻塞DOM树的构建,将控制权移交给 JavaScript 引擎,等到 JavaScript 引擎运行完毕,浏览器才会从中断的地方恢复渲染树的构建。这涉及到浏览器渲染原理,详情请见本人上一篇博客:浏览器渲染页面的原理及流程
若将引入JS脚本的连接放到HTML页面顶部,那么在加载该页面时,一旦遇到JS,页面渲染就会停滞,出现一段时间的灰色空白,直到JS加载完成,才会出现页面内容,这对用户体验是不友好的。所以,咱们须要将JS脚本放置到页面底部,或者让JS脚本异步或是延迟加载。
实例:以下图所示,该首页有CSS样式表一个,若将CSS样式表置于JS脚本之下,那么在加载完JS脚本以前,页面都不会进行渲染,会出现108ms的灰色空白。该首页有JS脚本文件5个,若将这5个JS文件放置在该首页的顶部,那么该首页加载JS脚本时,也将会出现108ms的灰色空白。
从严格意义上来讲,CSS的优先加载及JS的延迟加载并不能从根本上提高网页加载速度,可是它们能使网页更快被渲染出来,使页面内容逐步呈现,增长用户等待的耐心,提高用户体验。
3. 减小HTTP请求
HTTP请求,即客户端到服务器端的请求消息,包括资源请求、数据处理等。
HTTP请求需从客户端发起请求,而后由服务器端进行数据处理,而后再返回数据或资源。通常而言,耗时据请求资源的大小,服务器网速,约数ms-数百ms之间。请求资源越大,所花费的时间越长,服务器网速越慢,所花费的时间也越长。
通常而言,完成了DNS查找后,接下来即是进行HTTP请求,获取资源。首先下载HTML文件,而后解析HTML文件,根据HTML内容,获取CSS、JS及图片文件。每个CSS连接、JS连接以及图片连接都是一个HTTP请求。
每个HTTP请求都须要花费额外的时间。所以,咱们能够将一些可合并的资源进行合并,譬如将全部页面的css合并成一个style.css文件,譬如将全部页面的js合并成一个function.js文件,再譬如将一批小图标利用ps合成一张图片(此手段效果最显著,也最经常使用)。虽然有时文件会变大,可是在HTTP请求中,请求下载一个大小为100KB的资源文件,比请求下载两个大小为50KB的资源文件要快。
从实际测试来看,每减小一个HTTP请求,据请求资源大小,能加快网页加载速度约数ms-数百ms。
实例:合并图标
"用户信息页面"以下图所示:四个输入框左侧,有四张icon,合计大小8.9KB,四个HTTP请求合计时间23ms。
我利用ps,将此四张图片进行合并,而后以css的背景图片进行引用,其结果以下图所示:四个输入框左侧,四张icon合并后的大小6.0KB,一个HTTP请求时间8ms。减少图片大小2.9KB,提高加载速度15ms。看起来提高速度很少,但按比例算,提高幅度巨大。
4. 缩小文件
众所周知,HTTP请求中,返回的资源越大,HTTP请求所花费的时间越长,所以,缩小资源文件能够提高HTTP请求的速度,进而提高页面加载速度。不只如此,还能节省服务器流量及空间。
通常而言,缩小文件主要是指图片压缩,也包括CSS、JS文件压缩,网上有成熟的代码在线压缩工具,譬如:在线JS/CSS/HTML 压缩
而图片压缩主要是指图片在不一样的格式下、不一样的分辨率下保存,其大小将会有巨大的差别。譬如同一张图片的png格式与jpg格式肉眼看起来几乎没有区别,可是其大小相差了约5倍。而jpg格式中级也比高级要小约莫1倍。固然,图片的不一样格式有不一样的用处,且分辨率越高,图片也越清晰。
所以,根据需求为图片选择合适的格式及分辨率,就能获得最小的图片文件。
具体操做:在ps中打开图片,同时按下ctrl+alt+shift+s,打开"存储为web所用格式"弹框,便可任意选择保存图片的格式及分辨率(若按操做没法顺利压缩图片,请自行度娘)。
实例:同一张图片,jpg格式比png格式小约5倍,加载速度快约3倍。
缩小文件来提高页面加载速度,从我我的的项目优化经验来看,其效果极为显著,多个项目都提高了超过100ms的加载时间。
5. 善于利用缓存
避免在HTML文件中使用style标签插入CSS样式,及使用script标签插入JS脚本。若在HTML文件中插入CSS及JS,那么它们没法进入缓存,每次刷新页面,都要从新加载,不但浪费了浏览器资源,拖慢了页面加载速度,并且显得冗余且复用性低,不利于往后的维护。所以,将CSS样式与JS脚本分离出来,造成CSS文件及JS文件,就能进入缓存,进而提升页面加载速度。
灵活使用cookie和localstorage。在使用接口时,灵活使用cookie和localstorage来缓存接口返回的信息,避免没必要要的接口查询,从而提高页面加载速度。譬如:在登陆页面登陆时,缓存好用户信息,设置过时时间。在进入用户我的中心页面时,若数据并未过时,能够直接从缓存中取用户信息,没必要再调起接口去获取用户信息。
实例:css、js、图片均可进行缓存,从缓存中获取文件,时间为0ms。
总结:以上几点,对于页面加载速度的提高效果都很显著,只要作到以上几点,只要服务器不坑,项目页面加载速度都不会很慢。如下我将会从代码的角度来提出几点项目优化的经验。
6. HTML文件代码优化
1. 避免使用空请求,包括空的href连接、空src连接。空连接自己没法请求成功,所以会把一个HTTP请求拖到超时,并且空连接会阻塞页面中其余资源的下载进程,会拖慢页面加载速度。譬如:<img src="" alt="">。
2. 根据项目大小,选择主要使用class仍是id。id选择器优先级最高,访问速度最快。可是在html中每声明一个id,就会在JS底层声明一个全局变量,而全局变量的增多,将会拖慢JS中变量遍历的效率,若变量遍历达到十万次以上,就会出现较显著的延迟,并且容易形成全局变量污染。对于小项目,并没有影响,可是对中大型项目来讲,尤为是游戏项目,影响很大。我的推荐,当项目较小时,灵活使用class和id,当项目较大时,尽可能少使用id。
3. 预先设定图片大小。在页面加载过程当中,图片最后加载,若不对图片预设大小,当图片加载完成后,将会引发大量的重排,将会浪费浏览器资源及拖慢页面加载速度。
4. 尽可能减小DOM元素的数量与层级。解析HTML时,标签的数量越多,标签的层级越深,浏览器解析构建DOM树的时间就越长,应尽量的减小DOM元素的数量和层级。
5. 尽可能避免使用table标签。浏览器对table标签的解析是所有生成后再一次性绘制的,所以会形成表格位置较长时间的空白,推荐使用ul及li标签绘制表格。
6. 使用异步加载iframe标签。浏览器加载iframe标签时,会阻塞父页面渲染树的构建及HTTP请求,所以尽可能使用异步加载iframe。
等等…
7. CSS样式代码优化
1. 禁止使用样式表达式。CSS表达式从IE5起开始支持,但仅有IE支持。它的解析速度较慢,并且运算次数远比咱们想象的要大,随意动动鼠标就能轻松达到上万次运算,会对页面性能形成影响。譬如:"#myDiv{width:expression(document.body.offsetWidth - 110 + "px"); }"
2. 优化关键选择器,去掉无效的父级选择器,尽可能少在选择器末尾使用通配符。大多数人都认为,浏览器对CSS选择器的解析式从左往右进行的,譬如选择器:"#myDiv ul li a",大多数人会认为这个选择器效率极高,毕竟第一个ID #myDiv 就已经把范围限定了,先选择 #myDiv ,再在 #myDiv 下寻找 ul ,再一级一级往下,直到找到 a 标签,效率很高。事实上这是错的,浏览器对CSS选择器的解析式从右往左进行的。在上述选择器中,浏览器会先去寻找 a 标签,范围为全局,再在 a 标签的列表中,寻找父级标签是 li 标签的 a 标签,一直向上,直到最后,找到父级标签是 #myDiv ul li 的a标签。所以,效率并不像想象中那么高。显而易见,"#myDi a"选择器比"#myDiv ul li a"选择器效率要高得多。而通配符 a 的效率远比类选择器及id选择器低,若给 a 标签添加一个class myA ,构造新选择器:"#myDiv .myA",它的效率又远比"#myDi a"要高了。浏览器对CSS选择器的解析式从右往左进行,所以在选择器末尾最好使用类选择器,而不是通配符。CSS选择器效率问题详情请见:CSS选择器效率问题
等等…
8. JS代码优化
1. ajax请求方法按需求选择get或是post,访问接口所花费的时间在页面加载时间中占很大的比重,而接口访问方法中,get方法远比post方法要快,所以按需选择接口访问方法很重要。
2. 减小全局变量,尽可能使用局部变量。js中,全局变量运算速率远低于局部变量,速度差别达到上百倍,且全局变量越多,全局变量的查找速率便越慢。详情请见:减小全局变量对效率的提高
3. 减小对DOM的操做。js操做DOM将会引发页面的重绘及重排,须要花费时间及耗费浏览器资源。
等等…
结语:前端性能优化是一门完整的学问,并不是一两篇博客所能详尽的。以上我只是按照页面加载速度的提高幅度写了几点,其实还有大量优化手段,难以详尽。譬如:图片懒加载、按需加载、预加载等等,再譬如:从网络加载角度进行优化、从渲染角度进行优化、从架构协议角度进行优化等等
学无止境,诸君共勉!