web页面性能优化总结及原理解释

391 阅读9分钟

面试必问之-页面性能优化
参考原文地址

我们面试的时候很多的问题,其中问的频率比较高的一个就是页面怎么进行性能优化, 我们一般直接回答很多条,然后导致一个问题就是很多的面试官还会继续问,说具体怎么实现你说的这些方法,下面我们就简单的说几个典型的。记住页面性能优化的终极目的还是提高用户体验,所以一定意义上说提高用户体验也是页面性能优化的一部分。

性能优化

减少http的请求数

这个是我们最习惯的回答,但是其实很多面试官会接着问,怎么减少呢?这个时候很多人就晕了,其实也不难,从两个方面减少,分别从业务和静态资源上,业务上,我们尽量将复杂的业务可以合并的就合并到一个接口里面,数据量不大的情况下,数据量大的情况下做好相应的分页处理操作,尽量不要因为合并了接口导致数据量过大出现的接口超时,第二从静态资源上,其实请求后端接口一般真花费不了太多的时间,很大一部分的时间都是用到了图片、样式、脚本等上面了,但是呢减少静态资源的请求是不现实的,所以我们可以做的就是服务器端(cdn)合并,基于NODEjs的文件合并工具,通过将很多资源放到一个文件中的处理方式进而减少http请求,优化到极致就是一个页面最好只有一个css和js文件的请求。第二个处理静态资源的方式,将背景图片合并成一个文件,使用css Sprite通过 background-image 和 background-position 控制显示。

使用cdn加速

这个没办法举例子,但是可以说一下为什么cdn加速可以优化页面的性能,由于我们页面很大的时间都是在加载资源,所以说减少资源下载的时间是很重要的,cdn其实就是内部分发网络,他是一组分布在不同地理位置的web服务器,用来给用户提供发送高性能的内容,所以我们在选择的时候可以选择相应最快的来使用。

将css放到页面的顶部

这个就比较有意思了,有的人说这个就是扯啊,其实不是,我们页面性能优化的目的是什么,是为了给用户更好的体验,那我们页面是被逐步渲染的,所以我们希望页面可以尽可能的加载多的文件,也就是说,当浏览器逐步加载页面的头部,导航条,logo等其实这些都是给用户视觉上的反馈,说人话就是看起来页面是快了一点,如果对手机感兴趣的人应该知道,苹果手机反应是很快的,那其实在苹果4S的时候,工程师为了让4S看起来更流畅,我们开锁的那一瞬间是一张图片而已,一张过度的图片,为了给用户以视觉上的过度,会让用户觉得这反应也太快了吧,其实原理是一样的。

看情况决定使用内联样式还是外部js或者css

这个好像一直以来我们认知里面的优化方案是尽可能的使用内部样式,这样可以提高加载的速度,是的,但是这个要有一个前提条件,那就是外部文件占html文档数的比重,如果说网站用户在每次会话中进行多次页面访问,同事页面重用了多个脚本和样式表,使用外部文件是一个比较好的选择,如果一个网站主页,因为主页对于响应时间的要求比较高,因此更加倾向内联样式,有人会问,为什么使用外部的会快呢?这个问题问得好,因为外部的js和css有机会被浏览器缓存起来,对于内联的情况,由于html文档通常不会配置为可以缓存,所以每次请求html都会重新进行下载。由于缓存之后的文件是不会进行http请求的, 进而减少了http请求,加速了页面渲染。

减少DNS查询

我们一般输入了url以后呢,浏览器第一步要做的事情就是查询域名对应的ip地址,这个过程就是DNS的解析过程,那说人话就是如果让你记住[http://182.61.200.7/]就是百度的首页地址,你记得住吗?所以就有了让你记住域名,www.baidu.com,然后浏览器帮你寻找对应的ip地址,这个过程就是DNS的解析过程,为什么要减少DNS的查询呢?因为我们在DNS查询的过程是不会下载任何资源的,但是这个查询的过程是消耗时间的,虽然很少,一般是20MS左右,但是由于性能的考虑,一般的操作系统也好,浏览器也好,都会有自己的DNS缓存,一般是一分钟,IE的是30分钟,豪横,但是这个是可以自行配置的,这里可能还有人不知道怎么减少的,只是知道了为什么减少,减少的办法就是域名尽量使用同一个,由于缓存,同一个是不会进行二次查询的,不过这里需要一个点要注意,我们减少不同的域名虽然减少了DNS的查询,同时也减少了页面下载资源的并发量,也就是说,避免DNS查询优化了时间,减少并行下载量增加了响应时间,所以我们的原则是将不同的文件分发到2-4个域名上,选择一个折中的方案出来。

压缩js和css

压缩我们都明白,原理也很清楚,就是减少不必要的注释和空格,将文件的大小尽量控制的比较小,下载的速度就快进而达到提高性能的目的,js常见的压缩工具JSMin和YUI Compressor,另一种方式叫做混淆,这也是一种压缩方式,而且比压缩更加的彻底,但是混淆的过程很容易出现bug,其实我们的vue框架打包以后就是对js和css进行了混淆的操作,进而缩小vandorjs的大小,提高速度,这个是webpack打包工具的功能,除了压缩外部的js和css之外呢,我们也可以使用Gzip模块,对行内和块进行压缩,也是一种方案。

尽量减少301/302的重定向

重定向本身是不会消耗很多的时间,为什么这个列入到了性能优化里面了呢?原因和将css放到头部文件是一个道理,因为一般重定向的时候只有请求头,没有请求体,导致的一个效果就是会看到浏览器进度条在走动, 但是页面是空白的,这个用户体验是很差的,如果做了权限分配,使用重定向是开发成本最低的一种方案,但是要明白这个是拿用户体验换来的,当然你可以做一个伪静态的过度页面也未尝不了,不理解的话,移步到“将css放到页面的顶部”这一段苹果4S的过度原理

设置ETags进行控制缓存

首先说一下什么是ETags(Entity tags)实体标记, 页面中的实体其实就是静态资源,图片,脚本,样式等,ETags是比验证last modified日期更加高效的一种机制,服务器设置的时候:

HTTP/1.1 200 OK
Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
ETag: "10c24bc-4ab-457e1c1f"
Content-Length: 12195

之后如果浏览器要验证文件,用if-none-Match头部来传ETag给服务器,如果tag匹配,服务器返回304(文件未发生变化),从而不进行下载文件,进而达到减少资源请求的一个目的

GET /i/yahoo.gif HTTP/1.1
Host: us.yimg.com
If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT
If-None-Match: "10c24bc-4ab-457e1c1f"
HTTP/1.1 304 Not Modified

其实这个问题在于用什么来tag标记这个实体,一般都是使用文件的某些属性进行构造,而这些属性对于特定的网站服务类是唯一的。

避免使用iframe

使用iframe可以将一个html插入到父文档中,我们列举一下他的优缺点:
优点:可以用来加载速度较慢的第三方资源,广告等,用作安全沙箱,并行下载脚本
缺点:加载代价昂贵,即使页面什么都没有,iframe完全加载以后才会触发load时间,Safri,Chrome中可以通过js动态设置iframe src属性进而避免这个问题,缺乏语义

避免404

我们知道优化页面性能的主要方案之一就是减少http请求,如果发出去的http请求没有返回任何东西,直接404页面不存在的话,会大大的降低用户体验,比较好的解决方案是404的替代页面,但是我们还是希望尽可能的避免404的出现

优化Cookie

Cookie一般我们用来身份认证,个性化设置等用途,Cookie通过HTTP头在服务器和浏览器之间进行传递,所以减少Cookie的大小也可以提高响应速度,优化方案有减少不必要的Cookie,尽量的压缩Cookie的大小,设置合适的过期时间

减少DOM操作

缓存已经访问过的元素、使用className来操作元素的样式、避免使用js修复布局

不要在 HTML 中缩放图片

尽量使用大小适合的图片,比如需要一个100100的,不要使用 500500的然后设置宽和高进行缩小,最后即使使用了100*100的,也要设置宽和高避免浏览器自己猜造成的重绘

避免图片的src属性为空

这个原因很简单,src虽然为空,但是浏览器还是会发送一个http的请求,造成意外的流量负担,完全没有必要,浪费服务器的资源,还有可能产生错误。