有什么技术,是运用了空间换时间的思想?看了这么久文章,如果你记忆力不错的话,应该很容易想到「缓存」。空间换时间这个词最早的意思,就是用来描述缓存的。当然,缓存是一个很大的话题。比如说 CPU 嫌内存速度太慢,就自己带了一个存储器,用来缓存最近使用的命令,这就是 CPU 的高速缓存。再比如,操作系统嫌每次从硬盘里读取代码来运行速度太慢,就在一开始打开一个程序的时候,把它读到内存里做一个缓存,这就是为什么你打开游戏的时候,一般都有个 loading。
今天咱们顺着这个思路,来看一下浏览器是如何利用缓存来加快网页的打开速度的。如果按照上面的句型造句的话,这里应该是「浏览器嫌每次从网上下载一个网页太慢,就在硬盘上找了个地方,专门缓存已经浏览过的东西,这就是浏览器的缓存」。很简单的道理。跟硬盘相比,网络的速度还是差了一大截,而且还不稳定,随时都有可能连不上网,直接读硬盘上缓存的网页比去网上现下载要快的多。我这里说它缓存「浏览过的东西」,而不仅仅是我们看到的html页面,其实是因为在浏览器看来,服务器上的一切都是资源,每个资源都有自己的url地址,有时候网页里的图片、视频,比 html 页面本身大的多,因此更需要缓存起来。
举个简单的例子。当你在浏览器里打开 www.google.com 的时候,它会先去 google 的服务器上下载 google 的 html 网页。html 网页里,还会引导浏览器去下载其他的各种资源,比如 google 著名的涂鸦,还有 js 脚本之类的东西。下面这张图,红框框出来的一大坨,就是打开 google 的时候,浏览器下载的所有东西。理论上来讲,这些东西都广告是可以分别缓存起来到硬盘上的。
为什么说理论上呢?因为缓存这东西,有个天敌,叫做缓存失效。也很好理解,今天 google 首页上的图是一个小苹果在蹦床,改天奥运会结束了,又变回 google 的 logo 了。如果浏览器一直用缓存的图的话,用户看到的就一直是这个小苹果,肯定是不合理的。其他资源也是如此,缓存虽然加快了用户看到网页的速度,但是一旦缓存失效,又没有及时处理,会引发严重的 bug。
当然,缓存失效不失效,浏览器说了不算,归根到底还是由服务器来决定。服务器上有了新的东西,缓存自然而然就失效了,但是浏览器如何知道呢?其实也很简单,我来描述一下整个流程。第一次的时候,你访问 google.com,浏览器从服务器上下载了某个资源,服务器顺带把这个资源的「最后修改时间」也传给了浏览器。浏览器则把这个资源和它的「最后修改时间」一起缓存到硬盘上。第二次你又上 google,需要下载同一个资源的时候(因为是同一个 url),浏览器就带着这个资源的「最后修改时间」去问服务器,说我硬盘上缓存的这个资源啊,你看到底还能不能用。服务器一比对,假如服务器上的这个资源,最后修改时间比浏览器带来的要晚,那就说明资源后来被人更新过,浏览器上的缓存已经失效了,必须重新下载。反之呢,资源没有被更新,缓存有效,那就给浏览器回个暗号(一般是回个 304 响应码),说缓存有用,你就不用费事从我这儿下载啦。
当然了,每次去问服务器资源有没有过期,还是一件挺麻烦的事情。还有一招,就是服务器在一开始的时候,可以定一个资源的「保质期」。有些资源,其实不怎么变的,那服务器就告诉浏览器,这个资源的保质期是 72 小时,72 小时之内的下载请求,就不要来问我了,你就默认用缓存吧。72 小时之后,它就有失效的风险,但是到底失效没失效,还是由服务器根据「最后修改时间」来做决定,就要重新走一遍上面的流程。
这就跟你看美剧一样的道理。某美剧下载网站的服务器上有《冰与火之歌》第六季供人下载,是一个文件夹,HBO 每更新一集,管理员就往文件夹里放一集。现在你下载了这个文件夹,相当于你电脑上已经缓存了服务器的资源。这剧一般来说一周更新一集,那服务器就可以设置一周为保质期。换句话说,你今天更新了,一周之内就不要去服务器上下载了,是不会有新一集的。一周之后呢,你就要去问服务器,这个文件夹里有没有新资源啊,服务器一比对你电脑上的最新一集和服务器上的最新一集,就能告诉你有没有更新。没有的话,比如美国人又去过感恩节了,你就只能把缓存的几集再撸一遍了。 道理很简单,但是正是这些简单的技术原理,使我们的上网体验越来越好。电脑上网可能感觉不出来,不过现在谁还用电脑上网呢?更多的情况是我们离开了 WIFI,用 2G、3G 打开一个网页,希望它越快出来越好,没有浏览器缓存是很难的。
总结一下,浏览器会缓存它浏览过的「资源」(包括网页,图片,脚本等等),如果资源在保质期内,那下次同样的请求直接用缓存。过期之后,会带上资源上次的修改时间,由服务器来判断是否失效。浏览器的缓存先讲这些,当然这并不是全部,有时候光根据时间来判断失效可能不准,我们留到后面再讲。
来源:oschina
链接:https://my.oschina.net/u/2354417/blog/753460