总结
1. webview初始化耗时优化
1. webview提前加载(缓存池)
1. webview初始化会占用很大一部分时间,提前加载备用可以避免耗时
2. 注意点
1. webview重用时,页面资源需要clear,例如需要清空history队列、页面内容清空
2. 可能存在native堆栈多次push webview的情况。即页面的push不是webview内部加载HTML,而是通过native端push新的UIviewcontroller,加载新的webview。这种情况,会造成webview的大量出现,同时无法提前加载合适数量的webview。
2. webview与请求并行加载
1. request的请求需要依赖webview的初始化完成,避免等待webview初始化的时间,考虑并行加载
2. webview单独加载,request通过网络请求通道单独请求,当webview加载完成(或者request完成),加载请求结果到初始化完成的webview
2. 资源加载耗时优化--加载离线资源
1. 基于NSURLProtocol的拦截加载本地资源
1. H5容器首先区分是UIWebview还是WKwebview
1. Apple已弃用UIWebview,APP内部线程运行,存在内存问题,效率低,js交互性能差等劣势,但可以完美使用NSURLProtocol
2. wkwebview是iOS8之后出现,但很多新功能会受限于iOS系统版本。性能优于UIWebview,单独进程运行,js交互方便。但NSURLProtocol的使用有很大问题
3. 综上,只适用UIWebview
2. 针对wkwebview,无法使用nsurlprotocol,可以考虑自定义的schemehandle拦截
1. 只支持自定义scheme,无法对http、https、file使用
2. 版本要求,iOS11以上
3. 离线包技术
1. 基于本地路径,加载本地H5页面和资源
1. UIWebview的loadHTMLString:baseURL:
2. wkwebview的loadFileURL:allowingReadAccessToURL:
3. webview loadrequest时,根据url dispatch到本地资源路径,加载本地离线资源
2. 若H5资源存在动态化可能,需要离线包版本管理逻辑,以及版本同步策略,自建服务端发布平台
3. 可能问题:
1. 二向箔。本地相对路径方式,所有静态资源,都会产生离线化要求
2. 访问本地资源还会导致资源路径泄漏产生安全问题
3. 还会有一些浏览器的安全设置无法通过
4. 无法实现跨域资源请求,会让前端开发人员无法访问外部cdn(实测可以http://xxx/xxx.png方式后获取到资源)
4. 模板加载
1. 针对某些新闻类页面,样式固定,数据内容不同
2. 可以本地离线template HTML,请求新数据,本地重写填充template,并加载显示
3. 前端优化
1. 服务端提前渲染,静态直出
1. 页面在服务器端拉取首屏数据后通过NodeJs进行渲染,然后生成一个包含了首屏数据的Html文件
2. 首屏数据不用在客户端执行脚本加载处理,直接渲染HTML
2. 资源迁移到CDN,请求响应加速
3. 页面分离:HTML自定义增量标签,类似于模板加载
1. 首次加载template HTML,native端并行拉取最新数据,将增量标签替换成新数据,并刷新页面
4. 业务逻辑优化,减少js页面逻辑耗时
4. 基于浏览器webview容器的优化,设计webview底层加载优化,Android上可能,参考UC团队https://www.infoq.cn/article/9UKos4Xh_6wL4Fh1FOGL
参考文章:
1. 几种首屏提速策略简述(推荐阅读)
1. https://juejin.im/post/5cd4fda8f265da03a00febe1#heading-6
2. 离线包:通过获取沙盒H5路径直接加载
1. 步骤
1. 将所有的h5文件都放入一个文件夹中。
2. 将这个文件夹以相对路径的方式倒入到工程代码中。
3. 获取本地的文件路径。
2. 核心方法:
1. loadFileURL:allowingReadAccessToURL:
2. loadHTMLString:baseURL:
3. 可能问题:
1. 二向箔。本地相对路径方式,所有静态资源,都会产生离线化要求
2. 访问本地资源还会导致资源路径泄漏产生安全问题
3. 还会有一些浏览器的安全设置无法通过
4. 无法实现跨域资源请求,会让前端开发人员无法访问外部cdn(实测可以http://xxx/xxx.png方式后获取到资源)
3. 基于NSURLProtocol进行请求拦截(参考内容图2--百度Android拦截实现方案)
1. 拦截APP内HTTP/HTTPS请求,返回本地缓存资源
2. 在UIWebview完美支持实现加载缓存,但wkwebview不支持
1. WKWebview与NSURLProtocol兼容问题https://www.zhihu.com/question/39434803
4. 基于WKURLSchemeHandler进行自定义scheme注册拦截
1. 只支持自定义scheme,无法对http、https、file使用
2. iOS11以上
5. 自建本地服务器加载本地资源
1. 实质是:离线包技术+自建服务器拦截请求,具备两种方案的优点
2. 技术成本高
6. webview预加载,节省加载时间。
1. webview pool,实现webview的重复利用
2. 用完放回,需要清空webview,即重新加载空白页
7. 结合native功能
1. 网络请求、资源加载可考虑通过js调用native接口实现
1. 手机QQ优化方案
1. VasSonic(https://mp.weixin.qq.com/s/5SASDtiBCHzoCN-YBZy1nA)
2. 静态直出(服务端渲染):为了优化首屏体验,大部分主流的页面都会在服务器端拉取首屏数据后通过NodeJs进行渲染,然后生成一个包含了首屏数据的Html文件,这样子展示首屏的时候,就可以解决内容转菊花的问题了。
3. 离线包:提前下载H5资源(HTML,js,image等),本地加载(loadFileURL:allowingReadAccessToURL:或loadHTMLString:baseURL:)
4. 并行加载:webview和资源并行加载,避免等待时间,见参考内容图一
5. 动态缓存:缓存已打开的HTML,通过NSURLProtocol拦截请求,本地直接返回(针对UIWebview)
6. 页面分离:HTML增加自定义标签,增量更新标签内容
2. 支付宝mpaas-nebula动态化方案
1. https://segmentfault.com/a/1190000017043584
2. 实质是离线包技术
3. 特点是提供平台级的一整套支持服务,从开发、测试到后期运维提供多方保障
4. 虚拟域名,疑似自建本地服务器加载技术方案
5. fallback降级技术
3. UC 信息流正文“闪开”优化实践
1. https://www.infoq.cn/article/9UKos4Xh_6wL4Fh1FOGL
2. 极致优化—>浏览器webview内核优化
3. UI 页面 = F 模板 (Data 数据)
1. 将模板和数据分拆,并尽可能保障在用户触达前获取,然后根据场景选择合适的组装“地点”
注图:
- H5加载流程
初始化 webview -> 请求页面 -> 下载数据 -> 解析HTML -> 请求 js/css 资源 -> dom 渲染 -> 解析 JS 执行 -> JS 请求数据 -> 解析渲染 -> 下载渲染图片
- 百度App安卓采用的请求拦截方式