前言

参考链接:nginx_百度百科 未安装 Nginx 配置的话请移步至:Nginx的反向代理与负载均衡—配置Nginx

1. 首先需要了解的是浏览器的整个的执行机制

前端性能优化常用技术手段--Nginx服务器缓存策略 - 图1

  1. 浏览器对我们的静态资源,比如说 js css html 图片 字体 等都是有缓存策略的,如果说浏览器自身有缓存,它就会从自己本身的缓存里读了,我们也可以通过网络层类似于我们的服务器包括 Nginx 还有各种各样的静态资源服务器来设置我们的缓存
  2. 首先是如果本机的浏览器有缓存的话,那么他直接就在这个缓存里就获取到了,然后呈现给用户
  • 那么这个缓存还需要查看,如果是在网络上会查看它是否是过期的:
    • 如果不是过期的,它也是从本地的缓存中读取之后就可以了;
    • 如果是过期的就需要看一下这个资源有没有 Etag 这样的东西,Etag 是浏览器向服务器发送请求时的一个请求报头,服务器那边也会响应这个请求报头,然后两边共同的匹配一下资源是否过期,如果有 Etag 的话,它就会向浏览器注入 If-None-Match (如果没有匹配 — 百度翻译)这样的头。然后向我们的 webserver 发过去,然后服务器那边做一个基础的策略:是否是匹配的 Etag ,如果是匹配的就返回一个 304,如果没有匹配就给 Etag 这个文件一个戳,然后返回 200 更新,这样下次再请求的时候有了这个 Etag 就不会再把整个的资源再重新拉回来了
    • 如果没有发现 Etag 的话,在我们服务器还可以设 Expires ,Expires 这个东西就是过期时间,他发现 Last-Modified (最后修改 — 百度翻译)这样一个策略,它会向我们的服务器发送一个 If-Modified-Since (如果更改了 — 百度翻译)就是说上次的修时间,然后和服务器的 Expires 做一个对比,如果发现过期了就返回一个新的,如果是没过期就返回一个 304
    • 如果是上面的 Etag 和 Last-Modified 两个值都没有,那么他就会直接向我们的 web服务器发送一个请求,然后是请求响应—缓存协商
    • 如果是上面的 Etag 和 Last-Modified 这两个值都进行设置了,那么就是会将两个值都比较,都满足了之后才会最终得到一个响应,没有谁先谁后的问题,那么当我们设置对应的文件的时候,你会发现很多对应的服务器都是同时的对他们进行设置的,就是设置了 Etag 又设置了 Last-Modified ,所以说当你这个文件有对应的修改的时候,你还要及时的去修改这个 Last-Modified 就是里面的一个 Expires 的东西
    • Etag 相比于 Expires 有很多优点,它是一个基于文件的一个戳的比较,可以实现一个实时的更新,Expires 这个东西实际上是做不到那种秒秒级别的,它是一个 Unix 的一个时间戳,他做不到那种特别精细的时间的控制
    • 现在的话你也可以在 Header 里面设 control ,可以直接重写掉 Expires 这样的东西
    • 如果是一个整个的项目,你不是运维工程师的话,你可以跟运维去说:我需要设置这个文件对应的强缓,就比如说:这个文件 30 年不过期,例如 jquery 这种长时间不过期的文件,这个的话一般就用 Expires 的比较多,就是说过期时间设置较长这个就是强缓,那么 Etag 的话一般是针对的我们的业务的文件
      #接着下面是将上面所述的整个过程在 Nginx 里面进行演示
      ###前言
  1. 你需要知道的是:在任何的其他的服务器里面,它们这个的逻辑、思维是一样的,关键是要去看你是怎么去配置的。
  2. 操作 Nginx 的基础是你已经在服务器端安装并配置好了,我这里衔接的是 Nginx的反向代理与负载均衡—配置Nginx 这篇文章,这里我选择使用的是 Centos

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图2

具体的操作

  1. 在本机使用 Cmder 命令行终端通过 ssh 命令远程登录上 Centos 服务器上,温馨提示:这里你有可能会因为服务器的 ssh 服务没有开启又或者是 防火墙未关闭、服务器未开启而导致无法连接,请先在服务器端确保无误之后再进行操作

    1. ssh root@192.168.230.129
    2. Enter your password

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图3

  2. 在命令行中进入 nginx 配置文件的目录

    1. cd /etc/nginx/

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图4

  3. 查看当前目录下的所有文件

    1. ls

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图5

  4. 查看 nginx.conf 配置文件的内容

    1. cat nginx.conf

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图6

  5. 然后再重新打开一个命令行窗口

    1. //先远程登录
    2. ssh root@192.168.230.129
    3. Enter your password
    4. //再进入到 存放 nginx 静态资源的目录
    5. cd /usr/share/nginx/
    6. //查看目录下的所有文件 这里面是有一个存放项目的 html 的文件夹
    7. ls

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图7

  6. 然后先查看 nginx 状态,如果未启动,先执行启动服务的命令,之后再查看状态是否为 running 启动中

    1. systemctl status nginx
    2. systemctl start nginx
    3. systemctl status nginx

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图8

  7. 启动之后就可以在浏览器中打开服务器 IP 地址的在 ngnix.conf 文件中配置的 8080 端口了

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图9

  8. 这里我们对 /usr/share/nginx/ 下的 HTML 文件夹进行一些操作

    • 先查看文件找到 index.html

      1. cd html
      2. ls

      前端性能优化常用技术手段--Nginx服务器缓存策略 - 图10

    • 编辑 index.html 文件

      1. vi index.html
    • 这里在我执行上面的命令时进行了提示,这里直接回车就可以了

      前端性能优化常用技术手段--Nginx服务器缓存策略 - 图11

    • 然后就可以看到这个文件的源码了,然后按下键盘上的 i 键进入可编辑状态

      前端性能优化常用技术手段--Nginx服务器缓存策略 - 图12

    • 下面的 INSERT 表示现在是可编辑状态

      前端性能优化常用技术手段--Nginx服务器缓存策略 - 图13

    • 修改源码:在源码的 body 里面引入 jquery 文件,这里我直接是有的是 bootcdn 上的资源,再修改文字并增加 utf-8 编码格式

      1. <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
    • 退出并保存

      1. //先按键盘上的 ESC 键
      2. //然后再按 shift + :
      3. //之后再输入 wq (wq 是保存并退出 q! 是不保存并退出)
      4. //再回车

      前端性能优化常用技术手段--Nginx服务器缓存策略 - 图14

  9. 之后就可以刷新浏览器查看下修改的是否已成功以及 jquery 是否已经引用上

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图15

  10. 之后我在第二个命令行窗口中再 html 文件夹的同一级目录下新建一个 images 目录,并将本机桌面的图片复制到服务器上,再在 index.html 中引入

    1. //先查看当前路径
    2. pwd

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图16

  • 再在命令行中新开一个窗口,使用 scp 命令将桌面下的 000.jpg 文件复制至服务器的 /usr/share/nginx/html 文件夹下

    1. //先进入桌面查看具体路径
    2. cd Desktop
    3. // scp 要复制的文件路径 用户名 @ 服务器IP地址 : 文件路径 要复制到那里的路径名称
    4. scp ./000.jpg root@192.168.230.129:/usr/share/nginx/html
    5. Enter your password

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图17

  • 接着回到第二个命令行窗口下查看是否复制成功了

    1. ls

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图18

  • 接着在 index.html 中引入上面复制过来的图片

    1. cd ..
    2. cd html
    3. vi index.html
    4. i
    5. //在html 中新增一个 img 标签引入刚才复制的 img 文件
    6. <img src="./000.jpg" >
    7. ESC
    8. shift + :
    9. wq

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图19

  1. 这个时候在刷新浏览器会发现图片已经引用成功了

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图20

  2. 这里还可以在 nginx.conf 配置文件中增加图片类型引用时的判断,其他的静态资源也是同样的套路

    参考地址:nginx如何配置静态文件expires时间_百度经验

  • 这个设置的意思是:在请求所有的目录的路径中匹配 图片 正则表达式,如果匹配的话就是下面的 第一行是 文件的具体路径;第二行是过期时间 30天

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图21

  1. 还有一个需要注意的是:再进行验证的时候不能把下图中的这个 Disable cache 勾选上,这个勾选上的话就是禁用缓存了,这里我们实现的是需要缓存的,所以是绝对不能勾选的

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图22

  2. 接着来分析一下请求到的东西

  • document

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图23

    • 请求报文中的 Accept-Encoding 这个可以看到是支持 gzip 压缩的
    • 返回报文中的 ETag 加了一个戳,这个是 nginx 默认就开启的,如果是想要关闭的话,在 nginx.conf 文件中的 http 对象里加 etag: off; 即可,开启就是 on,不加的话默认的就是 on
    • 可以看到下面请求报文中有一个 If-None-Match 的值也是和上面的 Etag 的值是一样的
  • jquery

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图24

    • 因为这这里默认开启了 Etag 所以当你下次刷新的时候,它会跟服务器做对比,如果 Etag 的值是一样的说明没有改变就返回的是 304 ,可以看到下面请求报文中有一个 If-None-Match 的值也是和上面的 Etag 的值是一样的
  1. 接下来在第一个命令行窗口中在 nginx.conf 文件中将 gzip 开启,对比一下效果
    1. vi nginx.conf
    2. i
    3. //添加一行代码
    4. gzip on;
    5. ESC
    6. shift + :
    7. wq

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图25

  • 之后再重载 nginx

    1. nginx -s reload

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图26

  • 再次刷新浏览器,查看 document

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图27

    • 这个返回的是 304 是因为我们的 index.html 文件没有改变,ETag 的值也没有发生改变,如果 Etag 值是一样的说明没有改变就返回的是 304 ,可以看到下面请求报文中有一个 If-None-Match 的值也是和上面的 Etag 的值是一样的
  • 为了看出效果我们在第二个命令行窗口中修改 index.html 文件

    1. vi index.html
    2. i
    3. //如果有一些提示语的话回车一下
    4. //在之前的 "小川" 前面加一个 "孙"
    5. ESC
    6. shift + :
    7. wq

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图28

  • 之后再刷新浏览器

    • 这个文字已经相应的更新过来了

      前端性能优化常用技术手段--Nginx服务器缓存策略 - 图29

    • 也会发现 document 返回的报文中多了一个 gzip 的属性,然后是可以看到下面请求报文中有一个 If-None-Match 的值和上面的 Etag 的值已经不一样的,这个的机制是以 If-None-Match 后面的戳去匹配 Etag 也就是服务器响应的戳,发现是不一样的就会重新将更新后的资源拿过来 状态码也是 200

      前端性能优化常用技术手段--Nginx服务器缓存策略 - 图30

  • 再次刷新浏览器会发现,状态码是 304 了,而且 ‘If-None-Match’ 的戳和 Etag 的戳已经变成一样的了

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图31

    • 这个走的就是下图所标识的地方

      前端性能优化常用技术手段--Nginx服务器缓存策略 - 图32

    • 如果是没有这个 Etag ,它会校验 Last-ModifiedIf-Modified-Since 的戳是否一样,服务器来返回相应的状态

  1. 接下来在第一个命令行窗口中在 nginx.conf 文件中增加一个 epirse,过期时间的属性,对比一下效果
    1. vi nginx.conf
    2. i
    3. //编辑文件新增 属性 30d 是 30天
    4. expires 30d;

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图33

  • 重载

    1. nginx -s reload
  • 还需要像之前的那样对 index.htmlHTML 文件进行一些修改,这样方便于查看效果

    • 在 第二个命令行窗口中进行修改
      1. vi index.html
      2. i
      3. //将 "孙小川" 改为 "xiaochuan"
      4. ESC
      5. shift + :
      6. wq
  • 这个时候再刷新浏览器查看

    • 这个时候会发现返回报文中多了一个 Expires 过期时间的属性,后面的值刚好是今天再加上 30 天之后的具体日期

      前端性能优化常用技术手段--Nginx服务器缓存策略 - 图34

  1. 还可以在 nginx.conf 文件中加一句话:告诉浏览器不要缓存文件
    1. add_header Cache-Control no-cache;

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图35

  • 再重载

    1. nginx -s reload
  • 随便修改一下 index.html 文件

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图36

  • 再刷新浏览器,第一次是 200 第二次是 304 ,还有就是服务器返回时也有明确的标识:Cache-Control: no-cache 就是告诉浏览器不要缓存,然后具体的资源文件是像服务器请求的,服务器来决定返回的状态码

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图37 前端性能优化常用技术手段--Nginx服务器缓存策略 - 图38

总结

  • 将上面的东西都尝试的设置一遍之后,那么 Nginx 上比较关键的东西:Gzip 、Etag、 Expires (过期时间)、Cache-Control 这些就都配置好了;
    Cache-Control 下面还会有一些非常细致的东西:如果你在 Cache-Control 中配置了更多的过期时间就可以直接把 Expires 直接重写掉了,在一些不支持 HTTP.1 的浏览器里设置 Expires 是没有用的,所以你还是要再设置一个 Cache-Control
  • 百度官网的一个 js 文件的响应头部,有颜色的那些对我们来说都是需要掌握的东西

    前端性能优化常用技术手段--Nginx服务器缓存策略 - 图39

  • 掌握这个东西之后,对于以后来讲我们就可以跟运维去聊这个东西,比如说:我们的 jquery ,你就可以直接告诉他,我的这个jquery需要在页面上缓存多久多久,这个就可以设置一个 过期时间 Expires 或者是 Cache-Control,我的其他业务文件可能会临时变,所以需要配置 Etag ,这样的话他就会非常清楚的知道要怎样去配置这些相应的文件,当然这个东西具体操作还是运维去做的,我们只是需要知道这些东西是干嘛的就可以了