23 白屏:如何优化APP内前端白屏时间?
你好,我是三桥。
上一节课探讨的各种优化方案,都是为了减少TTFB指标。这节课,我们来说说白屏的问题。
在任何情况下,网页的首字节(TTFB)时间都会有一个具体的指标值,只有资源类文件可能会因为浏览器的缓存机制而为0。
也就是说,无论距离有多远,前端应用的HTML主文档都必须通过服务器,才能送达用户的浏览器。这个过程需要一定的时间。
白屏时间
由于请求主文档需要时间,这就导致我们在移动设备上访问前端应用时,常常会出现短暂的浏览器白屏现象。
以极客官网为例,我们可以通过使用Chrome开发者工具记录的屏幕截图来观察这种白屏现象,如下图所示。
从上图可以明显看出,当用户使用4G网络访问官网首页时,超过1秒才能真正看到页面内容。在这1秒内,用户只能在白屏状态下等待。如果用户没有耐心,他们可能就马上关闭浏览器。
图中的红框表示开始看到页面内容的时间点,下面对应的是FCP(首次内容绘制)指标,这表示开始绘制页面内容。
因此,我们可以得出一个结论,白屏时间近似等于FCP时间。而FCP时间是由首字节时间(TTFB)和浏览器绘制时间组成的。
从另一个角度来看,TTFB会影响用户打开网页时的白屏时间。TTFB越大,白屏效果越明显,用户等待时间越长。
要真正解决白屏时间问题,我总结出了两种解决方案:PWA方案和APP预下载方案。它们都可以有效解决白屏等待时间过长的问题。
PWA实现方案
日本的最大电商Rakuten实现了网店的PWA支持,把Web网站变成了可安装Web应用,结果在一个月内访问者留存率就提高了450%。
印度的一家在线旅游预订网站,通过构建一个全功能的PWA应用,成功提高了60%的转化次数,登录用户数也增加了20%。
首先,让我们先来解释一下什么是PWA。
渐进式Web应用程序(Progressive Web App,简称PWA)是一种结合了Web和原生应用程序的技术,提供了类似于原生应用程序的体验。
这些技术包括Service Worker、Web应用清单、HTTPS协议、IndexedDB数据库、推送通知、APP Shell模式等。它的最大特点就是支持离线访问、推送通知等功能。
PWA的核心是Service Worker,它是一种可以控制页面加载和行为的独立脚本。它能处理资源缓存,实现离线访问和处理推送通知等功能。
注册Service Worker线程,可以参考下面的代码。
// 注册 Service Worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js')
.then(registration => {
console.log('Service Worker 注册成功:', registration);
})
.catch(error => {
console.log('Service Worker 注册失败:', error);
});
});
}
我们能从概念上得出一个结论,就是用户在访问Web应用时,可以利用离线访问和资源缓存的能力,使得主文档、资源、数据并不一定非得通过网络请求才能获取。这样,用户就可以在TTFB接近0秒的速度下打开页面。
所以,集成了PWA能力的Web应用实际上优化了白屏的等待时间,无论用户是在网速较慢还是离线状态下,都能够快速加载Web应用。
那如果用户处于无网络状态呢?虽然无法向服务器发送请求获取数据,但我们可以设置提醒用户的功能,而不是让应用静默失败或崩溃。
不过,PWA对应用场景有特定的条件要求。首先,也是最关键的是Web浏览器需要支持Service Worker,否则无法实现离线应用和资源缓存。
其次,PWA最适合帮助网络较慢地区的移动用户更快地体验Web应用,从而降低用户退出率。
如果要使用PWA解决白屏问题,需要考虑市场环境因素。
比如,PWA在海外市场发展多年,用户习惯使用App和移动浏览器访问产品,如Chrome。如果你的产品是面向海外市场,PWA是一个不错的选择。
而如果是在中国市场,用户已经习惯了使用微信、支付宝、抖音等超级App,这类App满足了用户的大部分需求,那就很少会有用户通过浏览器方式解决日常需求。简单来说,中国市场的移动Web应用带来的价值有限,大部分产品更关注流量、留存、转化和商业模式。
所以,对于中国市场的前端应用,我建议不要考虑PWA模式来优化白屏问题,而是考虑另外一种优化方案,App预下载。
APP热更新方案
我曾在UC浏览器负责过一个前端合作项目,这个项目的目标是让三星手机在他们的默认浏览器中嵌入印度和印尼的头条信息流,并允许他们自主控制这个页面。
这是一个有趣的小项目。因为三星浏览器希望我们提供支持获取信息流数据纯HTML前端资源文件,而不是URL地址。
这就非常考验前端同学的能力了。在当时的技术条件下,很多前端项目还是多页面工程项目,有些甚至是基于服务器渲染的项目。要做到既能提供HTML文件,又能动态获取头条信息,是一个很大的挑战。那么,如何开发出一个能支持动态数据的HTML页面呢?
如果以现在的技术来看,我相信任何前端同学都能给出明确的答案:SPA单页应用。
当时,关于SPA的应用在前端技术社区中刚刚开始流行,相关详细方案很少。幸运地是,React和Vue两个框架也在这个时候逐渐流行起来。
我对比了两个框架,React在海外技术社区讨论得很活跃,但是中文文档和教程非常少,学习成本很高。另一方面,Vue虽然只是发布了0.6的beta版本,但是它的优点就是轻量、简单易懂,我们很快就用Vue搭建了一个SPA应用。
所以最终,我决定使用Vue技术栈作为该项目的基础框架。
好,第二个问题来了,我们如何向三星浏览器提供HTML文件呢?
我们与三星的技术团队进行了沟通,最后决定我们将前端资源打包,然后提供一个可访问的URL地址,三星浏览器会定时从这个地址拉取资源。
三星浏览器拿到资源包后,会解压并把前端资源保存在用户的手机文件系统中。当用户打开浏览器时,浏览器就可以直接打开这个本地的HTML文件。
项目上线后,用户打开三星的浏览器,信息流页面会瞬间打开,并获取头条数据,完全没有白屏,用户体验就像App的原生效果一样。
下面,我们通过一个完整的关系图来理解这个项目的技术流程。
从上述案例中,我们得出一个结论:如果提前将前端资源下载到用户本地并加载本地HTML文件,TTFB指标值几乎为0,白屏效果立即消失。
但是,这种方案有一定的局限性。它要求App具备前端资源热更新的能力,才能实现前端资源下载本地。
前端资源热更新是一种无需重新安装App就可以更新前端资源的方式。这种方法的主要优点是它可以在用户无感知的情况下进行,从而提供更流畅、更友好的体验。
因此,第二个优化白屏时间的方案是, 在App支持热更新的同时,结合前端SPA单页面开发模式,最后打包一份可以在本地运行的前端代码,并下载到App内本地运行。具体的设计图如下。
我们从图中可知,这个方案有两个关键点。
第一个是 App打开本地HTML。
众所周知,App可以通过WebView打开前端H5页面,通常是以HTTP请求访问为主要方式。这种方案的优点是接入快、维护简单。
但是这种方案也存在问题,加载H5需要时间,而且很明显地感知到白屏效果。实际上,WebView不像普通浏览器,它是一个简化版的浏览器,没有针对Web进行过多的性能优化。
要解决白屏问题,我们必须减少TTFB时间,最好的方案就是打开本地HTML,减少网络传输过程。但是,这种方法需要App和前端配合开发,甚至还需要前端项目支持两种打开方式。
有些同学可能会好奇,应该如何选择这两种打开方式呢?
如果是从零开始的新产品,最好的阶段就是使用http请求方案,因为无论从产品功能还是技术角度看,都存在很多不稳定因素。这种情况下,使用http方案可以快速试错,降低维护成本。
而减少白屏效果,提高用户体验,可以帮助产品建立口碑,增加用户量。因此,当产品相对稳定时,我们可以从技术需求的角度推动技术升级。
第二个是 App热更新,它不仅仅是下载资源包过程这么简单。
下载资源包只是最后的步骤。真正的难点是何时下载以及如何判断和更新资源包。让我们逐一讨论。
首先,我们来看下载的时机。在最初的案例中,用户打开三星浏览器的那一刻,首屏画面就会出现,后台就开始尝试拉取资源包,如果是用户第一次打开浏览器,资源包一定会被下载到本地。
实际上,这种方案是在用户主动打开App时尝试拉取最新资源包。那么问题来了,每次都要拉取资源包吗?
答案是不。这就引出了第二个问题,如何判断资源包有变更。
很简单,更新了资源包后,它的属性肯定会有变化,比如文件大小、上传时间、更新时间、修改时间等等。只要我们知道这些属性的变更,就能判断出可能有新版本。
MD5是一种常见的哈希函数,它会生成一个特定的哈希值。无论资源包发生任何内容变化,这个哈希值都会发生改变。
因此, 判断是否需要更新资源包就是看资源包的哈希值是否有变。如果变了,就下载更新,如果没变,就忽略。
最终,这个两个关键功能的实现过程如下流程图所示。
好了,有了设计图和流程图,真正的功能实现就是对着键盘敲代码了。你看,没有实现不了的功能,只有不想实现的人。
目前,热更新方案已经成为主流App的基本功能,很多你看到的,大概率都是使用H5实现的。例如,UC浏览器、微信App、支付宝App都有大量采用了本地H5页面来承载业务需求。
至此全链路优化中的TTFB优化,已经探讨完毕。从这些内容来看,链路日志并没有提供太多帮助,但我们要明白,日志是用来分析问题的,我们需要数据分析才能给出有效的解决方案。
总结
总结一下,在这节课中通过我经历的项目案例,总结出了两套优化白屏时间的方案。虽然TTFB指标和白屏时间有很多种不同优化方法,但优化的思路基本上是一致的。
PWA利用前端技术实现模拟原生应用的效果,但在国内市场并不常见。然而,服务于App的前端H5项目可以利用浏览器支持打开本地HTML的功能,实现快速打开页面,无需实时网络传输。
前端全链路优化的主要目标是解决用户体验问题,只要我们使用了HTTP请求的方案,TTFB指标就会有耗时,即使速度再快,白屏时间也无法避免。因此我们必须时刻关注TTFB指标,不要让它成为产品性能的瓶颈。
思考题
现在,给你布置两道思考题。
第一,观察一下常用的超级App内的页面,看看哪些是基于H5实现的?
第二,尝试对你的前端项目进行编译,生成本地可运行的代码,看看是否有惊喜?
欢迎你在留言区和我交流。如果觉得有所收获,也可以把课程分享给更多的朋友一起学习。我们下节课见!