H5离线包技术的实际应用-webview秒开

一、背景

在实际业务中,我们app中的webview使用的场景越来越多,加载速度成为了困扰用户的一个痛点,尤其是h5由jsp过渡到vue后,页面加载速度更慢了,经常是经过长时间的loading才能加载出来,虽然这和我们的整体架构有关,首页有4-7个webview fragment,在进入首页的时候会同时加载,各个页面都需要加载大量的图片以及数个请求。为此,提高加载速度成为了优化当中的一个方向。

二、技术探索

在查阅过相关资料后,技术方向大体分为了两个,一个是鹅厂的VasSonic通过辅以x5内核对于webview的优化,加上页面直出,整体加载速度很夸张,在我看来基本逼近了webview的加载极限,但是其难以实现之处在于侵入性很强,需要整体结构向它靠拢,后端、h5、Android三方配合,对于像我们公司以业务为导向的团队来说,做起来还比较困难。另一个就是离线包,通常来说,加载一个h5页面最耗时的部分就在于页面资源的下载,如html、css、js文件,如果这些文件不需要下载,那么剩下的时间开销基本就是页面解析及渲染。我们Android在和h5沟通过以后,决定采取方案二。

三、技术实现

1.离线包的组成

离线包由h5提供,包里面的结构基本和线上一致,本身我们的h5网页就是放在cdn上,这次只不过是拿出来,打成压缩包,放在Android的apk包里

2.Android对离线包的解析

首先,离线包的zip包是放在assets文件夹下,在app启动时,解压zip包到相应的文件夹目录下,拿到这个本地路径

3.对线上地址的替换

webview在加载的时候,会调用loadurl方法,此时传进去的url还是线上的url,Android要做的最重要的一步就是重写webviewClient的shouldInterceptRequest方法,在里面拿到要加载的url,并且进行替换,替换成本地url。同样的道理,凡事线上资源都可以进行替换,如css、js、图片资源,还可以通过glide对图片资源进行缓存。核心代码如下

    //=============================离线化对webviewclient的改造
    @Nullable
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String urlOrigin) {
        //拦截请求,把本地页面地址转换成线上页面地址
        String url = UrlConfig.replaceUrlHost(urlOrigin);

        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url));
        //如果是图片走缓存
        if (("image/jpeg".equals(mimeType) || "image/png".equals(mimeType)))
            return handleImageRequest(url, mimeType);


        if (UrlConfig.USE_OFFLINE && !url.contains("http")) {
            //构建WebResourceResponse,走重写后的方法。super会直接load传进来的urlOrigin
            try {
                URL localUri = new URL(url);
                InputStream is = localUri.openConnection().getInputStream();
                return new WebResourceResponse(
                        MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url))
                        , "UTF-8", is);

            } catch (IOException e) {
                //如果文件找不到,拦截方法会失效,还是走之前的url
                if (e.getMessage().contains(".js")) {
                    //当前线程-Chrome_FileThread
                    webview.getHandler().post(new Runnable() {
                        @Override
                        public void run() {
                            onError.onErrorReceived();//处理白屏的情况,缺少js文件会走onError
                            C.OFFLINE_LOADFAIL = true;
                        }
                    });
                }

                e.printStackTrace();
            }
        }
        return super.shouldInterceptRequest(view, url);
    }

注释1:UrlConfig.replaceUrlHost方法里面是具体替换过程。举个例子:线上地址肯定是 ww.baidu.com/index.html这种,本地地址就是file:///storage/0/emulate/baidu/index.html,把index.html之前做字符串替换就可以。

四、最终效果

经过测试同学的性能测试,页面首次加载提升率平均50%,二次加载平均提升35%;由于网络请求也是Android代替h5请求,所以request请求提升超过80%,这些数据是正常网络状态下,而在弱网状态下更是有超过300%的提升

================================================================================================

如有问题,可加1510312433交流

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
方案是为解决特定问题或达成特定目标而制定的一系列计划或步骤。它的作用是提供一种系统性的方法,以有效地应对挑战、优化流程或实现目标。以下是方案的主要作用: 问题解决: 方案的核心目标是解决问题。通过系统性的规划和执行,方案能够分析问题的根本原因,提供可行的解决方案,并引导实施过程,确保问题得到合理解决。 目标达成: 方案通常与明确的目标相关联,它提供了一种达成这些目标的计划。无论是企业战略、项目管理还是个人发展,方案的制定都有助于明确目标并提供达成目标的路径。 资源优化: 方案在设计时考虑了可用资源,以最大化其效用。通过明智的资源分配,方案可以在有限的资源条件下实现最大的效益,提高效率并减少浪费。 风险管理: 方案通常会对潜在的风险进行评估,并制定相应的风险管理策略。这有助于减轻潜在问题的影响,提高方案的可行性和可持续性。 决策支持: 方案提供了决策者所需的信息和数据,以便做出明智的决策。这种数据驱动的方法有助于减少不确定性,提高决策的准确性。 团队协作: 复杂的问题通常需要多个人的协同努力。方案提供了一个共同的框架,帮助团队成员理解各自的职责和任务,促进协作并确保整个团队朝着共同的目标努力。 监控与评估: 方案通常括监控和评估的机制,以确保实施的有效性。通过定期的评估,可以及时调整方案,以适应变化的环境或新的挑战。 总体而言,方案的作用在于提供一种有序、有计划的方法,以解决问题、实现目标,并在实施过程中最大化资源利用和风险管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值