50万奖金+官方证书,深圳国际金融科技大赛正式启动,点击报名 了解详情
写点什么

移动端本地 H5 如何做到秒开?

  • 2019-10-29
  • 本文字数:2520 字

    阅读完需:约 8 分钟

移动端本地 H5 如何做到秒开?

企业微信移动端项目中有需求要展示数据趋势的可视化图表,经过调研,最终决定以单页面 H5 来完成,对 APP 里的一些使用 H5 实现的功能模块,一般体验都比原生差,那么怎么提高 H5 加载速度?优化 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 页面可能并不适用,还需要视实际情况和需求而定。


本文转载自公众号云加社区(ID:QcloudCommunity)。


原文链接:


https://mp.weixin.qq.com/s/DEOP6i0vFWoE-eZGGDTkKA


2019-10-29 10:553681

评论

发布
暂无评论
发现更多内容

ChatGPT被开发者嫌弃?真正的用户群体出现

Onegun

人工智能 ChatGPT

行业大咖云集 多元观点碰撞 OpenHarmony技术峰会与你相约深圳

叶落便知秋

OpenHarmony

openGauss内核分析(五):统计信息与行数估计

存储拆分后,如何解决唯一主键问题?

小小怪下士

Java 程序员 后端 uuid

【漏洞发现】|多个严重CVE漏洞被发现,系内存类安全漏洞

云起无垠

漏洞 Fuzzing

AI不仅造就了ChatGPT,也重新定义了模糊测试

云起无垠

模糊测试

从混沌到清晰,阿里全球商品类目域建设思考

阿里技术

全球化技术能力

要想随时编码即刻创新,这个工具你需要一个

华为云开发者联盟

云计算 后端 华为云 企业号 2 月 PK 榜 华为云开发者联盟

openGauss内核分析(四):查询重写

SpringBoot与Loki的那些事

Java Spring Boot 框架

阿里云 EMAS & 魔笔 :1月产品动态

移动研发平台EMAS

阿里云 App 低代码 移动研发

万物皆可集成资源包!低代码集成系列一网打尽

葡萄城技术团队

基于图数据库 NebulaGraph 实现的欺诈检测方案及代码示例

NebulaGraph

图数据库 反欺诈 安全风控

数仓专家面对面 | 为什么我选择GaussDB(DWS)

华为云开发者联盟

数据库 后端 华为云 企业号 2 月 PK 榜 华为云开发者联盟

C#/VB.NET 如何在 Word 文档中添加页眉和页脚

在下毛毛雨

C# .net word文档 页眉页脚

一文详解SpEL表达式注入漏洞

华为云开发者联盟

开发 华为云 企业号 2 月 PK 榜 华为云开发者联盟

Java实现Http多次请求复用同一连接

Java HTTP

如何使用 NFTScan NFT API 检索单个 NFT 资产

NFT Research

API NFT

【我和openGauss的故事】openGauss的WDR报告解读

国内开源生态发展现状:开源基金会与开源组织 | 雨林开源行

开源雨林

Linux 开源 基金会 OSPO

云小课|MRS基础原理之Flink组件介绍

华为云开发者联盟

大数据 华为云 企业号 2 月 PK 榜 华为云开发者联盟

【ECCV 2022】TeSTRa:稳定的流式视频识别

Zilliz

计算机视觉

兴业银行正式加入openGauss社区

GitHub神坛变动!10W字Spring Cloud Alibaba笔记,30W星标登顶第一

Java 微服务 Spring Cloud

openGauss社区十一月运作报告

提升企业管理效率 从权限控制开始

力软低代码开发平台

TiDB Serverless 和技术生态全景

PingCAP

TiDB

设计原则 — L 里氏替换原则

Lemoon Can

SOLID 设计原则 SOLID原则 里氏替换原则

实用指南:如何在Anolis OS上轻松使用 Kata 安全容器?

OpenAnolis小助手

容器 安全 操作系统 龙蜥社区 kata

妙啊,空结构体还能这么用?Go语言的结构体看这篇就够了

王中阳Go

Go golang 高效工作 学习方法

移动端本地 H5 如何做到秒开?_文化 & 方法_腾讯Bugly_InfoQ精选文章