http://www.w3cfuns.com/blog-5446761-5400853.html
http://www.w3cfuns.com/blog-5446761-5400857.html
http://www.w3cfuns.com/blog-5446761-5400859.html
原创声明:此笔记被 wuww5511 标注为原创笔记,未经作者同意转载必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
一、减少HTTP请求
为什么要减少http请求?
在一个网页下载的过程中,浏览器会首先下载该页面的html代码,然后再根据获得的html代码去下载其他组件。
这些组件都是通过一个个的http请求来获得的,而http请求应该是前端页面加载过程中花费时间最多的一项。
每一个http请求花费的时间包括:建立连接的时间,发送请求的时间,等待服务器响应的时间,接收数据的时间。
可以看到,每多一个http请求,就会多一部分不必要的开销。
所有作为前端工程师的我们要减少http请求,让每个请求尽可能去传输更多的数据。
怎么减少http请求:
页面上的组件一般包括图片,外部js文件,外部css文件。
1、减少图片的http请求:(css sprite)
这种方法主要适用于网站上有很多小的图标的时候。
每一个图标文件的体积都很小,如果对每个图标都用一个http连接来请求,这个连接在时间的开销上发送请求,接收数据所花的时间几乎可以忽略(文件太小……),主要是建立连接,等待响应的时间。
我们可以将小的图标合并成一个大的图片。在显示时,可以通过将图片设置为背景,通过background-position来定位,获得想要的部分。
2、减少外部js文件,外部css文件的http请求(合并文件再发布):
可以考虑将多个js文件合并在一个js文件里,多个css文件合并成一个css文件。
但是,随着web应用规模的变大,模块化是一种必然的趋势,开发时把所有的内容都写在一个js,css文件里,太不现实了……
所以可以考虑通过一些管理工具,在开发完成后将需要的js模块,css模块合并成一个js文件和css文件,然后发布。
二、利用缓存优化缓存的原理是什么样子的呢?我们需要考虑的有3个地方。
1、客户端浏览器。 2、缓存服务器。 3、网站后台服务器。
当用户提交一个GET请求时:
1,首先接收到这个请求的是缓存服务器。
2,缓存服务器会查看请求的资源,如果该资源已被缓存,那么会根据GET请求的不同,直接返回资源,或者 向网站服务器发出验证报文。
3,如果发出了验证报文,服务器会根据验证报文判断缓存服务器是否可以继续使用已有的资源。
4,如果不能继续使用,则缓存服务器会下载新的资源到缓存中。
5,最后缓存服务器向客户端浏览器返回资源。
客户端浏览器,缓存服务器,网站后台是怎么控制缓存的呢?
当然是通过HTTP报文啦!
浏览器方面:
通过添加Cache-Control报头,告诉缓存服务器是否愿意直接接收缓存里的资源。
放宽对缓存的限制:
Example1: Cache-Control:max-stale=1234 请求的资源在从原始服务器缓存后的1234秒内都可以随便提供给我,不需要向服务验证。
Example2: Cache-Control:max-stale 请求的资无论什么时候都可以随便提供给我,不需要向服务验证。
加强对缓存的限制:
Example1: Cache-Control:max-age=10 请求的资源如果已经缓存了超过10秒了,必须对资源进行再次验证。
Example2: Cache-Control:max-age=0 请求的资源必须进行再次验证。
缓存服务器:
通过 If-Modified-Since,If-None-Match报头,向原始服务器询问,我缓存的数据是否应该更新。 If-Modified-Since:(时间),表示如果在给定时间后服务器更新了资源,就给我来一份吧
If-None-Match:(ETag),ETag是服务器给静态文件配置的唯一 标识符,如果文件被更新,那么ETag就会改变。这个报文的意思是如果找不到相同的ETag,缓存就更新资源。
原始服务器:
Last-Modified:(时间),告诉缓存服务器资源最后更新的时间。缓存根据这个时间发送 If-Modified-Since:(时间)验证资源
ETag:(ETag),告诉缓存服务器资源的ETag,缓存根据这个ETag发送If-None-Match:(ETag)验证资源
Cache-Contro报头告诉缓存服务器资源应该缓存的限制。
Example1:Cache-Control:no-store(告诉缓存服务器,这个资源不能缓存)
Example2:Cache-Control:no-cache(告诉缓存服务器,你可以存这个资源,但是发给客户端的时候要验证下这个资源)
Example3:Cache-Control:max-age=123(告诉缓存服务器,你最多可以缓存这个资源123秒)
注:一般浏览器本身就集成了一个缓存服务器,所以不用担心没有缓存服务器可用。
来看个例子吧。
以百度首页为例。
这是第一次打开页面时对logo图片的请求和应答报文。
在下面的响应报文中,原始服务器给出了上次编辑的时间(Last-Modified),可以缓存的时间(Cache-Control:max-age=),资源的标识符(ETag)。
当我们再次打开这个页面时(不是刷新页面),
浏览器没有对原始服务器发出GET请求,直接从本地缓存中提取需要的资源。
当我们刷新页面的时候(刷新页面会强制本地缓存对缓存的静态文件进行再次验证)。
缓存服务器对资源进行了再次验证。由于资源没有被修改,所以返回了304状态,表示缓存的资源可以继续使用。
对一变化不大的静态文件长时间的缓存,可以有效的提高前端性能。
三、外部CSS文件和JS文件
外部css文件应该放在html的顶部。
为什么呢?
浏览器想要将页面渲染出来,它至少要知道两个数据,html结构和css样式。
html结构在用户打开新页面时,最先下载下来,然后浏览器依次下载剩余的资源。
在css外部文件没有下载完成之前,浏览器无法渲染页面,所以用户在很长一段时间内看到的都是白屏。
做一个实验:
html文档部分:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Test</title> 5 </head> 6 <body> 7 Content 8 </body> 9 <link ref="styleheet" href="data.php?time=10" type="text/css"/> 10 </html>
data.php//根据传递过来的参数,延迟time秒后再响应请求。
1 <?php 2 $time=$_GET['time']; 3 sleep($time); 4 ?>
此时,你打开页面,会看到超过10s的白屏。
这个例子说明,外部css下载完成之前,会阻塞浏览器渲染页面,所以还是把外部css文件放在最前面为好。
补充:
在样式表中,通过@import引用其他的样式表,相对于将引用的样式表放在html文档最底部。所以不建议使用。
外部js文件应该放在html文档底部
为什么呢?
和外部css文件不同,外部js文件会在浏览器渲染的过程中阻塞渲染。
(原因是js程序可能会修改dom,所以会在渲染过程中下载并执行外部js,然后继续渲染)。
实验:
html文档:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Test</title> 5 </head> 6 <body> 7 Content 8 <script src="data.php?time=10"></script> 9 End 10 </body> 11 </html>
此时,你打开该页面,会看到大约在渲染出“Content”10s后,“End”才渲染完成。
该例子表明,外部js会阻塞浏览器渲染的过程,所以应该把外部js放在浏览器的底部。
补充:
还有其他的一些延迟外部js加载的方法:
在script标签中添加defer属性。例如:<script src="test.js" defer="defer"></script>
此时,脚本会在浏览器完成渲染后执行,不会阻塞渲染。
在script标签中添加asnyc属性。例如:<script src="test.js" async="async"></script>
此时,脚本会与浏览器渲染同时执行,不会阻塞渲染。
posted on
浙公网安备 33010602011771号