H5适用场景与效果调优总结

1.H5和原生的对比

1.1 H5的含义

h5指HTML5。是构建Web内容的一种语言描述方式。HTML5是互联网的下一代标准,是构建以及呈现互联网内容的一种语言方式.被认为是互联网的核心技术之一。

HTML5是Web中核心语言HTML的规范,用户使用任何手段进行网页浏览时看到的内容原本都是HTML格式的,在浏览器中通过一些技术处理将其转换成为了可识别的信息。

通俗的讲,H5是一个网页,就像一个很大的容器,里面可以放文本、图片、音视频等基本的流媒体格式的文件。

1.2 从应用场景看H5

既然H5作为广告的一种形式,那么在不同应用场景是有一定区别的,比如:市场策划说它是一些品牌文案,设计师眼中它是平面UI界面,编程开发人员说它是一个HTML网页,推广营销人员说它是一个活动。从创意形式、行业、场景三个维度来划分目前H5的实际应用表现:

创意形式 视频H5 、一镜到底、 全景VR、 快闪、 答题测试 、合成海报、 游戏、 拟态类、 数据表单 、横屏H5、 长页面
行业 互联网/IT、 汽车、 地产/酒店 、金融/银行、 文化/娱乐、 服饰/时尚 、电商/商业、教育/培训、 媒体/政府、 旅游/会展
场景 邀请函、 招聘 、品牌推广、 产品宣传、 婚礼庆典 、活动营销 、节日主题、 数据报告、 微杂志 、微官网、 年会

1.3 H5与原生的对比

对比维度
适配性 适配性较差,不同操作系统需要独立开发,使用不同的语言、SDK、工具、控件 适配性较好,对浏览器适配较为简单
开发成本 开发维护成本较高,尤其需要适配各种机型 开发成本低,只需适配浏览器
版本发布 复杂(已手机APP为例,需要向各个应用商店进行提交审核,然后手动安装更新) 版本发布较为简单,可实时更新,快速迭代
速度与性能 运行速度快 因依赖网络,运行速度无法保证;复杂或精细操作时耗性能,体验差
功能与稳定性 技术相对成熟,API稳定,可使用底层设备功能,如摄像头、蓝牙、重力传感器 处于发展阶段,部分功能无法在浏览器上实现
网络依赖与流量 可离线操作和本地储存,节省流量 弱网环境下加载慢,耗费流量

1.4 H5与原生使用场景分析

维度 场景 技术选择
页面变化频率 页面功能比较固定、变动频率较低 原生
经常有变动和更新的部分页面,更新时不需要发布整个APP H5
页面重要程度 主流程中较为重要的页面,需要良好的体验和稳定性 原生
不影响主流程的辅助性页面(例如说明介绍页) H5
页面使用频率 常用页面,比如首页、个人中心等页面 原生
是某段时间需要的某个活动需求,尝试阶段的业务 H5
页面复杂度 页面内容相对简单 原生
页面内容样式非常丰富,或者页面比较多需要定制化开发的特效时 H5
页面速度和性能 需要调起硬件;需要缓存数据、离线操作;存在大量的前后台数据交互,且需要保持稳定性 原生
页面不涉及复杂功能,可以通过优化方式提升页面性能,让它在某些情况也能接近原生体验 H5

2.H5效果调优

2.1 禁止缓存

笔者开发的页面要在android车机上通过webView展示,由于性能原因需要禁止H5的缓存。

2.1.1 清除H5缓存的原因?

H5页面使用缓存可以提高加载速度和减少资源消耗。但是在某些情况下,可能需要清除缓存。例如页面更新后,希望能够加载最新的页面而不使用旧的缓存。

2.1.2 webView清除H5缓存的方法

方法 说明
webView.clearCache(true) 会清除webView的所有缓存,包括磁盘缓存和内存缓存
webView.clearFormData() 会清除webView的表单数据
webView.clearHistory() 会清除webView的浏览历史记录
webView.clearMatches() 会清除查找结果

除了webView的缓存,H5页面可能还会在应用的缓存目录中存储一些文件,要清除这些文件, 可以使用如下代码:

java 复制代码
// (1)获取缓存目录
File cacheDir = getApplicationContext().getCacheDir();
// (2)删除缓存目录
deleteFiles(cacheDir);
private void deleteFiles(File dir) {
    if (dir != null && dir.isDirectory()) {
        for (File file : dir.listFiles()) {
            deleteFiles(file);
        }
    } else if (dir != null && dir.isFile()) {
        dir.delete();
    }
}

或者如下代码:

java 复制代码
// (1) 在android中获取webview的缓存目录
String cacheDir = webView.getContext().getApplicationContext().getCacheDir().getAbsolutePath();
// (2) 删除缓存目录
File cacheDirFile = new File(cacheDir);
if (cacheDirFile.exists()) {
    deleteDir(cacheDirFile);
}
private static boolean deleteDir(File dir) {
    if (dir != null && dir.isDirectory()) {
        String[] children = dir.list();
        for (int i = 0; i < children.length; i++) {
            boolean success = deleteDir(new File(dir, children[i]));
            if (!success) {
                return false;
            }
        }
    }
    return dir.delete();
}
// (3) 清除webView内存缓存
webView.clearCache(true);

详细请参考:解决Android 清除h5缓存的具体操作步骤android webview 和H5混合开发,webview清空H5已经缓存的数据

2.1.3 H5页面中禁止缓存的方法

通过 Meta标签设置不缓存:

html 复制代码
<!-- 禁止页面缓存 -->
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />

此种方式只对页面有效,对页面上的资源无效。

2.1.4 ngnix设置不缓存

ngnix 复制代码
# 禁用游览器缓存
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires 0;

特别地,针对图片设置不缓存:

nginix 复制代码
location / {            
    root        /app/dist;
    index       index.html;
    try_files   $uri $uri/ /index.html;
}
location ~ .(gif|jpg|jpeg|png|bmp|ico)$ {
     add_header Cache-Control "no-cache, no-store, must-revalidate";
     add_header Pragma "no-cache";
     add_header Expires 0;
 }

或者这样配置:

ngnix 复制代码
location / {            
    root        /app/dist;
    index       index.html;
    try_files   $uri $uri/ /index.html;
    if ($request_filename ~* .*.(?:gif|jpg|jpeg|png)$)
    {
        add_header Cache-Control "no-cache, no-store";
    }
}

设置不缓存之前:

设置不缓存之后:

2.1.5 H5与webView配合实现

笔者的H5使用React开发的,可以通过React实现路由守卫,跳页面通知webview清空缓存:

js 复制代码
const App = () => {
  const location = useLocation();
  useEffect(() => {
    // 调用Android外层方法
    console.log(location);
  }, [location]);
}

2.2 增加页面跳转的过渡效果

2.2.1 对React Transition Group的探索

React Transition Group的官网中给出了结合React Router一起使用的例子,笔者试了一下,怎么也不好使,还在群里问了一波,检查官网给的例子,发现官网给的例子上面加上了用于过渡的样式类名 "page"而笔者的例子怎么也加不上:

2.2.2 使用过渡时enter和exit类名

笔者发现,使用了React Transition Group后,虽然不会出现自定义的class样式类名,但是在页面切换时会出现 exit exit-active enter enter-active enter-done等类名。如下入下图所示:

所以可以使用这些类名来实现过渡效果,CSS代码如下:

css 复制代码
.enter {
  opacity: 0;
  transform: scale(1.1);
}
.enter.enter-active {
  opacity: 1;
  transform: scale(1);
  transition:
    opacity 300ms,
    transform 300ms;
}
.exit {
  opacity: 1;
  transform: scale(1);
}
.exit.exit-active {
  opacity: 0;
  transform: scale(0.9);
  transition:
    opacity 300ms,
    transform 300ms;
}

2.3 禁止页面缩放

禁止页面缩放可以通过meta标签来完成:

html 复制代码
 <!-- 禁止页面缩放 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

user-scalable: no 表示用户不可以缩放网页。

但是使用meta标签对ios10以后的版本不生效,可以通过JS监听手势来实现禁止页面缩放:

javascript 复制代码
document.addEventListener("gesturestart", function (event) {
  event.preventDefault();
});

2.4 禁止复制

html禁止复制可以通过CSS实现,也可以通过JS实现。先看一下CSS的方法:

css 复制代码
* {
  -webkit-touch-callout: none;
  user-select: none;
}

-webkit-touch-callout:none 用于当触摸并按住目标的时候,禁止显示系统默认菜单。默认是指:比如触摸链接元素打开新窗口,触摸img元素就保存图像。

user-select: none 用于禁止用户选择文本内容。

再看一下JS的方法:

如果是鸿蒙系统,使用了上面介绍的方法还不管用的话,可以参考这篇文章里面的方法:鸿蒙系统h5禁止复制功能,鸿蒙复制大坑,要是还不管用的话那就要考虑是不是浏览器把我们加的限制给去掉啦:

参考资料

【1】APP内嵌入H5页面的场景分析

【2】H5在APP内运用的场景

【3】H5的含义

【4】货拉拉 Android H5离线包原理与实践

【5】Android WebView与JS交互全面详解(小结)

【6】React18使用react-transition-group实现路由切换过渡动画

【7】中高级前端必须注意的40条移动端H5坑位指南 | 网易三年实践

【8】H5移动端禁止页面缩放(使用Android和IOS)

【9】记一次WEB、移动端(安卓、IOS)h5页面禁止禁用复制、选中

【10】禁止浏览器缓存的方法

【11】nginx缓存关闭

【12】nginx配置前端不缓存

相关推荐
一颗花生米。2 小时前
深入理解JavaScript 的原型继承
java·开发语言·javascript·原型模式
学习使我快乐012 小时前
JS进阶 3——深入面向对象、原型
开发语言·前端·javascript
bobostudio19952 小时前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
勿语&3 小时前
Element-UI Plus 暗黑主题切换及自定义主题色
开发语言·javascript·ui
黄尚圈圈3 小时前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
浮华似水4 小时前
简洁之道 - React Hook Form
前端
正小安6 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
_.Switch8 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光8 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   8 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发