宝哥软件园

前端浏览器缓存和代码部署

编辑:宝哥软件园 来源:互联网 时间:2021-12-12

前言

最近,我手上的石膏被拿掉了,于是我下楼去帮室友。楼下室友领导是阿里的,前端采用阿里的蚂蚁设计。设计上传到蓝色泻湖,聊天工具也用了阿里的指甲。有时间的时候也下楼和室友交流学习。如果我有更多的交流,我会被提升。我最近一直很忙。好久没更新博客了。我们不要说太多。今天我们主要讲的是前端性能优化的浏览器缓存。

浏览器缓存

我之前写过浏览器缓存和html5离线缓存。我们很容易对这些缓存感到困惑,比如200 OK(来自内存缓存、来自磁盘缓存)、304 NOT MODIFIED和应用缓存等。

来自内存缓存的200不访问服务器,而是直接读取缓存并从内存读取缓存。此时,数据将缓存在内存中。击杀过程结束后,即浏览器关闭后,数据将不存在。但是这个方法只能缓存派生资源。

来自磁盘缓存的200不会访问服务器,而是直接读取缓存并从磁盘读取缓存。当终止过程发生时,数据仍然存在。只有派生资源才能以这种方式缓存。

04 notmodified访问了服务器,发现数据没有更新。服务器返回了此状态代码。然后从缓存中读取数据。

三级缓存原理

先检查内存,如果有,直接加载。

如果没有内存,选择硬盘获取,如果有直接加载。

如果没有硬盘,则进行网络请求。

加载的资源缓存到硬盘和内存中。

一般浏览图片,以下流程:

访问-200-退出浏览器

然后进入-200(来自磁盘缓存)-刷新-200(来自内存缓存)。

应用缓存和上面的缓存有点不一样,是离线缓存,也就是不用联网就可以从硬盘读取资源,即使网络断开,用户也可以浏览。

设置浏览器缓存

304无论是协商缓存还是与服务器通信一次,如果要切断服务器通信,必须强制浏览器使用本地缓存(cache-control/expires)。

一般来说,设置浏览器缓存有几种方法。

1.通过HTTP的META设置过期和缓存控制。

http-e

quiv="Cache-Control" content="max-age=7200" /> http-equiv="Expires" content="Sun Oct 15 2017 20:39:53 GMT+0800 (CST)" />

这样写的话仅对该网页有效,对网页中的图片或其他请求无效。

2、apache服务器配置图片,css,js,flash的缓存

这个主要通过服务器的配置来实现这个技术,如果使用apache服务器的话,可以使用mod_expires模块来实现:

编译mod_expires模块:

Cd  /root/httpd-2.2.3/modules/metadata/usr/local/apache/bin/apxs -i -a -c mod_expires.c //编译

先打开httpd.conf文件,然后查找expires这个模块,找到后,删除左边的#号,表示打这个模块,并重启apache服务器

编辑httpd.conf配置:添加下面内容

 mod_expires.c>ExpiresActive onExpiresDefault "access plus 1 month"ExpiresByType text/html "access plus 1 months"ExpiresByType text/css "access plus 1 months"ExpiresByType image/gif "access plus 1 months"ExpiresByType image/jpeg "access plus 1 months"ExpiresByType image/jpg "access plus 1 months"ExpiresByType image/png "access plus 1 months"EXpiresByType application/x-shockwave-flash "access plus 1 months"EXpiresByType application/x-javascript      "access plus 1 months"#ExpiresByType video/x-flv "access plus 1 months"

3、php等设置

php  header("Cache-Control: public");  header("Pragma: cache");  $offset = 30*60*60*24; // cache 1 month  $ExpStr = "Expires: ".gmdate("D, d M Y H:i:s", time() + $offset)." GMT";  header($ExpStr);?>

或者

$seconds_to_cache = 3600;$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";header("Expires: $ts"); header("Pragma: cache");header("Cache-Control: max-age=$seconds_to_cache");

缓存情况下前端代码部署

问题一:有了缓存,如何进行前端代码更新呢?

我们可以在资源文件或者图片后面添加版本号,如下图。

enter image description here

问题二:但是所有文件都加了版本号之后,我们只更改了一个文件,其他文件的缓存不是浪费了吗?

解决这个问题,我们可以用数据摘要要算法,对文件求摘要信息,摘要信息与文件内容一一对应。如下图:

enter image description here

这样就解决了这个问题。

问题三:新的问题又来了,文件发布怎么办?

1、先部署页面,再部署资源:在二者部署的时间间隔内,如果有用户访问页面,就会在新的页面结构中加载旧的资源,并且把这个旧版本的资源当做新版本缓存起来,其结果就是:用户访问到了一个样式错乱的页面,除非手动刷新,否则在资源缓存过期之前,页面会一直执行错误。

2、先部署资源,再部署页面:在部署时间间隔之内,有旧版本资源本地缓存的用户访问网站,由于请求的页面是旧版本的,资源引用没有改变,浏览器将直接使用本地缓存,这种情况下页面展现正常;但没有本地缓存或者缓存过期的用户访问网站,就会出现旧版本页面加载新版本资源的情况,导致页面执行错误,但当页面完成部署,这部分用户再次访问页面又会恢复正常了。

好的,上面一坨分析想说的就是:先部署谁都不成!都会导致部署过程中发生页面错乱的问题。所以,访问量不大的项目,可以让研发同学苦逼一把,等到半夜偷偷上线,先上静态资源,再部署页面,看起来问题少一些。

如何解决这些问题呢?

这个问题,起源于资源的 覆盖式发布,用 待发布资源 覆盖 已发布资源,就有这种问题。解决它也好办,就是实现 非覆盖式发布,如下图:

enter image description here

看上图,用文件的摘要信息来对资源文件进行重命名,把摘要信息放到资源文件发布路径中,这样,内容有修改的资源就变成了一个新的文件发布到线上,不会覆盖已有的资源文件。上线过程中,先全量部署静态资源,再灰度部署页面,整个问题就比较完美的解决了。

总结如下:

1、 配置超长时间的本地缓存 —— 节省带宽,提高性能

2、采用内容摘要作为缓存更新依据 —— 精确的缓存控制

3、 静态资源CDN部署 —— 优化网络请求

4、更资源发布路径实现非覆盖式发布 —— 平滑升级

更多资讯
游戏推荐
更多+