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 shouldInterceptRequest - https://www.jianshu.com/p/7a237e7f055c
  • Android WebView的性能问题及缓存机制、资源加载方案 - https://bbs.huaweicloud.com/blogs/219777
  • Android WebView H5 秒开方案总结 - https://juejin.cn/post/7016883220025180191

使用 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 左右), 这可比网络请求快多了.

  • 示例代码

    public class WebviewClientHelper extends BridgeWebViewClient {public WebviewClientHelper(BridgeWebView webView) {super(webView);}@Overridepublic WebResourceResponse shouldInterceptRequest(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);return new WebResourceResponse("text/html", "UTF-8", new ByteArrayInputStream(bts));}}return wrr;}
    }final WebView wv = new WebView(activity);
    wv.setWebViewClient(new WebviewClientHelper(wv));

思路 02 - 使用 LOAD_CACHE_ELSE_NETWORK 缓存模式

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

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

  • 示例代码

    @Override
    public WebResourceResponse shouldInterceptRequest(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);return new WebResourceResponse("text/html", "UTF-8", new ByteArrayInputStream(sh.bytes));}}return wrr;
    }
    

cdn 加速

  • 上 cdn 加速, 开启 性能优化
    • js, html, css 等开启优化

    • 开启 Gzip (推荐) 或者 Brotli 压缩, Gzip 的适配性更好, 普遍都支持

      例如 阿里云 cdn

      image-20240313115209692


webview 测试是否支持 gzip 或者 brotli
  • How to enable brotli compression on Android System Webview? - https://stackoverflow.com/questions/65138909/how-to-enable-brotli-compression-on-android-system-webview

可以打开这个网站测试: 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


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2869017.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Java微服务 第二十一章 Java多线程安全与锁

🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 往期热门专栏回顾 专栏描述Java项目实战介绍Java组件安装、使用;手写框架等Aws服务器实战Aws Linux服务器上操作…

大数据分析-基于python的电影票房预测系统设计与实现

一 概要 近些年来,随着电影行业变得越来越热门,也为影院带来不小的票房收入。传统的影院都是依靠个人经验进行排片,但是由于影片的票房收入可能受多种因素的影响,排片多的电影最后的票房会远低于预期值,导致影院因安排…

2024年新算法:基于苦鱼优化算法BFO的城市三维无人机路径规划(复杂地形三维航迹路径规划)

摘要:本文提出了一种利用苦鱼优化算法(Bitterling fish optimization,BFO)来解决城市环境下无人机三维路径规划问题的方法。这种方法将复杂的无人机航迹规划任务转化为一个优化问题,然后运用苦鱼优化算法BFO来解决这个…

前端学习笔记 | WebAPIs(DOM+BOM)

一、作用和分类 1、基本概念 作用:使用JS去操作HTML和浏览器 分类:DOM(文档对象模型)和BOM(浏览器对象模型) html的标签JS的DOM对象 2、获取DOM对象-参数必须加引号 (1)选择匹配的第…

IO控制继电器电路

一、U1光耦: 分离高低压,防止高压干扰,实现电气隔离。 二、D5 二极管 1N4148: 续流二极管,保护元件不被感应电压击du穿或烧坏,以并联的方式接到产生感应电动势的元件两端,并与其形成回路&…

LCR 110

LCR 110 问题 例子 思路 使用dfs便利所有边 代码 class Solution { public:vector<vector<int>> res;void deep(vector<vector<int>>& graph, int id, vector<int>& buf){if(idgraph.size()-1){res.push_back(buf);return;}for(int …

AST解web控制流平坦化

此代码可以解决大部分 while if else 控制流平坦化原理&#xff1a; 先将 if 语句转为 switch 语句&#xff0c;再将 switch 分支合并&#xff0c;最后删除已合并的分支&#xff08;具体看代码&#xff09; 实现效果图 首先安装依赖&#xff1a; npm install babel/parser npm…

uniapp——第2篇:编写vue语法

前提&#xff0c;建议先学会前端几大基础&#xff1a;HTML、CSS、JS、Ajax&#xff0c;还有一定要会Vue!&#xff08;Vue2\Vue3&#xff09;都要会&#xff01;&#xff01;&#xff01;不然不好懂 一、去哪写&#xff1f; 就在【pages】的你的人一个页面文件夹里的【.vue】文…

免费接口调用 招标信息自动抽取|招标信息|招标数据解析接口

一、开源项目介绍 一款多模态AI能力引擎&#xff0c;专注于提供自然语言处理&#xff08;NLP&#xff09;、情感分析、实体识别、图像识别与分类、OCR识别和语音识别等接口服务。该平台功能强大&#xff0c;支持本地化部署&#xff0c;并鼓励用户体验和开发者共同完善&#xf…

火车订票管理系统|基于springboot框架+ Mysql+Java+B/S结构的火车订票管理系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 前台功能效果图 管理员功能登录前台功能效果图 用户功能模块 系统功能设计 数据库E-R图设计 lunwen…

bpmn-js中实现shape的内置属性、节点的默认配置

bpmn-js中使用elementfactory模块来构建一个元素的结构,其构建构成和元素属性的组成可参考:聊一聊bpmn-js中的elementFactory模块https://blog.csdn.net/chf1142152101/article/details/136294768。构建元素的属性会自动帮我们生成一个对应类型的shape的Id,其余属性均为空,…

洛谷P1182数列分段

题目描述 对于给定的一个长度为 N 的正整数数列 &#xff0c;现要将其分成 M&#xff08;M≤N&#xff09;段&#xff0c;并要求每段连续&#xff0c;且每段和的最大值最小。 关于最大值最小&#xff1a; 例如一数列 4 2 4 5 14 2 4 5 1 要分成 33 段。 将其如下分段&#…

Python类属性和对象属性大揭秘!

​ 在Python中&#xff0c;对象和类紧密相连&#xff0c;它们各自拥有一些属性&#xff0c;这些属性在我们的编程中起着至关重要的作用。那么&#xff0c;什么是类属性和对象属性呢&#xff1f;别急&#xff0c;让我慢慢给你解释。 类属性 首先&#xff0c;类属性是定义在类本…

计算机二级Python题目13

目录 1. 基本题 1.1 基本题1 1.2 基本题2 1.3 基本题3 2. turtle画图 3. 大题 3.1 大题1 3.2 大题2 1. 基本题 1.1 基本题1 lseval(input()) s"" for item in ls:if type(item)type("香山"):s item print(s) 1.2 基本题2 import random random.se…

学习使用js获取当前ip地址的方法,使用第三方API获取ip地址

学习使用js获取当前ip地址的方法,使用第三方API获取ip地址 使用 DNS 查询使用第三方 API 使用 DNS 查询 DNS 是一种用于解析主机名为 IP 地址的系统。可以使用 JavaScript DNS 查询来获取本机IP地址。下面是如何使用 JavaScript 进行DNS查询的示例代码。 <p class"loc…

腾讯云2核4g服务器能多少人在线?2核4G云服务器支持多少并发?

腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户同时在1秒内打开网站&#xff0c;并发数为10&#xff0c;经阿腾云测试&a…

嵌入式开发基础总结

学习目标 1.了解嵌入式开发 2.开发环境的搭建 3.Linux操作系统的基本操作 一、了解嵌入式开发 以应用为中心&#xff0c;以计算机技术为基础&#xff0c;软硬件可裁剪&#xff0c;适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。 1.嵌入式可以干…

[蓝桥杯练习题]确定字符串是否包含唯一字符/确定字符串是否是另一个的排列

确定字符串是否包含唯一字符 #include<bits/stdc.h> using namespace std; int main(){ios::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr);map<char,int>m;string s;cin>>s;for(int i0;i<s.size();i){if(isalpha(s[i]))s[i]tolower(s[i]);if(…

第十三届蓝桥杯(C/C++ 大学B组)

目录 试题 A: 九进制转十进制 试题 B: 顺子日期 试题 C: 刷题统计 试题 D: 修剪灌木 试题 E: X 进制减法 试题 F: 统计子矩阵 试题 G: 积木画 试题 H: 扫雷 试题 I: 李白打酒加强版 试题 J: 砍竹子 试题 A: 九进制转十进制 九进制正整数 ( 2022 )转换成十进制等于多…

C语言例:设 int x=100; 则表达式 x++>100?x+20:x+10 的值

代码如下&#xff1a; #include<stdio.h> int main(void) {int x100, y;y x>100?x20:x10;printf("表达式x>100?x20:x10 的值为&#xff1a;%d\n",y); //111printf("x %d\n",x); //101return 0; } //三目逻辑运算符&#xff0c;条件…