- Published on
资源加载那些事
- Authors

- Name
- noodles
- 每个人的花期不同,不必在乎别人比你提前拥有

本文整理网页资源加载系列内容,包含网络缓存过程、CDN、离线包、资源加载优化等.通过阅读可以实现对资源加载有比较系统的认识.
网络缓存

本地-强缓存
强缓存是浏览器在请求资源的时候,直接使用本地缓存的资源而不通过服务器去获取资源的一种方式.强缓存的实现是通过响应头中的expires和Cache-Control中的max-age来控制. Http/1.1的max-age优先expires
| 字段 | 意义 | 优先级 |
|---|---|---|
| expires | 指定缓存的过期时间(与客户端的时间设置相关) | HTTP 1.1 max-age优先expires |
| max-age | 指定请求资源过后多少秒后资源过期 | HTTP 1.1 max-age有优先expires |
当请求的资源存在本地缓存副本并且处于新鲜期的时候,直接返回本地资源. 当请求的资源没有本地缓存的时候,向服务器拉取对应的资源. 当资源存在缓存但是已经过期的时候,通过缓存协商去服务器获取资源.
请求-缓存协商
缓存协商是指通过与服务端交互缓存资源的信息来判断当前缓存是否可用的一种机制. 当通过缓存协商服务端认为当前的资源是可用的,返回304(响应体是空).客户端可以使用当前缓存资源并且更新缓存相关信息. 当服务端认为资源不可用的时候,返回200(响应体中包含请求的资源).
Cache-Control
Cache-Control 被用于在http请求和响应中通过指定指令来实现缓存机制。缓存指令是单向的,这意味着在请求设置的指令,在响应中不一定包含相同的指令.
| 字段 | 意义 |
|---|---|
| no-cache | 资源会被缓存,但每次使用前必须向服务器发起验证请求(协商缓存),验证通过后才可使用本地缓存 |
| no-store | 不进行缓存 |
| max-age | 相对于请求时间设置的最大过期时间 |
| public | 可以被客户端和代理缓存 |
| private | 只能客户端缓存,不能被代理缓存 |
| must-revalidate | 缓存过期后,必须向服务器重新验证,不得直接使用过期的缓存资源(即使网络不可用也不能使用过期缓存) |
last-modified和Etag
last-modified和Etag都是在响应头中返回的对资源的一些设置信息,可以通过这两个值来缓存协商当前缓存资源时候可用.
| 字段 | 意义 | 作用方式 | 优先级 |
|---|---|---|---|
| last-modified | 资源在服务端的上次修改时间 | 通过在请求头中设置If-Modified-Since的值为缓存资源的last-modified值来与服务端询问缓存的新鲜度 | 服务端优先验证Etag |
| Etag | 代表资源的实体标识,当资源的内容在服务端修改的时候,需要重新生成Etag | 通过在请求头中设置If-None-Match的值为缓存资源的Etag值来与服务端询问缓存的新鲜度 | 服务端优先验证Etag |
Etag的出现更像是为了弥补last-modified的不足.例如:
- last-modified的时间只能精确到秒
- 一个资源的频繁修改但是内容并没有修改
CDN
CDN简介
CDN(内容分发网络)指的是一组分布在各个地区的服务器.这些服务器存储着数据的副本,当用户访问资源的时候,CDN服务器可以根据用户的IP,服务集群的负载状态等信息尽快的返回给用户所需要的资源.
CDN优点
CDN主要的功能是托管静态资源,项目中对静态资源进行CDN的配置已经是标配,使用CDN主要有以下优点:
- 将静态资源托管给CDN起到给源站分流的作用,降低服务端负载,解决网络网络带宽问题和不同服务商网络速度不同的问题.
- 对资源的请求大部分都在CDN的边缘节点完成,访问延迟降低,用户能尽快的看到内容.
- CDN域名与源站域名不同,源站的cookie不会随着静态资源的请求发送,避免 Cookie 随静态资源请求发送,减少无效流量.
CDN请求资源流程

CDN优化
- 合理设置CDN节点的缓存时间,保证用户能及时同步到最新的内容
- 根据不同的路径 配置不同的缓存规则,实现缓存的最大化
- CDN缓存节点预热
离线包
离线包是一种将静态资源预先打包下发到客户端的技术,常见于 Hybrid App 场景,可以有效降低首屏网络请求延迟。
离线包
资源加载优化
缓存的意义
- 资源或者服务的尽快到达和可用
- 解决网络带宽问题和服务负载
- 减少网络流量,让流量做更加有意义的事
思考
缓存在提升性能、降低延迟的同时,也引入了额外的复杂度:如何保证缓存与源数据的一致性、如何控制缓存的存储与淘汰成本、如何在缓存失效时优雅降级——这些都是需要提前权衡的问题。
技术决策从来不是非黑即白的。在对系统基础服务做改动之前,不妨先问自己两个问题:这个改动可能在哪里出问题? 我为什么要这样做,而不是另一种方式? 把这两个问题想清楚,再动手,往往能少走很多弯路。