docs: WKWebView request hook && APM Wake Up

This commit is contained in:
liubinpeng
2021-05-28 10:03:50 +08:00
parent 0fa61f3513
commit 3d346dd596
12 changed files with 575 additions and 747 deletions

BIN
.DS_Store vendored

Binary file not shown.

13
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,13 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Dart & Flutter",
"request": "launch",
"type": "dart"
}
]
}

View File

@@ -792,3 +792,20 @@ https://mp.weixin.qq.com/s?__biz=MzUxMzcxMzE5Ng==&mid=2247488218&idx=1&sn=21afe0
NSURLProtocol能够让你去重新定义苹果的URL加载系统(URL Loading System)的行为URL Loading System里有许多类用于处理URL请求比如NSURLNSURLRequestNSURLConnection和NSURLSession等。当URL Loading System使用NSURLRequest去获取资源的时候它会创建一个NSURLProtocol子类的实例你不应该直接实例化一个NSURLProtocolNSURLProtocol看起来像是一个协议但其实这是一个类而且必须使用该类的子类并且需要被注册。                                       
4. WKWebView 网络请求拦截
原生 WKWebView 在独立于 app 进程之外的进程中执行网络请求,请求数据不经过主进程,因此在 WKWebView 上直接使用 NSURLProtocol 是无法拦截请求的。
但是由于 mPaas 的离线包机制强依赖网络拦截所以基于此mPaaS 利用了 WKWebview 的隐藏 api去注册拦截网络请求去满足离线包的业务场景需求参考代码如下
```Objective-c
[WKBrowsingContextController registerSchemeForCustomProtocol:@"https"]
```
但是因为出于性能的原因WKWebView 的网络请求在给主进程传递数据的时候会把请求的 body 去掉,导致拦截后请求的 body 参数丢失。
在离线包场景,由于页面的资源不需要 body 数据,所以离线包可以正常使用不受影响。但是在 H5 页面内的其他 post 请求会丢失 data 参数。
为了解决 post 参数丢失的问题mPaas 通过在 js 注入代码hook 了 js 上下文里的 XMLHTTPRequest 对象解决。
通过在 JS 层把方法内容组装好,然后通过 WKWebView 的 messageHandler 机制把内容传到主进程,把对应 HTTPBody 然后存起来,随后通知 JS 端继续这个请求,网络请求到主进程后,在将 post 请求对应的 HttpBody 添加上,这样就完成了一次 post 请求的处理。整体流程可以参考如下:
![ajax-时序图](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2021-05-28-WKWebViewRequestHook)
通过上面的机制,既满足了离线包的资源拦截诉求,也解决了 post 请求 body 丢失的问题。但是在一些场景还是存在一些问题,需要开发者进行适配。

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@ int main(int argc, const char * argv[]) {
在 foo 方法里面下断点,见下图
![rename symbol](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2020-02-25-asm.png)
![rename symbol](./../assets/2020-02-25-asm.png)
可以看到,`foo` 方法的 symbol 被变为 `@杭城小刘`,变量 `age` 被变为 `objc_age`
@@ -43,7 +43,7 @@ int main(int argc, char * argv[]) {
}
```
![App main 方法 rename 失败](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2020-02-25-asm2.png)
![App main 方法 rename 失败](./../assets/2020-02-25-asm2.png)
可以看到 App 工程主入口函数 `main` 函数,想修改为 `mook_main`。但是报错 `ld: entry point (_main) undefined. fir architecture x86_64`

View File

@@ -1,15 +1,23 @@
# APM
# APM - Wake Up
## 启动时间的监控和治理
- https://everettjf.github.io/2018/08/24/most-simple-task-queue-model/
- https://github.com/izhangxb/GMTC/blob/master/全球移动技术大会GMTC%202017%20PPT/手淘iOS性能优化探索%20.pdf
- https://mp.weixin.qq.com/s/Kf3EbDIUuf0aWVT-UCEmbA
- http://yulingtianxia.com/blog/2016/10/30/Optimizing-App-Startup-Time/
- https://www.jianshu.com/p/c14987eee107
- https://time.geekbang.org/column/article/85331
- https://punmy.cn/2018/06/18/15278496835424.html
- https://www.shangmayuan.com/a/a14fb820d1bc4457b018bf7b.html
>
网传:如果在老设备上,使用最新的 iOS 系统苹果会自动降频CPU 频率),从而让你的 iPhone 看上去很卡,让你主动去购买新的设备。
> 我知道可以借助三方工具类BSBacktraceLogger获取主线程调用栈[BSBacktraceLogger bs_backtraceOfMainThread];然后定时0.01秒计算各方法的调用耗时。但是具体不知道该怎么计算啊,望老师指点!
作者回复: 连续相同的堆栈,将其时间相加就是那个堆栈方法的耗时。
其实,苹果在 iOS 13 的时候,在内核中加入了一个新的性能衡量指标`wakeup`。CPU 频率和设备电池有关系。看看 ARM 架构中对于 CPU 功耗问题的描述:
> Many ARM systems are mobile devices and powered by batteries. In such systems, optimization of power use, and total energy use, is a key design constraint. Programmers often spend significant amounts of time trying to save battery life in such systems.
由于ARM被大量使用于低功耗设备而这些设备往往会由电池来作为驱动所以 ARM 在硬件层面就对功耗这个问题进行了优化设计。
功耗可以分为2种类型即静态功耗与动态功耗。
静态功耗指的是只要 CPU 通上电,由于芯片无法保证绝对绝缘,所以会存在“漏电”的情况,而且越大的芯片这种问题越严重,这也是芯片厂家为什么拼命的研究更小尺寸芯片的原因。这部分功耗由于是硬件本身决定的,所以我们无法去控制,而这种类型功耗占比不大。
动态功耗指的是 CPU 运行期间,接通时钟后,执行指令所带来的额外开销,而这个开销会和时钟周期频率相关,频率越高,耗电量越大。这也就说明了苹果为什么会控制 CPU 使用率而相关研究Facebook 也做过也表明CPU 在20以下和20以上的能耗几乎是成倍的增加。
且苹果在具体哪个系统推出了 Battery Health 模块,其中有个 Maximum Capacity 的指标。用于判断电池的性能。苹果在这个开放出来之前,肯定已经在收集电池的健康状况。
iOS 11.3 及更高版本优化了性能管理功能,会定期评估所需的性能管理程度,以避免意外关机。如果电池健康能够满足系统所观察到的对峰值电源的要求,则系统会调低性能管理的程度。如果再次出现意外关机,则系统会调高性能管理的程度。这种评估是持续进行的,使得性能管理更能适应实际情况。
综上:当老设备运行新的 iOS 操作系统,系统会判断电池健康状态,如果电池不够健康,那么系统为了防止电池持续损坏(当 CPU 以较高频率工作,则会损坏电池设备,降低寿命),会自动降低 CPU 频率。其中这个有个判断标准,这个标准是不断变化的。

View File

@@ -97,3 +97,4 @@
* [91、二进制重排](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter1%20-%20iOS/1.91.md)
* [92、flutter 无痕埋点](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter1%20-%20iOS/1.92.md)
* [93、flutter 新功能引导](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter1%20-%20iOS/1.93.md)
* [94、APM-Wake Up](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter1%20-%20iOS/1.94.md)

View File

@@ -335,6 +335,22 @@ function proxy_on(){
## 九、iTerm 提示升级,升级后终端报错
![报错信息](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2021-05-05-agnosterConfiguration.png)
报错信息如上图所示。复制这个路径信息到 Finder 中。按住快捷键 `Command + Shift + G`,在弹出的面板中输入路径,点击回车,会看到定位到一个文件。用 VSCode 打开后看到如下所示,就是代码配置文件冲突
![报错信息](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2021-05-05-agnosterConflicts.png)
解决冲突即可。

View File

@@ -96,7 +96,7 @@
* [91、二进制重排](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter1%20-%20iOS/1.91.md)
* [92、flutter 无痕埋点](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter1%20-%20iOS/1.92.md)
* [93、flutter 新功能引导](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter1%20-%20iOS/1.93.md)
* [94、APM-Wake Up](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter1%20-%20iOS/1.94.md)
* [Chapter2 - Web FrontEnd](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter2%20-%20Web%20FrontEnd/chapter2.md)
* [1、-last-child与-last-of-type你只是会用有研究过区别吗](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter2%20-%20Web%20FrontEnd/2.1.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB