移动端本地 H5 秒开
一、为什么 H5 体验糟糕
为什么打开一个 H5 页面会有一长段白屏时间?因为它做了很多事情,大概是:
初始化 webview -> 请求页面 -> 下载数据 -> 解析HTML -> 请求 js/css 资源 -> dom 渲染 -> 解析 JS 执行 -> JS 请求数据 -> 解析渲染 -> 下载渲染图片
一般页面在 dom 渲染后才能展示,可以发现,H5 首屏渲染白屏问题的原因关键在于,如何优化减少从请求下载页面到渲染之间这段时间的耗时。
二、如何优化
上述打开一个页面的过程有很多优化点,包括前端和客户端,常规的前端和后端的性能优化已有前辈们总结过最佳实践,主要的是:
降低请求量:合并资源,减少 HTTP 请求数,minify / gzip 压缩,webP,lazyLoad。
加快请求速度:预解析DNS,减少域名数,并行加载,CDN 分发。
缓存:HTTP 协议缓存请求,离线缓存 manifest,离线数据缓存 localStorage。
渲染:JS/CSS优化,加载顺序,服务端渲染模板直出。
一般情况下,我们只要对照这个列表,对比差异就基本能搞定绝大部分前端性能问题了。不过我们在里面仔细再分析下,对首屏启动速度影响最大的就是网络请求,包括请求 HTML、css、image 等静态资源和展示数据的请求。
那么将 H5 相关页面和资源打包到客户端中,然后客户端将展示数据传给页面,通过webView加载展示,这样几乎不需要网络请求,webview 只要渲染页面,执行js即可,这样体验岂不是很完美?
三、具体怎么实现?
整体思路看起来比较清晰,但是其中有几个关键问题需要解决:
3.1 本地H5页面如何和native通信:
本地 H5 页面如何和 native 通信的方式基本有三种:jsapi、URL Scheme 和 字符串替换。具体不同方式适合使用场景有所不同:
jsapi :客户端提供接口,注入 API让 Javascript调用,直接执行相应Native代码,适用于需要通过交互,进行数据请求的场景
URL Scheme : Web 端发送 URL Scheme 请求,之后 Native 拦截到请求并根据 URL Scheme 及所带的参数进行相关操作。适用于进行页面跳转的场景。
字符串替换: 客户端读取本地 H5后,通过对 H5 中的约定的标记位进行字符串替换,然后加载展示页面。适用于没有复杂交互,只通过页面渲染数据的场景。
3.2 如何开发调试和维护
开发本地 H5 模块,很容易想到在本地通过模拟数据开发,然后将 H5 给到各客户端打包后进行联调。然而这样的方案实现起来十分繁琐,原因是 H5 资源给到客户端打包时很分散,不统一,管理困难。
那么我们改进一下,将使用本地 H5 实现模块的页面建立一个统一 git 仓库,IOS 和 android 客户端通过git submodule
将本地 H5 的git 外链到项目中,这样客户端中的资源就可以统一管理,解放了每次都手动繁琐的替换打包工作。
但是这种方法其实也并不完美,H5 代替原生实现的优势,一个在于开发成本低,另一个在于 H5 可以更加快捷的更新迭代,如果打包在客户端中的H5 页面就像客户端一样,没法快速更新了。很容易想到将 H5 资源给到后台,客户端按照业务模块预下载整个离线包,离线包根据版本做增量更新。这种的方案,就可以较好的解决上面的问题了。
四、细节优化
解决了上面的问题,本地 H5 确实可以达到秒开的加载速度,不过要达到和客户端一样的体验,还需要配上一些细节优化:
预加载 webView,预拉取数据
在联调本地 H5 页面过程中,发现首次加载页面时间比后续打开时间都慢很多,原因预计是 webView 首次初始化时候需要启动资源和服务较多,于是尝试客户端在预先初始化 webView 方案,果然这样第一次打开页面时候就变快了。同时为了 H5 在第一次打开时能直接展示数据,客户端在页面打开前就预拉取数据并缓存,这样来减少请求数据时间导致的白屏。
屏蔽webview HTML 内容自动识别
在 IOS webView 中默认会自动检测 HTML 中手机号、email、地址格式并标记。
解决方法:通过添加 meta 头来禁止默认行为
<meta name="format-detection" content="telephone=no,email=no,adress=no">
点击延迟
在WebView中,click通常会有大约300ms的延迟(同时包括链接的点击,表单的提交,控件的交互等任何用户点击行为)。
解决方法:使用fastclick/touchend一般可以解决这个问题。
国际化
客户端内的 H5 也需要国际化,前端国际化方案有很多,通常情况下都是根据项目框架选择相应的国际化插件,然而在本地 H5 的页面中,再引入额外插件会增加客户端打包大小,略显冗余。适合自己的才是最好的,这里采用了一种适合轻量级的国际化方案。
1.提取语言文案
2.页面和 js 中引用提取的文案
3.根据配置切换语言方案
$('.i18n').each(function() {var key = $(this).attr('name');$(this).html(language[key]);});var language = getQueryVariable('en') ? i18n.en : i18n.zh
WKWebView 兼容
WKWebView 性能比 UIViewView 性能好很多,所以客户端开发一般都推荐使用 WKWebView。
但是使用 WKWebView 加载本地的 HTML 时也有一些兼容问题,在 iOS8 不能在 HTML 文件中引用本地的 css 或者 js 或者图片文件,IOS8 以上的是正常的,可以引用远程资源。为了兼顾兼容性和秒开体验,所以做降级方案,通过系统版本动态加载JS, IOS8 使用网络资源,IOS8 以上使用本地资源。
还有在iOS8中,使用一些远程的 cdn 的 css 或者 js 文件,必须注意在引用标签上加上 charset属性,不然 css 和 js 库将会乱码
五、最后
从前端优化,到客户端缓存,到离线包,到更多的细节优化,做到上述这些点,H5 页面在启动上差不多可以媲美原生的体验了。
总结起来,大体优化思路就是:减少一切网络请求,做好预加载和缓存,尽量在用户打开之前就加载好所有内容。这里有些优化手段也要根据项目和实际需求来评估,需要跟开发成本和效率权衡。上述讨论的仅针对功能模块类的单页面 H5 页面秒开的优化方案,其他一些交互较复杂的 H5 页面可能并不适用,还需要视实际情况和需求而定。
参考文献
WebView性能、体验分析与优化:https://tech.meituan.com/WebViewPerf.html
参考:https://mp.weixin.qq.com/s/0OR4HJQSDq7nEFUAaX1x5A
移动端本地 H5 秒开相关推荐
- Android Webview H5 秒开方案实现
本文首发于微信公众号「玉刚说」 原文链接:Android Webview H5 秒开方案实现 前言 现在许多app都嵌入了H5页面, 然而WebView加载速度慢这个问题却一直影响着用户的体验, 所以 ...
- 得物 App H5秒开优化实战
文/XU MING 关注得物技术,做最潮技术人! 背景 H5秒开优化是一个老生常谈的问题,于是得物技术联合了客户端和H5共同发力.本文将逐步介绍如何通过客户端 + H5 的优化手段(1+1>2) ...
- 移动端开发——APP端上H5容器化建设
1. 背景 当前移动端和前端的结合愈加紧密,尤其是在偏重活动运营的电商App中,受制于App版本审核,具备研发成本低.可灵活发布等特点的H5页面受到青睐,使其在APP端上承接了越来越多的业务.然而H5 ...
- vue 调用pc端本地摄像头、麦克风实现拍照、录视频、录音 并上传到服务器指定树文件夹
vue 调用pc端本地摄像头.麦克风实现拍照.录视频.录音 并上传 自己写blog只是为了下次方便使用 过程确实很烦 ,自己摸索加各大网站cv查看 可以直接使用 1.调用摄像头拍照 录屏 首先是npm ...
- uni-app 多端本地图片转base64 本地图片转base64
文章目录 uni 适配多端 本地图片转base64 函数 多端转换统一函数 使用 h5本地图片转base64 app本地图片转base64 微信小程序本地图片转base64 uni 适配多端 本地图片 ...
- app能不能跳转外部h5_利用条件编译在app端使用h5+(网页跳转 实例)
利用条件编译在app端使用h5 在 uni-app 中可以使用条件编译发挥各自平台的特色能力,h5+ 对象为 plus,在js中我们可以通过条件编译调用它 ^_^ 语法格式 // #ifdef APP ...
- 移动端,h5页面1px 1像素边框过粗解决方案
移动端,h5页面1px 1像素边框过粗解决方案 参考文章: (1)移动端,h5页面1px 1像素边框过粗解决方案 (2)https://www.cnblogs.com/uimeigui/p/12150 ...
- 移动端手机h5上传图片旋转90度
移动端手机h5上传图片会旋转90度的问题 h5页面调用相机正常情况下都是正常的,但是有些手机横着照相的时候就会正常的,iphone正确的拍照方式是横屏的,而用户往往是竖屏拍照上传的,就相当于照相机反转 ...
- Android端本地音乐播放器(一)---前言
前言: 2018时的记录:大概一周多以前(现在是2018.11.26 15:24)android平台开发的课程结束了,要写大作业,最后决定写这个音乐播放器,因为老师在课堂上讲的例子也是这个,前面的 ...
最新文章
- C/C++实现sleep函数
- Lua的require使用
- 我做 Fiori 开发经常使用的几个系统,不同的 SAP UI5 版本
- chrome v46渲染partial html内容的一个问题
- galaxy s8 android pc,手机秒变PC!三星Galaxy S8桌面模式曝光
- Linux下使用wget下载FTP服务器文件
- paip.myeclipse7 java webservice 最佳实践o228
- 芯烨打印机api密钥php,php连接芯烨云打印机 (php demo)
- 手机图片怎么转文本?
- 计算机中冰点还原快捷键,冰点还原软件如何使用,小编教你如何使用冰点还原软件...
- 第五套人民币是大众收藏的机会
- Java Files.walk示例
- 【MacOS】Hammerspoon-sugood多合一效率工具,新增状态栏显示系统信息(CPU/内存/硬盘/网速)-v0.1.7
- 用计算机打字用哪种方法最好,打字高手练习(快速练习好电脑打字的方法)
- java使用mybatis 调用存储过程返回一个游标结果集
- 字节跳动疯狂扩张:IPO前的最后一战
- 今日金融词汇---仓位,是什么?
- 基本电路概念(二)什么是电容?
- Linux运维常用工具软件
- 万能查询,总有你想要的!
热门文章
- MacTeX的使用心得
- 深度学习:乳腺x检测
- Matlab中关于复杂函数二重积分的问题
- Forest - 轻量级HTTP客户端框架
- logiscope系列-使用说明书
- 微信小程序新版canvas绘制图片方法
- 算法 64式 7、搜索算法整理_第1部分_1到15题
- 枚举.........
- Excel函数 - 提取月份,转换月份格式
- 报错:此操作系统版本不支持此选项。管理员应使用“打开或关闭 Windows 功能”对话框、“服务器管理器”管理工具或 dism.exe 命令行工具安装/卸载包含 IIS8 的 ASP.NET 4.5