前言
驻波很久没有写过什么业务实践菜鸟文了,闲来无事,交流一下最近学习的一个C端高频率打开但非用户常驻页的页面秒开率大提升的优化。对于前端而言秒开率指标的重要性肯定是不用介绍的了,驻波在这里不讲秒开率的提升的八股,驻波不是为了优化seo,我们做的是端内承载的H5,只是为了页面打开更快。
静态资源的pre
我们常见通用的<link />
是dns-prefect
与preconnect
,preload
<link rel="dns-prefetch" href="https://xxxxx.com/" />
<link rel="preconnect" herf="https://xxxxx.com/" />
<link rel="preload" herf="https://xxxxx.com/" />
dns-prefetch
它属于 DNS 预解析(DNS Prefetch) ,而不是完整的资源预加载。在移动端网络不稳定的情况下,解析dns路径是十分耗时的操作。而它 仅限于域名解析层面,不会真正下载资源或建立连接。
preconnect
是提前建立 TCP/TLS 连接,用于告知浏览器尽早与指定的服务器建立连接这有助于减少后续从该服务器请求资源时的延迟。当使用 <link rel="preconnect">
提前建立了到目标服务器的连接后,如果该服务器支持并配置了 HTTP Keep-Alive(即持久连接),那么这个连接不会在单个请求完成后立即关闭。相反,它会保持一段时间开放,允许在同一连接上发送多个请求和接收响应。
preload
会尽早获取指定的资源。与 dns-prefetch
和 preconnect
不同,preload
实际上会请求并下载资源,而不仅仅是准备网络连接或解析DNS。这意味着它可以用于加速关键资源(如字体、样式表、脚本等)的加载过程。但如果在首屏加载时使用preload
加载非关键资源,可能会拖慢首屏的加载速度。
prefetch
prefetch —— 预请求。它允许浏览器在后台预先加载用户可能接下来会访问的资源。通过这种方式,当用户实际导航到这些资源时,它们已经被缓存,从而可以立即呈现给用户,减少等待时间并加快页面加载速度。
与dns-prefetch & preconnect
不同,prefetch
也是进行资源获取。与preload不同的是,preload
具有较高的优先级,可能会抢占浏览器的资源加载带宽,影响其他更重要资源的加载,进而影响页面的整体性能。
而prefetch
的优先级相对较低,浏览器会在空闲时间异步加载资源,但是当prefetch的请求过重时,同样的会阻塞主线。
我们都知道对于端内H5的加载顺序一般都是:
该流程明显是串行的,在资源文件体积较大,API 接口较慢等场景下,都会拉低首屏渲染速度,影响用户体验和业务收益。请求在主线程中加载等待回应的过程,会阻塞绘制。即使我们将请求改为prefetch也不能完全解决这个问题。因此联合Server设计出一套新方案:
为了实现 API 请求的提前执行,预取(Prefetch)方案的设计如下:
在 WebView 初始化阶段(甚至更早,如应用通过 Scheme 解析启动时),启动并行启动一个独立的 Worker线程,利用该线程预先发起关键 API 请求以获取业务首屏所需的数据。
通过 WebView 侧的运行时环境(Runtime)与 Worker 建立通信通道,将预取到的数据从 Worker 线程高效传递至 WebView。
业务逻辑层直接利用预取的数据进行首屏内容渲染。
该方案通过并行化预取与 WebView 启动的流程,避免了 API 请求的串行等待,从而显著提升首屏加载速度。
⚠️注:此处的woker并不是我们传统的Web Worker,准确的来说应该是使用JSB能力的混合式开发 Worker。 (React Native Worker)类似的,让调用底层客户端能力直接创建,这样才能的到加快数据的请求。