webview 优化加载 H5 应用(尝试方案)

简介: webview 优化加载 H5 应用(尝试方案)

之前提到过,web 产物的优化问题。我就在想那能不能把产物包拆开,有些写到原生apk中?于是有了本次的方案尝试。


特定方式编译 web 产物

这里以 alita 的项目为例,因为在alita的项目中,初始项目只有一个 alita 的依赖。设想是将用户的 alita 依赖包,编译到一个 vendors 文件中,用户添加的其他第三方依赖,编译到另一个 micro 文件中。这样可以保证每个项目编译出来的 vendors 文件都是一样的,或者说,可以使得多个项目共用一个 vendors 文件。(经过多次尝试,虽然每次编译出来的 vendors 文件大小,不完全一致,但是交换着使用,却没有任何问题。)


设置默认移除依赖

我们读取用户项目的 package.json 文件,取得 dependencies 里面定义的第三方依赖。定义一个排除数组。这里是 'alita' 和 'alita' 中已经包含的常用依赖。如果在 umi 项目中,那可能是 umi、umi-preset-react 和 umi-plugin-xxx 等。

const exclude = ['alita', 'classnames'];


设置默认引入依赖

由于项目中的 antd 和 antd-mobile 是按需加载的,即最终被引入到项目中的依赖库,如。

import Button from 'antd/es/button';

在编译的时候,webpack 以为的包名是 antd/es/button 而不是 antd。因此我们可以手动把 antd 相关的东西再加回来。定义一个需要导入的第三方依赖。

const include = ['antd-mobile', 'antd', 'rc-', 'rmc-'];

结合两次定义的数组,取得我们需要包含的真实的依赖。

const dependencies = api.pkg.dependencies || {};
const pkgNames = Object.keys(dependencies)
.filter((i) => !exclude.includes(i))
.concat(include);

增加 chainWebpack 配置(这在上一个文章中,有较为详细的说明)。把满足我们定义的第三方依赖,打包到 micro 文件中,剩余的 打包到 vendors 中。

cacheGroups: {
            micro: {
              name: 'micro',
              chunks: 'all',
              enforce: true,
              test: (module: any, chunks: any) => {
                if (module.resource) {
                  for (let key = 0; key <= pkgNames.length; key++) {
                    if (
                      module.resource.includes(`/node_modules/${pkgNames[key]}`)
                    ) {
                      return true;
                    }
                  }
                }
                return false;
              },
              priority: -9,
            },
            vendors: {
              name: 'vendors',
              chunks: 'all',
              test: /[\\/]node_modules[\\/]/,
              priority: -12,
            },
          },
        },

这是的判断条件是包含,因为存在 rc-* 等库。

执行编译之后,产物中就会包含三个js文件,umi.js,micro.jsvendors.js


增加 chunks 配置

chunks: ['micro', 'umi']

需要注意的是,我们产物是三个文件,但是我们只用了两个。并不包含 vendors.js

生成的index.html,如下所示:

<body>
    <div id="root"></div>
    <script src="./micro.js"></script>
    <script src="./umi.js"></script>
</body>


webview 前置引入vendors.js

上面我们提到,产物是三个js文件,但是我们在 html 中却只用了两个。还有一个我们放到原生app中。(我们安卓开发的同事提供的方法)

WebView mWebView;
// 取到 js 文件
final String jsStr = FileUtil.getJsStr(mActivity,"vendors.js");
BaseJavaScript javaScript = new BaseJavaScript();
mWebView.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                Log.i("caicai", "shouldOverrideUrlLoading");
                return true;
            }
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                Log.i("caicai", "onPageStarted");
            }
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
            }
            @Override
            public void onLoadResource(WebView view, String url) {
                super.onLoadResource(view, url);
                Log.i("caicai",url);
                view.evaluateJavascript(jsStr, new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String value) {
                        Log.i("caicai", "jsStr:"+value);
                    }
                });
            }
        });

安卓中使用 view.evaluateJavascript 方法,将js文件前置添加到 webview 中。ios中有类似的方法(来自ios开发同事)

 WKUserContentController *userContentController = 
 configuration.userContentController;
 [userContentController addUserScript:script];

这种方式加载,可以减少大文件的下载时间,一个正常的项目,只需要下载100k左右的js文件。在对接到已知系统的情况,可以显著的提升用户体验。


安卓添加腾讯X5内核

同一个web应用,在ios上和安卓上,同样用webview打开的方式访问,在安卓上确实无法和iOS上对比。但是只要改动几个配置,引入腾讯X5内核,在安卓端的体验就可以有一个质的飞跃。接入方式非常简单,不会安卓原生开发的小白,就可以完成。比如我!


app/build.gradle 增加模块

// 这个不同的项目引入方式还不一样,注意看下上下文的引入方式,不要全信官方文档
implementation 'com.tencent.tbs.tbssdk:sdk:43903'

app/src/main/AndroidManifest.xml 中增加访问权限

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application>
// service 写在 application 里面
<service
            android:name="com.tencent.smtt.export.external.DexClassLoaderProviderService"
            android:label="dexopt"
            android:process=":dexopt" >
        </service>
</application>

替换所有引用的库

把原生 android.webkit 的引用修改为  com.tencent.smtt.sdk ,根据官方文档,一个一个的全局覆盖就好了。


开启预启动功能

这个是需要搭配上面提到的 service 服务一起使用才会有效的。

// app/src/main/java/com/example/minialita/MainActivity.java 
@Override
    protected void init() {
        HashMap map = new HashMap();
        map.put(TbsCoreSettings.TBS_SETTINGS_USE_SPEEDY_CLASSLOADER, true);
        map.put(TbsCoreSettings.TBS_SETTINGS_USE_DEXLOADER_SERVICE, true);
        QbSdk.initTbsSettings(map);
    }

其他地方都不用修改,还是使用保留之前的用法。但是 web 应用的滚动流畅性非常好,页面跳转切换,也有接近原生的感受。(还是差一点点)


虽然说,这作为一个尝试方案,但是在真实项目中使用,却可以明显的提高用户体验。实践成本也很小。如果在你们有类似的使用场景,不妨尝试一下。


目录
相关文章
|
开发工具 Android开发
应用研发平台EMAS的用户反馈SDK确实使用了WebView
应用研发平台EMAS的用户反馈SDK确实使用了WebView
141 6
|
移动开发 小程序 Android开发
小程序webview组件嵌H5页面,安卓手机没有问题,苹果有部分页面不显示
小程序webview组件嵌H5页面,安卓手机没有问题,苹果有部分页面不显示
363 0
|
API Android开发 数据安全/隐私保护
解决android webview 加载http url 失败 net::ERR_CLEARTEXT_NOT_PERMITTED 错误
解决android webview 加载http url 失败 net::ERR_CLEARTEXT_NOT_PERMITTED 错误
2322 0
|
6月前
|
前端开发 JavaScript API
Webview+Python:用HTML打造跨平台桌面应用的创新方案
本文系统介绍了使用PyWebView库结合HTML/CSS/JavaScript开发跨平台桌面应用的方法。相比传统方案(如PyQt、Tkinter),PyWebView具备开发效率高、界面美观、资源占用低等优势。文章从技术原理、环境搭建、核心功能实现到性能优化与实战案例全面展开,涵盖窗口管理、双向通信、系统集成等功能,并通过“智能文件管理器”案例展示实际应用。适合希望快速构建跨平台桌面应用的Python开发者参考学习。
647 1
|
小程序 Android开发 iOS开发
ISO钉钉小程序小程序webview打开nextjs应用异常
ISO钉钉小程序小程序webview打开nextjs应用异常
158 3
|
存储 移动开发 Android开发
使用kotlin Jetpack Compose框架开发安卓app, webview中h5如何访问手机存储上传文件
在Kotlin和Jetpack Compose中,集成WebView以支持HTML5页面访问手机存储及上传音频文件涉及关键步骤:1) 添加`READ_EXTERNAL_STORAGE`和`WRITE_EXTERNAL_STORAGE`权限,考虑Android 11的分区存储;2) 配置WebView允许JavaScript和文件访问,启用`javaScriptEnabled`、`allowFileAccess`等设置;3) HTML5页面使用`<input type="file">`让用户选择文件,利用File API;
|
Android开发
【Azure 环境】移动应用 SSO 登录AAD, MSAL的配置为Webview模式时登录页面无法加载
【Azure 环境】移动应用 SSO 登录AAD, MSAL的配置为Webview模式时登录页面无法加载
166 0
|
Android开发 UED Kotlin
kotlin webview 加载网页失败后如何再次重试
在Kotlin中,当使用WebView加载网页失败时,可通过设置WebViewClient并覆盖`onReceivedError`方法来捕获失败事件。在该回调中,可以显示错误信息或尝试使用`reload()`重试加载。以下是一个简要示例展示如何处理加载失败
|
Web App开发 移动开发 JavaScript
通过H5(浏览器/WebView/其他)唤起本地app
通过H5(浏览器/WebView/其他)唤起本地app
|
Web App开发 数据采集 移动开发
开发uniapp过程中对app、微信小程序与h5的webview调试
开发uniapp过程中对app、微信小程序与h5的webview调试
1949 1