共计 4781 个字符,预计需要花费 12 分钟才能阅读完成。
一、前言
挪动互联网时代,网页仍旧是内容展现的重要媒介,这离不开 WebKit 浏览内核技术的反对与倒退。在 iOS 平台下开发者们须要通过 WKWebView 框架来与 WebKit 打交道。尽管苹果官网提供了对于 WKWebView 的 API 与应用阐明,但这并不能满足开发者们的需要,各类简单场景仍旧让咱们焦头烂额,而解决方案却不易寻找。此时,优良的开发者们将眼光移向苹果开源的 WebKit 内核代码,试图从中寻找解惑之道,却发现仍旧困难重重,崎岖一直,次要问题如下:
- 内核源码简单难懂:动辄几个 G 的源码,且不足要害代码正文与阐明,跟踪剖析工作量大;零碎兼容分支较多,一块代码可能辨别 iOS、Mac、嵌入式等分支;历史代码或试验性能较多,导致查看源码并不容易缕清逻辑。
- 无奈联合业务代码剖析:异样问题往往在简单场景下才会呈现,不足业务代码的联合,问题无奈复现,咱们也就无奈定位问题,最终容易走上猜想起因、更换计划尝试修复的路子。
无论你是出于趣味还是以上起因,想要摸索 WebKit 源码而不得其法,本文都将帮忙你疾速入门。接下来,咱们将依照 源码下载、源码编译、创立调试工程、源码实战剖析 的步骤助力你深刻浏览内核摸索之路。
二、源码下载
编译及调试之前咱们首先须要获取一份苹果官网的 WebKit 源码。
- github 下载 (举荐):https://github.com/WebKit/WebKit
- 官网下载:https://WebKit.org/
下载后的 WebKit 工程通过 Xcode(Xcode 是苹果官网举荐的 iOS 利用开发工具)关上后目录如下图。
WebKit 工程目录
其中 gtest / MiniBrowser / MobblieMiniBrowser / TestWebKitAPI / WebKitTestRunner 仓库为测试仓库。思考到编译效率的问题,通常状况下不须要编译测试仓库。因为本文前面将形容如何无效利用这些测试仓库,咱们此处抉择进行全源码编译。
三、源码编译
获取到源码后,接下来咱们介绍下命令行及 Xcode 的编译形式。
本文举荐先应用命令行编译一遍,再用 Xcode 编译。从实际来看,如果编译过程中出错,命令行编译形式更易追踪到具体异样信息。
1) Embedded Builds 下载的 WebKit 目录外面有一个 Tools/Scripts 目录,这外面有各种脚本,包含应用命令行编译 WebKit 的脚本,其中一个重要的脚本就是 configure-Xcode-for-embedded-development,在 Mac 终端控制台运行如下命令:
sudo Tools/Scripts/configure-Xcode-for-embedded-development
之所以须要执行这个脚本,是因为 iOS 属于嵌入式平台,编译嵌入式平台的 WebKit 须要用到一些命令行工具,Xcode 正是利用该脚本构建这些命令行工具。否则,在编译诸如 JavaScriptCore 等工程的时候,就会报如下谬误:‘com.apple.product-type.tool’, but there’s no such product type for the embedded platform,找不到对应的架构。
2)通过 Xcode 进行编译,设置构建产物存储地位
在关上工程后,抉择 Xcode 的 File 菜单,抉择 Workspace Settings,而后关上 Workspace 设置窗口,如下图所示:
接下来咱们抉择 Advanced 按钮,关上如下窗口,按红框所示,将工程编译目录配置为 WebKitBuild,点击实现:
筹备工作终于实现了,接下来咱们能够开始编译了。
3) 开始编译
首先选中 All Source 选项,配置 scheme 抉择模拟器运行,而后点击 Xcode 的构建按钮开始构建。
此处请急躁期待,首次编译耗时较长,本文测试是在 i5 处理器 8G 内存 Mac Pro 机器上测试的,测试 全源码编译耗时 1h。编译胜利后会弹出 MiniBrowser 不可用 正告(属于 Mac 利用工程),咱们漠视即可。此时内核编译工作完结,接下来咱们持续进入下一步,创立调试工程,进行源码摸索。
四、创立调试工程
本文依照两类调试需要进行辨别介绍,别离应用官网 Demo 工程和自定义工程进行调试,具体如下所示。
1)理解 WebKit 运行机制及源码:应用官网 Demo 工程调试
编译实现后,在咱们的工程产物 WebKitBuild 目录中会有一个 MobileMiniBrower APP。此时咱们能够在工程 scheme 配置中抉择 MobileMiniBrowser APP 进行工程构建,该 APP 是苹果官网的浏览器 Demo(如下图所示),可通过地址栏执行地址输出,后退 / 后退以及多 Tab 等性能,可在源码里进行断点测试。
2)剖析理论业务问题:应用自定义工程调试
针对这类需要,咱们就须要依照如下步骤在工程中 应用咱们编译胜利的 WebKit.framework 去替换零碎的 WebKit.framework:
- 首先,用 Xcode 新建一个新的 Project,示例外面是 TestWKWebView,并将这个 Project 增加到 WebKit 的工程空间 WebKit.xcworkspace 中,编译产物依照 WebKit 编译所述,同样输入到 WebKitBuild 目录。
- 做好下面的设置之后,就能够编写测试程序,在测试程序中打上断点,这时你会发现零碎 WebKit 库曾经被替换,断点可跳转源码,即可欢快的进行源码摸索了。
走到这一步后,大家能够发现,WebKit 源码很宏大,哪怕代码 run 起来了,如何下断点剖析问题仍旧很难把控。因而咱们须要进行一些知识点的补充与了解,本文将进入实战环节,用 Demo 工程进行剖析阐明,给大家提供源码剖析的思路。
五、源码实战剖析
1)WebKit 的多过程机制
在 iOS 零碎中,通常一个利用对应一个过程,然而在 WebKit 的倒退过程中,基于稳定性与安全性思考,引入了多过程的概念,防止繁多页面的异样影响整体 app 运行,首先本文简略介绍下几个常见的 WebKit 过程, 如下所示。
- UIProcess —— 应用程序所在过程,WKWebView 代码和 WebKit 框架已加载到你的过程空间中;
- WebContent —— 又称 WebProcess,JS 和 DOM 内存调配所在的地位,即网页内容渲染与 js 执行所处过程;
- Network Process —— 负责收回与 Web 申请关联的根底网络申请;
- Storage Process —— 用于数据库和服务工作者的存储。
接下来,咱们用两个 Demo 进行内核剖析:
Demo1 —— 单 webview 模型:
咱们在 Demo1 工程中简略应用一个 WKWebView 来进行网络加载,以百度首页为例,运行我的项目后,点击调试模式中的 show the debug navigator 选项,该性能是 debug 下的资源剖析模块。
当初咱们能够查看各过程的 CPU、内存、磁盘、网络应用状况,当然也能够进行 Instruments 剖析。
过程散布如下:
Demo2 —— 多 webview 模型:
应用多个 WKWebView 进行网络加载,每加载一个网页,创立一个新的 WKWebView 实例。
过程散布如下:
联合以上 Demo 工程,咱们能够有一个直观上的了解:
- WebContent 过程 对应的是每一个新开的网页,该过程视内存状况可进行复用,某一 WebContent 过程的异样并不会影响到主 app 过程,常见的异常现象为白屏。
- UIProcess 过程 为 app 所在过程,WKWebView 在该过程中提供了大量 API 供开发者与内核交互,也是开发者最相熟的一部分。
- NetWorking 过程,无论多 WKWebView 还是单 WKWebView 场景,都只有惟一的 NetWorking 过程,这种设计次要便于网络申请治理以及保障网络缓存、cookie 等治理的一致性。
苹果官网文档中形容:配置同一 WKProcessPool 的多个 WKWebView 共享同一 WebContent 过程,即能够配置 WebContent 过程惟一(https://developer.apple.com/d…)。
但源码头文件中的正文与官网文档不统一,源码头文件形容配置同一 WKProcessPool 的多个 WKWebView 共享的是同一 WebContent 过程池,该配置未限度 WebContent 过程数量,而是共享过程池。
从 Demo 理论测试看,官网文档形容并不精确,咱们以源码正文为准。
有了上述了解,咱们再去看 Xcode 下 WebKit 的文件目录,目录也依照过程职责进行了较为正当的划分。
因而,在调试过程中,除了依据已知关联 API 或代码堆栈进行全局搜寻或单步断点调试外,咱们还能够多联合三大过程的工作职责进行问题剖析与查找。另外,既然能够查看各过程的 CPU、内存、磁盘、网络等状态了,对这方面有性能要求的,能够用来查看一个网页加载时各过程具体的资源耗费是多少。
2)TestWebKitAPI 工程
应用源码工程,除了代码剖析外,苹果零碎还提供了大量的零碎 API 相干功能测试,这些测试基于 gtest 框架实现,集成在 TestWebKitAPI 工程里,实际中依照如下思路可利用 TestWebKitAPI 工程进行一些接口分析与测试:
- 理解各类 API(包含公有 API)的测试用例,通过这类代码示范与阐明,便于咱们深刻理解接口的应用标准,更好的了解 API 的设计思路。
- 利用该框架可进行 gtest 测试,gtest 是一个跨平台的 (Liunx、Mac OS X、Windows、Cygwin、Windows CE and Symbian) C++ 单元测试框架,由 google 公司公布,它能在不同平台上编写 C++ 测试代码。gtest 框架提供了丰盛的断言、致命和非致命判断、参数化、”死亡测试”等。在 WebKit 内核源码中已有大量的基于 gtest 框架的测试代码积攒,当咱们做了一些 trick 操作时,基于 TestWebKitAPI 工程做自动化测试,也是一种不错的抉择。
六、Tips
- WebKit 源码调试可能在个别状况下不会用到,然而对于 WebKit 简单问题的剖析与解决,联合业务对 WebKit 源码进行摸索与剖析,还是有肯定意义的。
- 非凡场景下,开发者可能对一些 API 进行非凡应用,这个时候可断点调试的源码能更好帮忙咱们躲避危险。
- 苹果官网禁止了在真机上替换 WebKit 内核,咱们能够编译对应的真机库,然而无奈进行装置调试,因而本文里的内容都是在模拟器进行的。
- 因 webkit 源码在不断更新,因而下载编译过程中可能会遇到一些不兼容问题,个别可通过正文相干不兼容代码解决。
七、结语
本文作为入门篇章不再详述 WebKit 内核关键技术剖析,你当初能够调试 WebKit 源代码,或在运行 Web 应用程序时应用 Instruments 来剖析 WebKit 过程。心愿本文能率领你够更深刻地理解应用 WKWebView 利用的堆栈细节,并更好地理解 WebKit 层如何工作,后续作者会持续抽丝剥茧,基于业务详述浏览内核关键技术,与君共勉~
敬请期待:
深刻了解 WKWebView(根底篇)– WKWebView 加载生命周期与代理办法分析
深刻了解 WKWebView(根底篇)– 聊聊 cookie 治理那些事
深刻了解 WKWebView(根底篇)– 探索 WebKit 网络资源缓存
参考资料:
1. WebKit 源码:https://github.com/WebKit/WebKit
2. WebKit 官网:https://webkit.org/
举荐浏览:
|基于 etcd 实现大规模服务治理利用实战
|短视频个性化 Push 工程精进之路
|百度爱番番数据分析体系的架构与实际
———- END ———-
百度 Geek 说
百度官网技术公众号上线啦!
技术干货 · 行业资讯 · 线上沙龙 · 行业大会
招聘信息 · 内推信息 · 技术书籍 · 百度周边
欢送各位同学关注