
前言
本次我们基于 URLRequest.CachePolicy
协议进行 WKWebView 缓存能力的验证,主要验证方向为网页页面及相应资源的内容缓存。
API 如下
1 | public struct URLRequest : ReferenceConvertible, Equatable, Hashable, Sendable { |
1 | extension NSURLRequest { |
验证策略
我们采取的验证策略为
- 不设置请求头状态下
- 联网状态正常进入,加载网页,查看网页是否正常显示
- 杀死 APP 后,断开网络,加载网页,查看网页是否正常显示
- 设置请求头状态下
- 联网状态正常进入,加载网页,查看网页是否正常显示
- 杀死 APP 后,断开网络,加载网页,查看网页是否正常显示
验证代码如下
1 | import UIKit |
验证过程
固定协议策略
固定使用一个缓存协议模式
- useProtocolCachePolicy 默认方式
- 测试结果:第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页无法打开
- 设置请求头状态下: 第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页正常打开
- 结论:
- 优点:默认策略,无需特别关注配置,网页内容更新不会收到缓存影响,如果本地有缓存可用,会根据缓存控制头来加载缓存内容,会默认进行页面内容缓存。
- 缺点:默认情况下断网后无法加载任何内容,需要根据 HTTP 协议中的缓存控制头(例如 Cache-Control 和 Expires)来决定是否使用缓存中的数据。
- reloadIgnoringLocalCacheData 忽略本地缓存
- 测试结果:测试结果:第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页无法打开
- 设置请求头状态下: 第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页无法打开
- 结论:
- 优点:联网状态下每次都更新最新的内容,忽略本地缓存中的数据,即不使用任何本地存储的缓存副本,当使用此策略时,即使本地缓存中有数据,也会强制从网络重新加载资源。
- 缺点:完全忽略了本地缓存,断网后无法加载任何内容
- 结论:
- reloadIgnoringLocalAndRemoteCacheData 忽略任何缓存
- 测试结果:测试结果:第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页无法打开
- 设置请求头状态下: 第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页无法打开
- 结论:
- 优点:永远展示的是最新的数据,不会受到任何缓存干扰。
- 缺点:完全依赖网络, 忽略本地缓存和远程缓存中的数据,还进一步忽略了远程缓存(例如 CDN 缓存)中的数据。
- 结论:
- returnCacheDataElseLoad 如果缓存中有可用的数据,则使用缓存中的数据;如果没有缓存或者缓存已过期,则从网络重新加载数据
- 测试结果:第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页打开正常
- 设置请求头状态下: 第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页正常打开,缓存过期后无法打开
- 结论:
- 优点:断网后可以正常打开网页,打开的内容是上次最后一次联网记录的内容,如果缓存中有可用的数据,则使用缓存中的数据;如果没有缓存或者缓存已过期,则从网络重新加载数据。
- 缺点:如果一旦缓存成功且不过期,即使联网也不会更新内容,即每次打开的页面都是相同的内容(只有没缓存内容或缓存过期时,才会从网络进行请求)
- 结论:
- returnCacheDataDontLoad 离线模式,如果缓存中有可用的数据,则使用缓存中的数据;如果没有缓存或者缓存已过期,则不从网络重新加载数据。
- 测试结果:第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页打开正常
- 设置请求头状态下: 第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页正常打开,缓存过期后也能打开
- 结论:
- 优点:不依赖网络,纯离线模式,即使没有网,只要有缓存就可以展示内容。
- 缺点:完全无法更新内容,每次打开内容都相同。
- 结论:
- reloadRevalidatingCacheData 强制从网络重新加载数据,但在加载前会验证缓存中的数据是否仍然有效。
- 测试结果:第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页无法打开
- 设置请求头状态下: 第一次联网进入,网页打开正常,杀死APP,断网重新进入,网页正常打开,缓存过期无法打开
- 结论:
- 优点:在缓存过期后能够立即更新到新的内容,同时能够节省流量,在缓存有效期内不进行网络请求
- 缺点:依赖联网,需要请求头中配置内容,否则断网后无法打开,也不会进行页面缓存
- 结论:
动态协议策略
根据网络状态动态切换协议策略
- 测试根据网络环境切换协议 useProtocolCachePolicy -> returnCacheDataDontLoad
- 测试结果:有网时正常打开,无网络时正常打开,但只有缓存的资源可以加载展示
- 测试根据网络环境切换协议 useProtocolCachePolicy -> returnCacheDataElseLoad
- 测试结果:有网时正常打开,无网络时正常打开,但只有缓存的资源可以加载展示
- 测试根据网络环境切换协议 useProtocolCachePolicy -> reloadRevalidatingCacheData
- 测试结果:有网时正常打开,无网络时无法打开
结论
- 当前 YCOneBrowserViewController 中使用的缓存协议为
useProtocolCachePolicy
,断网后无法加载任何内容,但可以根据 HTTP 协议中的缓存控制头(例如 Cache-Control 和 Expires)来决定是否使用缓存中的数据。 returnCacheDataElseLoad
、returnCacheDataDontLoad
、reloadRevalidatingCacheData
和useProtocolCachePolicy
四种协议均可以在断网后使用页面缓存,但对网络的依赖程度和页面更新的影响不同。- 固定协议策略模式下,按断网时缓存生效的可靠性排名:
returnCacheDataDontLoad
>returnCacheDataElseLoad
=reloadRevalidatingCacheData
=useProtocolCachePolicy
- 动态协议策略下,按断网时缓存生效的可靠性排名:
returnCacheDataDontLoad
>returnCacheDataElseLoad
=reloadRevalidatingCacheData
=useProtocolCachePolicy
- 适合目前使用的策略为根据动态协议策略,在联网状态下采用
useProtocolCachePolicy
协议,该协议会在加载完毕后缓存本页面的内容,在断网状态下切换为returnCacheDataDontLoad
保证页面可以加载出来(除非从来没有缓存成功过)。
Actions
- Web页面分级
- 强更新级
- 强静态级
- 切换策略
- 保证缓存
- 全局策略使用固定策略
reloadRevalidatingCacheData
- 配置内容使用 默认
useProtocolCachePolicy
,断网returnCacheDataDontLoad
- 全局策略使用固定策略
- 根据网络状态
- 有网
useProtocolCachePolicy
,如果触发白屏检测切换到returnCacheDataDontLoad
继续加载,添加逻辑进行二次白屏检测 - 断网
returnCacheDataDontLoad
,重新联网切换回useProtocolCachePolicy
- 检测协议缓存是否存在?
- 有网
- 保证缓存
- 开关
- 全局配置:默认
useProtocolCachePolicy
,断网returnCacheDataDontLoad
- 局部配置:根据 url 配置策略
- 全局配置:默认
1 | { |
YCOneBrowserViewController 缓存逻辑
初始化浏览器
1
2
3
4
5
6
7
8
9
10
11@implementation YCOneBrowserViewController
- (void)viewDidLoad {
[super viewDidLoad];
...
[self initBrowser];
...
}
@end加载 requesetURL
1
2
3
4
5
6
7
8- (void)initBrowser {
...
if (![self.configuration disableStartLoadRequest]) {
[self loadRequest];
}
...
}开始加载 url
1
2
3
4
5- (void)loadRequest {
[self loadRequestWithData:nil baseURL:nil];
...
}进入加载逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/*!
* 手动加载请求,默认自动执行加载, 不需要手动调用
* @note configuration.disableStartLoadRequest 为 YES 时,手动执行该方法调用
*/
- (void)loadRequestWithData:(NSString *)requestData baseURL:(NSURL *)baseURL {
if (requestData) { // 用HTML数据直接加载
...
}else if (self.URL.isFileURL) {
...
} else {
[[YCHttpCacheFactory returnWebCacheControl] headForHtmlWithRequest:[NSURLRequest requestWithURL:self.URL]
resultBlock:^(NSURLRequest *resultReqeust) {
...
}];
}
}进入缓存位
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72@implementation YCWebCacheHeaderControl
// 根据HEAD请求,判断静态资源是否更新
- (void)headForHtmlWithRequest:(NSURLRequest *)request resultBlock:(void(^)(NSURLRequest *resultReqeust))resultBlock {
// 若是本地url,则不进行缓存校验
if (request.URL.isFileURL
|| ![self isInWhiteList:request.URL.absoluteString]) {
// 移除已有缓存
[self clearHttpCacheForRequest:request];
NSMutableURLRequest *mutableRequest = request.mutableCopy;
[mutableRequest setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
if (resultBlock) {
resultBlock(mutableRequest.copy);
}
return;
}
NSMutableURLRequest *mutableRequest = request.mutableCopy;
mutableRequest.HTTPMethod = @"HEAD";
[mutableRequest setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
mutableRequest.timeoutInterval = 5.f;
// 获取请求的本地header
NSDictionary *cachedHeaders = [self.diskCache getHeaderByRequestUrl:mutableRequest.URL.absoluteString];
// 设置 headers
if (cachedHeaders) {
NSString *etag = [cachedHeaders objectForKey:@"Etag"];
if (etag) {
[mutableRequest setValue:etag forHTTPHeaderField:@"If-None-Match"];
}
NSString *lastModified = [cachedHeaders objectForKey:@"Last-Modified"];
if (lastModified) {
[mutableRequest setValue:lastModified forHTTPHeaderField:@"If-Modified-Since"];
}
}
[[[NSURLSession sharedSession] dataTaskWithRequest:mutableRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
// 判断响应的状态码 未改变或者离线
if (httpResponse.statusCode == 304
|| httpResponse.statusCode == 0) {
// 读取本地缓存
[mutableRequest setCachePolicy:NSURLRequestReturnCacheDataElseLoad];
} else {
// 存header
if (httpResponse.allHeaderFields) {
[self.diskCache saveHeader:httpResponse.allHeaderFields ByRequestUrl:request.URL.absoluteString];
}
// 加载远程
[mutableRequest setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
}
dispatch_async(dispatch_get_main_queue(), ^{
// 加载资源
mutableRequest.HTTPMethod = @"GET";
if (resultBlock) {
resultBlock(mutableRequest.copy);
}
});
}] resume];
}
@end
其他
为何缓存失效时间和发起请求的当前时间一致
Q: 解释这段response,为何缓存失效时间和发起请求的当前时间一致?
1 | 当前时间: 2024-08-28 06:13:17 +0000 |
A: 根据提供的响应头部信息,我们可以详细解释为什么缓存失效时间(Expires)和发起请求的当前时间几乎一致。
详细解释
- SK—Cache-Control: no-cache
含义: 指示客户端不要缓存响应内容。
作用: 确保客户端每次请求都会从服务器获取最新数据,不使用缓存版本。
- SK—Expires: Wed, 28 Aug 2024 06:13:16 GMT
含义: 表示响应内容的有效期截止时间为 Wed, 28 Aug 2024 06:13:16 GMT。
作用: 告诉客户端在指定的时间之前,可以缓存该响应内容;超过该时间后,需要重新请求。
- SK—Date: Wed, 28 Aug 2024 06:13:17 GMT
含义: 表示响应的生成时间为 Wed, 28 Aug 2024 06:13:17 GMT。
作用: 帮助客户端和服务器同步时间,用于缓存验证和其他时间相关的操作。
为什么缓存失效时间和发起请求的当前时间一致?
- Cache-Control: no-cache:
该头部明确指示客户端不要缓存响应内容。这意味着每次请求都应该从服务器获取最新数据。
- Expires 和 Date 时间几乎一致:
Expires 时间为 Wed, 28 Aug 2024 06:13:16 GMT。
Date 时间为 Wed, 28 Aug 2024 06:13:17 GMT。
这两个时间几乎一致,表明服务器希望响应内容在生成后立即失效。
具体原因
- 即时失效:
由于 Expires 时间几乎与 Date 时间一致,这意味着响应内容在生成后立即失效。
这种设置通常用于需要频繁更新的内容,确保客户端每次请求都能获取到最新数据。
- 结合 Cache-Control: no-cache:
即使 Expires 时间已经过去,Cache-Control: no-cache 也会强制客户端每次都从服务器获取最新数据。
总结
- Cache-Control: no-cache 指示客户端不要缓存响应内容。
- Expires 时间几乎与 Date 时间一致 表明响应内容在生成后立即失效。
- 这种设置通常用于需要频繁更新的内容,确保客户端每次请求都能获取到最新数据。
returnCacheDataDontLoad 为何在缓存过期后仍然可以展示?
Q: 在得到上述response时我使用的缓存策略是useProtocolCachePolicy,如果webview遵循Cache-Control: no-cache 指示客户端不要缓存响应内容,为何我切换为returnCacheDataDontLoad在断网后仍然能展示之前加载过的内容?
A: 在使用 WKWebView 时,缓存策略的选择会影响页面加载的行为。具体来说,WKWebView 提供了几种不同的缓存策略,其中包括 useProtocolCachePolicy 和 returnCacheDataDontLoad。
缓存策略详解
- useProtocolCachePolicy:
使用协议级别的缓存策略。
遵循 HTTP 缓存控制头(如 Cache-Control 和 Expires)。
如果缓存控制头指示不缓存,则不会使用缓存数据。
- returnCacheDataDontLoad:
优先返回缓存数据,即使缓存已过期也不再发起网络请求。
如果没有缓存数据,则显示空白页面。
为什么 returnCacheDataDontLoad 在断网后仍能展示之前加载过的内容
当你使用 returnCacheDataDontLoad 缓存策略时,即使缓存控制头指示不缓存(如 Cache-Control: no-cache),WKWebView 仍然会尝试从缓存中加载数据。这是因为:
- 缓存策略优先级:
- returnCacheDataDontLoad 策略优先返回缓存数据,无论缓存控制头如何指示。
- 这意味着即使 Cache-Control: no-cache,WKWebView 也会尝试从缓存中加载数据。
- 缓存存储机制:
- WKWebView 有一个本地缓存存储机制,即使缓存控制头指示不缓存,实际的响应数据仍然可能被缓存。
- 这种缓存存储机制是为了提高性能和用户体验,即使在某些情况下缓存控制头指示不缓存,实际数据仍然会被缓存。
总结
- useProtocolCachePolicy:
- 遵循 HTTP 缓存控制头(如 Cache-Control 和 Expires)。
- 如果缓存控制头指示不缓存,则不会使用缓存数据。
- returnCacheDataDontLoad:
- 优先返回缓存数据,即使缓存已过期也不再发起网络请求。
- 即使 Cache-Control: no-cache,WKWebView 仍然会尝试从缓存中加载数据。
因此,在断网情况下,使用 returnCacheDataDontLoad 策略时,WKWebView 会优先返回缓存数据,即使缓存控制头指示不缓存。
这个缓存存储机制的具体机制是什么,比如缓存内容的大小限制,对缓存的清理时机等等
A: WKWebView 的缓存机制涉及多个方面,包括缓存内容的大小限制、缓存的清理时机等。下面详细解释这些机制。
缓存存储机制
缓存内容的大小限制
WKWebView 的缓存机制主要依赖于 Safari 的缓存系统。具体来说,WKWebView 使用的是 WebKit 引擎的缓存机制,而 WebKit 的缓存机制又基于 Safari 的缓存策略。
默认缓存大小:
- Safari 和 WebKit 默认的缓存大小为 50MB。这意味着总的缓存大小不会超过 50MB。
- 这个大小限制是为了避免缓存占用过多的存储空间。
自定义缓存大小:
可以通过修改 WebKit 的缓存配置来调整缓存大小。
例如,可以通过 WKWebsiteDataStore 来设置缓存大小。
1
2
3
4
5
6
7
8import WebKit
func configureWebCacheSize() {
let websiteDataStore = WKWebsiteDataStore.default()
let cacheConfig = WKStorageName.default().appendingPathComponent("WebCache")
websiteDataStore.setCapacityOfBytes(for: cacheConfig, to: 100 * 1024 * 1024) // 设置为 100MB
}
缓存的清理时机
WKWebView 的缓存清理机制主要包括以下几种情况:
- 缓存过期:
- 当缓存内容的 Expires 时间到达时,缓存内容将被视为过期。
- Expires 头部指定了缓存内容的有效期。
- 缓存大小限制:
- 当缓存总大小超过设定的大小限制时,WKWebView 会自动清理旧的缓存内容。
- 清理逻辑通常是按照最近最少使用(LRU)原则进行。
- 手动清理缓存:
- 可以通过调用 WKWebsiteDataStore 的方法手动清理缓存。
- 例如,可以定期清理缓存以释放存储空间。
1 | import WebKit |
示例代码
下面是一个完整的示例代码,展示了如何配置缓存大小和手动清理缓存:
1 | import UIKit |
总结
- 缓存内容的大小限制:
- 默认缓存大小为 50MB。
- 可以通过 WKWebsiteDataStore 调整缓存大小。
- 缓存的清理时机:
- 缓存过期:根据 Expires 头部。
- 缓存大小限制:当缓存总大小超过设定的大小限制时,自动清理旧的缓存内容。
- 手动清理缓存:通过调用 WKWebsiteDataStore 的方法进行清理。
通过这些机制,WKWebView 能够有效地管理和维护缓存数据,确保在需要时能够及时加载最新的内容,同时避免占用过多的存储空间。
当缓存内容的 Expires 时间到达时,缓存内容将被视为过期,就会被清理,那为什么我在过期时间以后使用returnCacheDataDontLoad策略依然可以展示已缓存的网页内容呢?
A: 在使用 WKWebView 时,尽管 Expires 或 Cache-Control 指令可以指示缓存何时过期,但是 WKWebView 的行为受到其缓存策略的影响。特别是当你使用 WKWebViewConfiguration.requestCachePolicy = .returnCacheDataDontLoad 时,即使缓存已过期,WKWebView 仍然会尝试从缓存中加载数据。
缓存策略 .returnCacheDataDontLoad 的行为
- .returnCacheDataDontLoad:
- 这个策略指示 WKWebView 在加载资源时优先从缓存中读取数据。
- 如果缓存数据可用,那么 WKWebView 将直接使用缓存数据而不发起新的网络请求。
- 如果没有缓存数据或者缓存数据不可用(例如,缓存已被清理),则 WKWebView 可能会显示空白页面或其它默认内容。
为什么过期后仍然能展示缓存内容
- 缓存过期不等于立即清理:
- Expires 或 Cache-Control 指令标记缓存数据何时被认为是“过期”的,但这并不意味着缓存数据会立即被删除。
- 实际上,缓存数据可能会继续保留在存储中,直到缓存管理器根据其自身的策略决定清理它为止。
- 缓存管理器的清理策略:
- WKWebView 的缓存管理器通常会根据 LRU(Least Recently Used,最近最少使用)原则来决定哪些缓存数据应该被保留,哪些应该被清理。
- 如果缓存空间足够,并且没有达到最大缓存大小限制,那么即使缓存数据过期,也可能暂时不会被清理掉。
- 缓存策略优先级:
- 当使用 .returnCacheDataDontLoad 策略时,WKWebView 会优先尝试使用任何可用的缓存数据。
- 这意味着即使缓存数据已经过期,只要它仍然存在于缓存中,WKWebView 就会使用它。
总结
- 缓存过期不等于立即清理:
- Expires 或 Cache-Control 指令标记缓存数据何时被认为是“过期”的,但这并不意味着缓存数据会立即被删除。
- 缓存策略优先级:
- 当使用 .returnCacheDataDontLoad 策略时,WKWebView 会优先尝试使用任何可用的缓存数据,即使这些数据已经过期。
因此,在使用 .returnCacheDataDontLoad 策略时,即使缓存数据已经过期,只要它仍然存在于缓存中,WKWebView 就会使用它。这意味着即使在断网情况下,用户仍然可以看到之前加载过的页面内容。
这里所说的大小限制是多少
Q: “如果缓存空间足够,并且没有达到最大缓存大小限制,那么即使缓存数据过期,也可能暂时不会被清理掉” 这里所说的大小限制是多少
A: 关于 WKWebView 的缓存大小限制,具体来说,默认情况下,WKWebView 使用的缓存大小限制为 50MB。这是 Safari 和 WebKit 默认的缓存大小限制
缓存大小限制
- 默认缓存大小:
- WKWebView 默认的缓存大小为 50MB。
- 这个大小限制是为了防止缓存占用过多的存储空间。
- 自定义缓存大小:
- 可以通过 WKWebsiteDataStore 来调整缓存大小。
- 你可以根据需要设置一个更大的或更小的缓存大小。
如何查看和调整缓存大小
- 查看当前缓存大小
可以通过 WKWebsiteDataStore 来查询当前的缓存大小:
1 | import WebKit |
- 调整缓存大小
可以通过 WKWebsiteDataStore 来调整缓存大小:
1 | import WebKit |
缓存清理机制
- 缓存过期:
- 当缓存数据的 Expires 时间到达时,缓存数据将被视为过期。
- 过期的数据可能会被清理,但不是立即清理。
- 缓存大小限制:
- 当缓存总大小超过设定的大小限制时,WKWebView 会自动清理旧的缓存内容。
- 清理逻辑通常是按照最近最少使用(LRU)原则进行。
- 手动清理缓存:
- 可以通过调用 WKWebsiteDataStore 的方法手动清理缓存。
- 例如,可以定期清理缓存以释放存储空间。
示例代码
以下是一个完整的示例代码,展示了如何配置缓存大小和手动清理缓存:
1 | import UIKit |
总结
- 默认缓存大小:
- WKWebView 默认的缓存大小为 50MB。
- 自定义缓存大小:
- 可以通过 WKWebsiteDataStore 来调整缓存大小。
- 缓存清理机制:
- 缓存过期:根据 Expires 头部。
- 缓存大小限制:当缓存总大小超过设定的大小限制时,自动清理旧的缓存内容。
- 手动清理缓存:通过调用 WKWebsiteDataStore 的方法进行清理。
通过这些机制,WKWebView 能够有效地管理和维护缓存数据,确保在需要时能够及时加载最新的内容,同时避免占用过多的存储空间。
如果我可以自己调整缓存大小,那这个大小是否存在一个规定的上限值?
A: 关于 WKWebView 的缓存大小,虽然你可以自定义缓存大小,但确实存在一些实际的上限值。这些上限值取决于设备的存储空间以及系统的限制。以下是一些关键点:
缓存大小的上限
- 系统限制:
- iOS 和 macOS 系统对缓存大小有一定的限制。
- 一般来说,缓存大小不应超过设备的可用存储空间。
- 实际限制:
- 通常情况下,WKWebView 的缓存大小建议不超过几百 MB。
- 具体的上限值取决于设备的存储空间和系统配置。
实际操作中的限制
- iOS 设备:
- 对于 iOS 设备,通常建议缓存大小不要超过几百 MB,例如 100MB 到 500MB。
- 实际上限取决于设备的存储空间。
- macOS 设备:
- 对于 macOS 设备,缓存大小可以稍微大一些,但也建议不要超过几百 MB。
实际测试和调整
- 测试不同大小:
- 你可以通过实际测试来确定最适合应用的缓存大小。
- 测试不同的缓存大小,观察应用的表现和设备的性能。
- 动态调整:
- 根据设备的实际存储空间动态调整缓存大小。
- 例如,可以检查设备的剩余存储空间,并根据剩余空间动态设置缓存大小。
示例代码
以下是一个示例代码,展示了如何动态调整缓存大小:
1 | import UIKit |
总结
- 系统限制:
- iOS 和 macOS 系统对缓存大小有一定的限制。
- 通常建议缓存大小不要超过几百 MB。
- 实际限制:
- 具体的上限值取决于设备的存储空间和系统配置。
- 一般建议不要超过设备剩余存储空间的一定比例,例如 10%。
- 动态调整:
- 可以根据设备的实际存储空间动态调整缓存大小,以确保应用的性能和用户体验。
通过这些措施,你可以更好地管理 WKWebView 的缓存大小,确保应用在不同设备上的表现和性能。