程序猿小风扇

合抱之木,生于毫末。

0%

一、从一个简单的例子开始

在《Go语言圣经》的第一章有这么一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import (
"fmt"
"log"
"net/http"
)

func sayHello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello world!")
}

func main() {
http.HandleFunc("/", sayHello)
err := http.ListenAndServe(":9090", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}

这是一个基于 HTTP 协议的 WEB 服务,通过监听 9090端口 来响应客户端的请求;从上面可以看出,编写一个 WEB 服务器很简单,只要调用 http 包的两个函数就可以了;并且实际上这个 WEB 服务内部支持高并发,也就是在同一时间可以响应来源多个客户端的请求;Go 大道至简的设计理念,对于长期沉浸在 C/C++ 程序员是一种极大的解放。

那么,Go 是如何实现WEB高并发的?带着这个问题,开始一步步来分析。

阅读全文 »

背景

笔者在《WKWebView》一文中提到过,WKWebView 在独立于 app 进程之外的进程中执行网络请求,请求数据不经过主进程,因此,在 WKWebView 上直接使用 NSURLProtocol 无法拦截请求。所以如果需要使用到拦截请求,有种可行地方案是使用苹果开源的 Webkit2 源码暴露的私有API(详见原文第3小节:NSURLProtocol问题)。
但使用私有API,必然带来以下几个问题:

  • 审核风险
  • 拦截http/https时,post请求body丢失
  • 如使用ajax hook方式,可能存在 post header字符长度限制Put类型请求异常

由此看来,在 iOS11 WKURLSchemeHandler [探究] 到来之前,私有API并不那么完美。
所幸通过寻找发现,iOS系统上具备搭建服务器能力,理论上对实现 WKWebView 离线资源加载 存在可能性。

分析

基于iOS的local web server,目前大致有以下几种较为完善的框架:

  • CocoaHttpServer (支持iOS、macOS及多种网络场景)
  • GCDWebServer (基于iOS,不支持 https 及 webSocket)
  • Telegraph (Swift实现,功能较上面两类更完善)

因为目前大部分APP已经支持ATS,且国内大部分项目代码仍采用OC实现,故本文将以 CocoaHttpSever 为基础进行实验。
Telegraph 是为补充 CocoaHttpSever 及 GCDWebServer 不足而诞生,对于纯Swift项目,推荐使用 Telegraph

阅读全文 »

分析

在iPhone 6s、iOS 10.3.2中,对 http://www.qq.com 进行10次请求,得到如下数据:

次数 UIWebView 内存消耗 WKWebView 内存(APP)消耗 UIWebView 请求耗时 WKWebView 请求耗时
1 67.47 MB 0.81 MB 4.13 s 0.80 s
2 58.23 MB 0.86 MB 1.16 s 0.54 s
3 57.83 MB 0.50 MB 1.14 s 0.56 s
4 59.38 MB 0.88 MB 1.08 s 1.07 s
5 59.70 MB 0.75 MB 1.07 s 0.71 s
6 64.05 MB 0.83 MB 1.47 s 0.65 s
7 59.45 MB 0.81 MB 1.11 s 0.63 s
8 57.55 MB 0.45 MB 1.15 s 0.64 s
9 58.47 MB 0.77 MB 1.17s 0.75 s
10 58.89 MB 0.84 MB 1.11 s 0.70 s

UIWebView平均内存消耗:54.13 MB
WKWebView平均(APP)内存消耗:0.75 MB
UIWebView平均请求耗时:1.46 s
WKWebView平均请求耗时:0.7 s

综上可得:WKWebView在请求耗时上为UIWebView的50%左右,内存上更是完胜。但实际上 WKWebView是一个多进程组件,网络请求以及UI渲染在其它进程中执行。仔细观察会发现:加载时,App进程内存消耗虽非常小甚至反而大幅下降,但Other Process的内存占用会增加。所以:在UIWebView上当内存占用太大的时候,App Process会crash;而在WKWebView上当总体的内存占用比较大的时候,WebContent Process会crash,从而出现白屏现象。

阅读全文 »