背景介绍缓存一直是前端性能优化的重要一环。了解前端缓存对于构建高性能网站至关重要。之前对缓存的认知一直停留在阅读《HTTP权威指南》和一些相关帖子的深度。过了一段时间,我总是忘记它。正好最近不是很忙。结合内网的一些参考资料,结合实践,试对缓存及其最佳实践进行全面分析。前后端交互中涉及的缓存前端是浏览器针对HTTP规范实现的资源缓存。HTTP规范定义了4个与缓存相关的字段。对HTTP感兴趣的同学也可以看看我在《HTTP权威指南》的读书笔记。《HTTP权威指南》以上是HTTP中关于缓存的header字段。浏览器其实只是HTTP协议的一个代理客户端。变成我们看到的样子,就像QQ本身应该只是一个即时通讯工具,但现在也是一个巨头。一般情况下,我们只缓存GET请求。当然我们可以缓存POST等其他类型的请求吗?按照规范是可以的,只要设置相应的头域,即Cache-Control、Expires等即可。但是这里其实意义不大。之所以要做缓存,是因为在现在的互联网环境下,最影响性能,也就是最耗时的部分是网络传输。如何在有限带宽下提高性能?这里是缓存展示拳脚的世界。对于后端来说,缓存有两种,一种是存放在磁盘硬盘中,一种是存放在内存中。相对来说内存缓存速度快,但是容易造成内存泄露,所以这部分需要慎重管理好(听说淘宝首页是H5页面,为了提高性能,选择驻留在内存以提高分发速度)。后端缓存主要是为了防止前端渗透到DB(数据库),因为后端的主要性能瓶颈大部分存在于查表,所以通过后端缓存,发生减少直接穿透到DB的用户请求,从而提高性能。本文重点介绍前端。因为后台不是很专业,所以只介绍如上。有兴趣的朋友可以进行深入研究。注意:浏览器的缓存也是基于磁盘的,缓存在硬盘上。前端缓存的套路前面说过,前端的核心就在于上面的四个header字段。以对CSS样式的常见请求为例。对于第一个请求,服务器通常会发送这4个字段,可能是全部4个,也可能一个都不发送。这里主要说明四个字段都存在的情况。对前端的第二次请求:首先,浏览器会检查Cache-Control和Expires。如果有Cache-Control,就以它为标准。如果超时,就会向后端发送请求,请求中会带上If-Modified-Since,If-None-Match。背景:后台服务器收到请求后,会比较这两个字段,同样以If-None-Match为准。如果没有If-None-Match,则比较If-Modified-Since。如果对比发现文件没有过期,即Etag没有变化,或者Last-Modified与If-Modified-Since一致(仅当If-Modified-Since存在时)。如果改变,则发送一个新文件,否则,直接返回304。这是请求过程的粗略图片。但仅此而已,离真正的修炼还是有一定的距离。浏览器提供的三种刷新方式在第一种情况下被认为是理想的,但在实际场景中,不可能像规范中那样令人满意。所以浏览器提供了三种刷新方式。点击url+enter或者标签的超链接,点击前进后退键F5刷新或者点击刷新键ctrl+F5强制刷新。那么,这三种情况有什么区别呢?第一个其实是我们理想中的情况,特别注意如果缓存还没有过期,借助Chrome的Network,我们会发现状态码是200,因为没有请求到后端而是上次的结果request是直接reproduced,所以还是200,唯一不同的是他的size栏不显示他的size,而是从cache中显示。第二种会直接忽略Cache-Control和Expires是否过期,直接在requsetheaders中设置Cache-Control:max-age=0,直接向服务端发送请求。服务器根据If-None-Match和If-Modified-Since判断是否过期。大多数情况下,我们长期设置静态资源,很多都没有过期。这个时候我们会看到很多304(还有一种情况是请求过期后得到304)。第三种也是直接忽略Cache-Control和Expires是否过期,设置Cache-Control:no-cache,不会发送If-None-Match和If-Modified-Since。服务器必须返回新资源。如何启用缓存设置既然您知道了缓存的好处,那么配置缓存的方法有哪些呢?配置apache或ngix服务器,启用相应的缓存模块,在后端代码中动态设置前端HTML页面meta标签,主要有3种方式。最省心省力的方法应该是第一种,也是最常用的方法,第二、第三种只能说是辅助。我的是在腾讯云上买的服务器,配置方法如下:在ubuntu上配置apache缓存。配置指导思想服务器配置主要针对静态资源,如图片、css、js等,一般是类型匹配,然后设置一个过期时间。比如照片的过期时间要设置的越长越好,比如1个月,CSS和JS脚本也可以设置的长一些,但是HTML脚本一定不要设置缓存时间。在生产实践中,为了满足尽可能长时间缓存和尽可能更新版本的要求,通常在构建时标记MD5码,因为所有静态资源都是通过HTML或通过HTML页面视图导入的,所以你只需要控制HTML。请求相应的更新版本完全可以满足上述要求。第二段代码如下res.set('Cache-Control','max-age=60000');//nodeexpress第三段代码如下
