三种形式:Native页面、RN页面和h5页面,相当比前两种形式,h5有跨平台、开发成本低、迭代速度快优势,同时也有加速速度慢,性能不够理想的问题。为弥补h5的短板,最快最有效的是提升h5加载速度。
根据前端同事的调研,以下为h5页面加载过程耗时分析:
其中静态资源下载过程时间是最长的,而且根据h5的复杂程度还可能会更长,如果能提前把这些资源缓存好,并拦截WebView加载资源的过程,这将大大提交h5的打开速度。幸运的是Android的webview可以直接拦截下载资源。
public class DuWebViewClient extends WebViewClient { @Nullable @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { return super.shouldInterceptRequest(view, url); } }客户端方案
对于客户端来说,资源缓存主要包括两部分: h5资源下载,WebView资源拦截
在具体实现时还需要解决解决几个问题
- 提前缓存的资源哪里来?
- 在远端创建一个配置文件,配置好需要提前缓存的资源url
- 请求需要预加载的资源配置列表接口
- 清空待下载的任务队列,防止重复和冗余请求
- 在缓存中检查本地是否存在
- 存在直接略过
- 不存在放入下载队列
- 下载资源策略
- 根据配置将资源分为几个优先级 priority
- 特高 0: 不论前后台,不论网络情况立即下载
- 高 1: 前台wifi条件下,或者后台不论网络环境下
- 中 2: 后台,不论网络环境
- 低 3: 后台wifi条件下
- 在进入不同条件时,从待下载列队中取出下载任务进行下载
- 下载完成后进资源进行校验
- 检查规则暂定采用返回头里面的md5进行校验
- 资源存储到缓存,防止
- 缓存采用LRUDiskCache,大小暂定50M,这样可以
- 将下载的资源本身,及请求的Respone的header部分进行存储
- 以资源的url作为惟一key进行保存,此时要保证当资源有修改时url也一定会修改
- WebView拦截资源
- 重写WebViewClient的shouldInterceptRequest方法
- 根据url查找本地是否存在缓存
- 有缓存就取出缓存与header
- header添加字段du_cached: [缓存时间戳],预留
- 埋点统计
- 针对首次打开WebView页面的进行统计
- 页面加载完毕后上传Apm
下载流程:
拦截流程
代码框架设计
遵循高内聚,低偶合的原则,sdk对外主要暴露四个类,FastHybridApi与FastHybridConfig配置初始化,IFastHybridProxy用来代理WebView资源加载过程,而FastHybridResourceResponse单独封装利于我们转化成自己需要的对象。所以对于外外部使用来说,仅需要三步
- 根据需求初始化
FastHybridApi.init(context, FastHybridConfig( appId = "du", isDebug = DuConfig.DEBUG, configUrl = if (DuConfig.DEBUG) TEST_CONFIG_URL else RELEASE_CONFIG_URL , miniCheckTime = if (DuConfig.DEBUG) 0L else FhConstants.DEFAULT_MINE_CHECK_TIME ))
- 创建IFastHybridProxy, 其中setOnLoadCallBack是为了统计页面加载完成的时间
boolean isH5resourceLoad = ConfigCenterHelper.isEnable("h5resourceLoad", false); fastHybridProxy = FastHybridApi.INSTANCE.createProxy(loadUrl, isH5resourceLoad); fastHybridProxy.setOnLoadCallBack((url, timeSpent, isCacheOpen, isCacheResource, isFirstLoad, cachedResources) ->{ if (isCacheResource && isFirstLoad){ FhLogger.INSTANCE.d("onLoad upload to apm..."); Mapmap = new HashMap<>(); map.put("url", url); map.put("cost", String.valueOf(timeSpent)); ApmBiClient.monitorMap("other", isCacheOpen && isH5resourceLoad ? "h5_resource_load" : "h5_resource_load_2", map, 1f); } } );
- 代理WebView的加载过程
private DuWebViewClient webViewClient = new DuWebViewClient() { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); if (fastHybridProxy != null) { fastHybridProxy.onPageStarted(url); } } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); onPageLoadFinish(view, url); if (fastHybridProxy != null){ fastHybridProxy.onPageFinish(url); } } @Nullable @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { FastHybridResourceResponse resourceResponse = fastHybridProxy != null ? fastHybridProxy.shouldInterceptRequest(request) : null; return resourceResponse != null ? resourceResponse.toWebResource() : super.shouldInterceptRequest(webview, request); } @Nullable @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { FastHybridResourceResponse response = fastHybridProxy != null ? fastHybridProxy.shouldInterceptRequest(url) : null; return response != null ? response.toWebResource() : null; } };
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)