0


creator-webview加载优化


title: creator-webview加载优化

categories: Cocos2dx
tags: [cocos2dx, creator, webview, 优化, 加载, 性能]
date: 2024-03-02 13:17:20
comments: false
mathjax: true
toc: true

creator-webview加载优化


前篇

使用 Android 的 webview 去加载一个 cocos 的 h5 游戏, 如果全部资源都有网络上请求的的话, 即使使用了缓存, 第一次加载还是避免不了加载全部资源的情况, 还是会很慢.

加载H5页面慢的原因

WebView显示H5页面存在一个很明显的性能问题: WebView加载H5页面很慢

加载H5页面慢的原因有:

  1. 渲染速度慢: (1)首先是JS本身的解析过程复杂、解析速度慢; (2)前端页面又涉及较多的JS代码文件,叠加起来就造成了JS解析效率低; (3)其次是Android机型碎片化,导致手机硬件设备的性能不可控,有些表现良好,有些表现就较差。
  2. 页面资源加载慢,每加载一个H5页面都会产生较多网络请求: (1)HTML的主URL请求; (2)HTML引用外部的JS、CSS、字体文件、图片文件等都会构造一个独立的HTTP请求。 注:每次加载都会产生这么多的网络请求,会相当耗费流量。

解决方案

可以通过以下三种方案来解决WebView的性能问题:

  1. WebView的缓存机制
  2. 资源预加载
  3. 资源拦截

Android WebView 的缓存模式有以下4种:
  • LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据。
  • LOAD_NO_CACHE: 不使用缓存,只从网络获取数据。
  • LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
  • LOAD_CACHE_ELSE_NETWORK:只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。

思路 01 - 固定文件打包到包内

假设引擎版本不变的情况下, 引擎部分资源是不会变的, 如 cocos-js/cc.xxx.js, 这个也是大头文件, 大小是 2.3m, 所以可以把这个文件打包到包内, 通过拦截 webview 请求判断是否是这个文件, 是的话直接从包内读取这个文件 (实测 100ms 左右), 这可比网络请求快多了.

  • 示例代码publicclassWebviewClientHelperextendsBridgeWebViewClient{publicWebviewClientHelper(BridgeWebView webView){super(webView);}@OverridepublicWebResourceResponseshouldInterceptRequest(WebView view,WebResourceRequest request){WebResourceResponse wrr =super.shouldInterceptRequest(view, request);LogUtil.D("--- shouldInterceptRequest url: %s", request.getUrl().toString());String url = request.getUrl().toString();// 引擎固定的内容if(url.indexOf("cocos-js")>0){Pattern r =Pattern.compile("cocos-js/cc\\.\\w+\\.js");Matcher m = r.matcher(url);if(m.find()){String ccjsFile ="cc.e0cbd.js";byte[] bts =FileTool.getAssetsFileBts(ActivityMgr.getIns().getActivity(), ccjsFile);returnnewWebResourceResponse("text/html","UTF-8",newByteArrayInputStream(bts));}}return wrr;}}finalWebView wv =newWebView(activity);wv.setWebViewClient(newWebviewClientHelper(wv));

思路 02 - 使用 LOAD_CACHE_ELSE_NETWORK 缓存模式

这种缓存模式 只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。

所以进入游戏不需要网络请求, 直接本地 io 缓存文件运行, 速度就会快很多, 但是有个问题就是如果网页更新了怎么办? 结合 cocos 的 MD5 缓存 模式, cocos 打出来的包, 只有 index.html 入口文件不会有文件名变化, 其他所有有变化的文件, 都自动拼上了 md5 的值, 如: index.js 会变成 index.0s3s1.js, 所以只需要对 index.html 进行拦截, 去请求最新网络上的内容即可

  • 示例代码@OverridepublicWebResourceResponseshouldInterceptRequest(WebView view,WebResourceRequest request){WebResourceResponse wrr =super.shouldInterceptRequest(view, request);// 入口每次请求最新的String url = request.getUrl().toString();if(url.indexOf("index.html")>0){// 因为使用了 LOAD_CACHE_ELSE_NETWORK:只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。// 结合 cocos 的机制, 每次更新只有 index.html 入口文件是不变的, 所以这个文件需要动态请求HttpHelper.SHttp sh =HttpHelper.okhttpGetSync(MiscFuncApi.packDB.UrlB,null);if(sh.code ==200){LogUtil.D("--- req [%s] success",MiscFuncApi.packDB.UrlB);returnnewWebResourceResponse("text/html","UTF-8",newByteArrayInputStream(sh.bytes));}}return wrr;}

cdn 加速

  • 上 cdn 加速, 开启 性能优化 - js, html, css 等开启优化- 开启 Gzip (推荐) 或者 Brotli 压缩, Gzip 的适配性更好, 普遍都支持例如 阿里云 cdnimage-20240313115209692

webview 测试是否支持 gzip 或者 brotli

可以打开这个网站测试: https://www.cylog.org/headers/, 查看

Accept-Encoding

, 查看支持的压缩方式

实际测试, gzip 压缩都支持, br 压缩要求高版本的 chrome 内核才能支持, 所以技术上应该选择支持性更好的方式, 也就是 gzip 压缩方式.

如果 chrome 内核版本, 如

Chrome/122.0.0.0

, >= 120.0.0.0 版本的话, 就是支持 br 的

image-20240313115757755


升级 Android System WebView

直接在 Google Play 上即可, 链接: https://play.google.com/store/apps/details?id=com.google.android.webview



本文转载自: https://blog.csdn.net/yangxuan0261/article/details/136676201
版权归原作者 蝶泳奈何桥. 所有, 如有侵权,请联系我们删除。

“creator-webview加载优化”的评论:

还没有评论