首页 > 编程知识 正文

uniapp启动页加载动画,h5制作软件app有哪些

时间:2023-05-05 04:52:14 阅读:146249 作者:4348

移动设备的性能得到了提高,网页的性能体验逐渐被接受。 此外,由于web开发模式的诸多优点(跨平台、动态更新、减体积、无限扩展),APP客户端出现了越来越多的嵌入式网页(为了适应当前流行的说法,以下将所有页面都称为H5。 虽然可能与H5无关,但许多APP已将某些功能模块更改为通过H5实现)。

虽说H5页的性能变好了,但如果不根据目的进行优化,体验就会很差。 主要两种体验:

页面启动白屏时间:打开H5页面需要一系列处理,有白屏时间,体验差。 响应—由于webkit呈现机制、单线程和历史负担等原因,页面更新/交互性能体验不如本机性能体验。 本文先不讨论第二点,只讨论第一点,如何减少白屏时间? 对于使用APP中的几个H5实现的功能模块,如何加速它们的启动,使它们的启动体验更接近本机?

过程为什么打开H5页会增加白色屏幕? 那是因为做了很多事。 也许:

webview -初始化-请求页面-下载数据分析HTML -请求js/css资源-渲染DOM -运行js -请求js数据-分析渲染-下载渲染图像

虽然一些简单的页面没有JS请求数据的步骤,但应该有大多数功能模块。 基于当前用户信息,JS在后台请求和呈现相关数据是正常的开发方法。

常规页面可以在dom渲染后显示雏形。 到目前为止,用户看到的是白色屏幕,在下载渲染图像之前整个页面都不会完全显示。 以秒为单位优化第一个屏幕是缩短这个过程的时间。

前端优化在打开上述单个页面的过程中,有很多优化点,包括前端和客户端。 典型的前端和后端性能优化在桌面时代有最佳实践,主要有:

降低请求量:资源整合、减少HTTP请求数量、minify/gzip压缩、webP、lazyLoad。 33558预解决www.Sina.com/DNS、减少域数量、并行加载和CDN分发。加快请求速度:HTTP协议缓存请求、脱机缓存管理、脱机数据缓存本地存储。缓存:JS/CSS优化、加载顺序、服务渲染、pipeline。 其中,对第一个屏幕启动速度影响最大的是网络请求,因此优化的重点是缓存。 这里重点介绍了针对前端请求的缓存策略。 再细分一下,分为HTML缓存、JS/CSS/image资源缓存和json数据缓存。

HTML和JS/CSS/image资源都属于静态文件,HTTP本身提供了缓存协议。 浏览器可以实现这些协议以缓存静态文件。 具体请参照这里。 总之,是两种缓存。

询问是否有更新:根据If-Modified-Since/ETag等协议询问后端是否有更新。 如果没有更新,则返回到304,浏览器使用本地缓存。 直接使用本地缓存:根据协议中的Cache-Control/Expires字段,确定可以直接使用本地缓存而不要求更新的时间长度。 前端允许的最大缓存策略是,HTML文件每次都询问服务器是否有更新,JS/CSS/Image资源文件使用本地缓存而不要求更新。 JS/CSS资源文件如何更新? 常见的方法是在构建过程中为每个资源文件提供版本号或散列值。 当更新资源文件并更改版本号和散列值时,该资源请求的URL将更改,相应的HTML页面将更新,以请求新的资源URL,同时资源也将更新。

JSon数据缓存可以缓存本地存储请求的数据,并且可以在首次显示时使用本地数据,然后请求更新。 这由前端js控制。

这些缓存策略提供资源文件(如JS/CSS )和用户数据缓存的完整缓存,以便每次都可以直接使用本地缓存数据,而无需等待网络请求。 但不能缓存HTML文件。 对于HTML文件,如果将Expires/max-age时间设置为较长,并长时间使用本地缓存,则来不及更新。 如果设置得较短,则每次打开页面时都必须查询是否有更新,以确定是否使用本地资源。 通常,每次都会要求前端位于此处的策略。 这是用户在较弱的网络中感受到的白色屏幕时间,因此HTML文件的“缓存”和“更新”之间存在冲突。

客户机优化接下来轮到客户机了。 桌面时代仅限于浏览器,H5页面无法进一步优化。 目前,H5页面内置于客户端APP中,客户端拥有更多权限。 因此,客户端可以超越浏览器的范围进行更多的优化。

HTML缓存首先是缓存,然后是客户端,说客户端有更自由的缓存策略,客户端可以拦截H5页的所有请求,自己管理缓存。 上述HTML文件的“缓存”和“更新”之间的冲突可以通过这种策略解决。

客户端拦截请求,在第一次请求HTML文件后缓存数据,第二次不提交请求,直接使用缓存的数据。 什么时候去请求更新? 该更新请求可以在客户端自由控制策略,使用本地缓存打开本地页面后,可以在后台启动更新缓存查询,并在下次打开时启用; 您也可以在APP启动或任何时间在后台请求预更新,以提高用户体验

访问最新代码的几率。

这样看起来已经比较完美了,HTML 文件在用客户端的策略缓存,其余资源和数据沿用上述前端的缓存方式,这样一个 H5 页面第二次访问从 HTML 到 JS/CSS/Image 资源,再到数据,都可以直接从本地读取,无需等待网络请求,同时又能保持尽可能的实时更新,解决了缓存问题,大大提升 H5 页面首屏启动速度。

问题

上述方案似乎已完整解决缓存问题,但实际上还有很多问题:

没有预加载:第一次打开的体验很差,所有数据都要从网络请求。缓存不可控:缓存的存取由系统 webview 控制,无法控制它的缓存逻辑,带来的问题包括: i. 清理逻辑不可控,缓存空间有限,可能缓存几张大图片后,重要的 HTML/JS/CSS 缓存就被清除了。 ii.磁盘 IO 无法控制,无法从磁盘预加载数据到内存。更新体验差:后台 HTML/JS/CSS 更新时全量下载,数据量大,弱网下载耗时长。无法防劫持:若 HTML 页面被运营商或其他第三方劫持,将长时间缓存劫持的页面。

这些问题在客户端上都是可以被解决的,只不过有点麻烦,简单描述下:

可以配置一个预加载列表,在APP启动或某些时机时提前去请求,这个预加载列表需要包含所需 H5 模块的页面和资源,还需要考虑到一个H5模块有多个页面的情况,这个列表可能会很大,也需要工具生成和管理这个预加载列表。客户端可以接管所有请求的缓存,不走 webview 默认缓存逻辑,自行实现缓存机制,可以分缓存优先级以及缓存预加载。可以针对每个 HTML 和资源文件做增量更新,只是实现和管理起来比较麻烦。在客户端使用 httpdns + https 防劫持。

上面的解决方案实现起来十分繁琐,原因就是各个 HTML 和资源文件很多很分散,管理困难,有个较好的方案可以解决这些问题,就是离线包。

离线包

既然很多问题都是文件分散管理困难引起,而我们这里的使用场景是使用 H5 开发功能模块,那很容易想到把一个个功能模块的所有相关页面和资源打包下发,这个压缩包可以称为功能模块的离线包。使用离线包的方案,可以相对较简单地解决上述几个问题:

可以预先下载整个离线包,只需要按业务模块配置,不需要按文件配置,离线包包含业务模块相关的所有页面,可以一次性预加载。离线包核心文件和页面动态的图片资源文件缓存分离,可以更方便地管理缓存,离线包也可以整体提前加载进内存,减少磁盘 IO 耗时。离线包可以很方便地根据版本做增量更新。离线包以压缩包的方式下发,同时会经过加密和校验,运营商和第三方无法对其劫持篡改。

到这里,对于使用 H5 开发功能模块,离线包是一个挺不错的方案了,简单复述一下离线包的方案:

后端使用构建工具把同一个业务模块相关的页面和资源打包成一个文件,同时对文件加密/签名。客户端根据配置表,在自定义时机去把离线包拉下来,做解压/解密/校验等工作。根据配置表,打开某个业务时转接到打开离线包的入口页面。拦截网络请求,对于离线包已经有的文件,直接读取离线包数据返回,否则走 HTTP 协议缓存逻辑。离线包更新时,根据版本号后台下发两个版本间的 diff 数据,客户端合并,增量更新。 更多优化

离线包方案在缓存上已经做得差不多了,还可以再配上一些细节优化:

公共资源包

每个包都会使用相同的 JS 框架和 CSS 全局样式,这些资源重复在每一个离线包出现太浪费,可以做一个公共资源包提供这些全局文件。

预加载 webview

无论是 iOS 还是 Android,本地 webview 初始化都要不少时间,可以预先初始化好 webview。这里分两种预加载:

首次预加载:在一个进程内首次初始化 webview 与第二次初始化不同,首次会比第二次慢很多。原因预计是 webview 首次初始化后,即使 webview 已经释放,但一些多 webview 共用的全局服务或资源对象仍没有释放,第二次初始化时不需要再生成这些对象从而变快。我们可以在 APP 启动时预先初始化一个 webview 然后释放,这样等用户真正走到 H5 模块去加载 webview时就变快了。webview 池:可以用两个或多个 webview 重复使用,而不是每次打开 H5 都新建 webview。不过这种方式要解决页面跳转时清空上一个页面,另外若一个 H5 页面上 JS 出现内存泄漏,就影响到其他页面,在 APP 运行期间都无法释放了。

可以参考美团点评的这篇文章。

预加载数据

理想情况下离线包的方案第一次打开时所有 HTML/JS/CSS 都使用本地缓存,无需等待网络请求,但页面上的用户数据还是需要实时拉,这里可以做个优化,在 webview 初始化的同时并行去请求数据,webview 初始化是需要一些时间的,这段时间没有任何网络请求,在这个时机并行请求可以节省不少时间。

具体实现上,首先可以在配置表注明某个离线包需要预加载的 URL,客户端在 webview 初始化同时发起请求,请求由一个管理器管理,请求完成时缓存结果,然后 webview 在初始化完毕后开始请求刚才预加载的 URL,客户端拦截到请求,转接到刚才提到的请求管理器,若预加载已完成就直接返回内容,若未完成则等待。

Fallback

如果用户访问某个离线包模块时,这个离线包还没有下载,或配置表检测到已有新版本但本地是旧版本的情况如何处理?几种方案:

简单的方案是如果本地离线包没有或不是最新,就同步阻塞等待下载最新离线包。这种用户打开的体验更差了,因为离线包体积相对较大。也可以是如果本地有旧包,用户本次就直接使用旧包,如果没有再同步阻塞等待,这种会导致更新不及时,无法确保用户使用最新版本。还可以对离线包做一个线上版本,离线包里的文件在服务端有一一对应的访问地址,在本地没有离线包时,直接访问对应的线上地址,跟传统打开一个在线页面一样,这种体验相对等待下载整个离线包较好,也能保证用户访问到最新。

第三种 Fallback 的方式还带来兜底的好处,在一些意外情况离线包出错的时候可以直接访问线上版本,功能不受影响,此外像公共资源包更新不及时导致版本没有对应上时也可以直接访问线上版本,是个不错的兜底方案。

上述几种方案策略也可以混着使用,看业务需求。

使用客户端接口

网路和存储接口如果使用 webkit 的 ajax 和 localStorage 会有不少限制,难以优化,可以在客户端提供这些接口给 JS,客户端可以在网络请求上做像 DNS 预解析/IP直连/长连接/并行请求等更细致的优化,存储也使用客户端接口也能做读写并发/用户隔离等针对性优化。

服务端渲染

早期 web 页面里,JS 只是负责交互,所有内容都是直接在 HTML 里,到现代 H5 页面,很多内容已经依赖 JS 逻辑去决定渲染什么,例如等待 JS 请求 JSON 数据,再拼接成 HTML 生成 DOM 渲染到页面上,于是页面的渲染展现就要等待这一整个过程,这里有一个耗时,减少这里的耗时也是白屏优化的范围之内。

优化方法可以是人为减少 JS 渲染逻辑,也可以是更彻底地,回归到原始,所有内容都由服务端返回的 HTML 决定,无需等待 JS 逻辑,称之为服务端渲染。是否做这种优化视业务情况而定,毕竟这种会带来开发模式变化/流量增大/服务端开销增大这些负面影响。手Q的部分页面就是使用服务端渲染的方式,称为动态直出,见文章。

最后

从前端优化,到客户端缓存,到离线包,到更多的细节优化,做到上述这些点,H5 页面在启动上差不多可以媲美原生的体验了。

总结起来,大体优化思路就是:缓存/预加载/并行,缓存一切网络请求,尽量在用户打开之前就加载好所有内容,能并行做的事不串行做。这里有些优化手段需要做好一整套工具和流程支持,需要跟开发效率权衡,视实际需求优化。

另外上述讨论的是针对功能模块类的 H5 页面秒开的优化方案,客户端 APP 上除了功能模块,其他一些像营销活动/外部接入的 H5 页面可能有些优化点就不适用,还需要视实际情况和需求而定。另外微信小程序就是属于功能模块的类别,差不多是这个套路。

这里讨论了 H5 页面首屏启动时间的优化,上述优化过后,基本上耗时只剩 webview 本身的启动/渲染机制问题了,这个问题跟后续的响应流畅度的问题一起属于另一个优化范围,就是类 RN / Weex 这样的方案,有机会再探讨。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。