WebView拦截线上资源,加载离线资源

优化加载:WebView拦截加载离线资源
在项目开发中,通过Charles分析发现Webview加载网页时存在大体积js和css资源,影响加载速度和用户体验。本文介绍了如何在客户端通过WebView拦截线上资源,转而加载本地离线资源,提升Webview的加载效率。重点讲解了拦截资源的步骤,包括获取需要拦截的资源、设置WebViewClient进行拦截,并强调了注意事项,如正确设置mimeType和与前端约定资源文件名。

一、前言

最近的项目开发中接入了一些网页功能,Webview加载完成大约需要10秒左右,经过使用Charles抓包分析,发现在加载过程中出现了几个比较大的js和css文件,这些文件在没有压缩之前有15M左右,发布线上压缩有也有3M左右,这些资源严重影响了webview的加载速度,同时也带来了不好的体验。在极致情况下,web端应该去做这些优化处理,但在项目赶时间的情况下,客户端在做了这些大文件资源做了离线处理,让webview加载这些的时候从本地加载。

二、Webview拦截资源

2.1获取需要拦截的资源

//本地缓存路径,一般都放在assets目录中
private static final String PATH_WEB_RESOURCE = "www";
private List<String> offlineResource;

//获取需要的缓存文件
private List<String> fetchOfflineResource(Context context) {
    AssetManager assetManager = context.getAssets();
    try {
        String[] res = assetManager.list(PATH_WEB_RESOURCE);
        if (res != null) {
            return Arrays.asList(res);
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

2.2拦截处理

Webview中拦截需要 WebViewClient

setWebViewClient(new WebViewClient(){

    //重写以下方法,兼容不同的版本
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView webView, String s) {
        int last = s.lastIndexOf("/");
        if (last != -1) {
            if (s.endsWith(".js") || s.endsWith(".css")) {
                String suffix = s.substring(last);
                if (offlineResource.contains(suffix)) {
                    String mimeType;
                    if (suffix.endsWith(".js")) {
                        mimeType = "application/x-javascript";
                    } else if (suffix.endsWith(".css")) {
                        mimeType = "text/css";
                    }
                    try {
                        return new WebResourceResponse(mimeType, "UTF-8", getContext().getResources().getAssets().open(PATH_WEB_RESOURCE + suffix));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return super.shouldInterceptRequest(webView, s);
    }

    @Override
    public WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest webResourceRequest) {
        return shouldInterceptRequest(webView, webResourceRequest.getUrl().toString());
    }

    @Override
    public WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest webResourceRequest, Bundle bundle) {
        return shouldInterceptRequest(webView, webResourceRequest.getUrl().toString());
    }
});

2.3 注意事项

  1. WebResourceResponse中的mimeType一定要与拦截的资源做好对应关系,比如text、
  2. 和前端约定好这些几乎不变的资源文件名,因为前端在发布的时候会做压缩处理,会改变文件的文件名

小结

为了能够快速响应用户操作,提高用户体验,开发会探索一些优化方案来处理,同时又能够满足产品的快速迭代需求。实际项目中我们还会接入X5WebView和VasSonic来提高WebView的加载速度,其中VasSonic处理起来有点麻烦,需要H5端、服务端、APP端的同时接入

在 HarmonyOS 中,使用 `WebSchemeHandler` 加载本地资源包是一种实现离线加载网页内容的有效方式。通过自定义协议和资源拦截机制,可以将本地文件系统中的资源映射到特定的 URL 协议上,从而实现对 H5 离线资源包的访问控制与加载优化。 ### 自定义协议与 WebSchemeHandler 的绑定 首先需要创建一个继承自 `WebSchemeHandler` 的类,并重写其 `handleInnerRequest` 方法来处理自定义协议的请求。该方法会接收一个 `ResourceRequest` 对象作为参数,用于构造返回的 `WebResourceResponse`。 ```java public class CustomSchemeHandler extends WebSchemeHandler { private Context context; public CustomSchemeHandler(Context context) { this.context = context; } @Override public WebResourceResponse handleInnerRequest(ResourceRequest request) { Uri uri = Uri.parse(request.getRequestUrl()); String path = uri.getPath(); // 获取请求路径 try { // 假设资源存放在应用私有目录下的 assets 文件夹中 InputStream inputStream = context.getAssets().open("webResources" + path); return new WebResourceResponse.Builder() .setMimeType("text/html") .setEncoding("UTF-8") .setResponseData(inputStream) .build(); } catch (IOException e) { e.printStackTrace(); return new WebResourceResponse.Builder() .setResponseCode(404) .setReasonPhrase("Not Found") .build(); } } } ``` ### WebView 配置与 SchemeHandler 注册 在初始化 `WebView` 时,需要为其配置自定义的 `WebSchemeHandler`,以便识别并处理自定义协议(如 `custom://`)的请求。 ```java WebView webView = findViewById(R.id.webView); CustomSchemeHandler schemeHandler = new CustomSchemeHandler(this); // 设置 SchemeHandler 并指定自定义协议 webView.setSchemeHandler("custom", schemeHandler); // 加载自定义协议的 URL webView.loadUrl("custom://example.com/index.html"); ``` ### 资源文件管理与路径映射 为了确保资源能够被正确加载,需将 HTML、CSS、JS 及图片等资源统一打包,并放置在应用的 `assets` 或内部存储目录中。通过解析请求 URL 的路径部分,将其映射到实际的文件路径或资产资源路径中[^3]。 ### 注意事项 - **MIME 类型设置**:返回的 `WebResourceResponse` 必须设置正确的 MIME 类型,以确保浏览器能正确解析内容。 - **编码格式**:对于文本资源(如 HTML、CSS、JS),应设置合适的字符编码(如 UTF-8)。 - **异常处理**:在读取资源时应捕获可能发生的异常,避免因资源缺失导致应用崩溃。 - **性能优化**:对于大体积资源,建议采用流式读取方式,并考虑缓存策略提升加载效率。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值