前端优化系列 - 初始化的性能影响分析

本文涉及的产品
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

前言

数据表明,即使在资源有缓存的情况下,页面首次访问的耗时也是非首次访问的两倍。

为什么首次访问这么耗时呢,时间去哪里了?本文详细分析页面首次访问耗时的原因。

常见的初始化

我们先看看打开一个页面,需要经过那些流程。可能会包括,外壳初始化,内核初始化,创建WebView,创建Renderrer进程,初始化V8 JS引擎,初始化IPC,初始化CC,初始化网络库,初始化文件系统,初始化数据库,启动ServiceWorker线程,DNS解析,创建网络连接,页面服务器初始化,等等。这些流程前端一般是看不见的。

在讨论具体的耗时之前,我们先约定,下文所有的数据都是基于Nexus 5手机。不同的手机的性能数据差异极大,一些高端手机(比如,iPhone X),性能可能是中低端机的好几倍。

外壳初始化

我们先看看浏览器外壳的初始化,用户点击桌面图标启动浏览器,浏览器会进入一个状态机,按步骤初始化各个模块,很多模块的初始化会涉及网络,文件IO,JNI,等等操作,这些都会有一定的耗时。

当然,全新安装首次启动,外壳初始化的过程中,一般最耗时的是加载SO和JAR,其中使用DexClassLoader去加载JAR文件,在一些中低端机器,特别是Android 5.0以前的系统,耗时是以秒计算的,有些甚至可以达到10秒。非全新安装首次启动,加载SO和JAR的耗时会大幅下降,大概在500ms。

我们为什么需要关心浏览器启动的耗时呢?一些场景下,用户通过扫码或者点击桌面图标去访问页面,这个过程就会包含浏览器的启动流程,我们有必要了解这其中发生了什么。

对于内置浏览器内核的App,比如,支付宝,手淘,情况又是怎样的呢?我们这边暂时没有支付宝和手淘的启动性能数据,但模块初始化,加载SO和JAR,这些流程都会有,时间不会很小。

在外壳初始化耗时方面,有没有一些比较好的解决办法呢?

最好的办法就是进程保活,现在国内很多手机厂商都会给微信,支付宝,等超级App去进程保活,用户在任务列表杀掉了应用,其实进程还在。

如果是多进程的情况,可以提前创建进程,比如,微信和支付宝的小程序,用户访问时可以直接使用预创建的进程。

内核初始化

我们再来看看内核的初始化,与外壳的初始化类似,内核的初始化也需要加载SO和JAR,创建WebView和初始化各个功能模块。

在创建WebView方面,全新安装首次创建约1秒,非全新安装首次创建约300ms,第二次创建约15ms。

首次创建Renderrer进程,初始化IPC,初始化CC,这些耗时在百毫秒的级别;

V8 引擎相关的初始化耗时也在百毫秒的级别,其中首次NewContext要20ms。

总的来说,首次访问加载SO和JAR一般需要500ms,创建WebView和走完内核流程一般需要消耗500ms,也就是说,提前初始化内核和预创建WebView加载一个URL,跑一趟内核流程,可以带来约1秒的收益。

业务初始化

在页面加载的过程中,内核会有很多回调通知外壳,这些回调的处理上是否可能存在性能问题呢?

我们发现,在一些App上,一些接口很可能会出现性能问题,比如,onPageStarted,shouldOverrideUrlLoading,shouldInterceptRequest。

这些接口为什么会出现性能问题呢?一般很多应用会在首次onPageStarted回调时执行复杂的业务逻辑,比如,初始化一些统计模块,进行JS注入,等等。需要说明的是,onPageStarted并不是同步接口,为什么也会有影响呢?因为它是在UI线程执行的,长期占用UI线程,会对内核有较大的影响,内核很多操作需要抛转到UI线程去处理,比如,ServiceWorker线程启动就有抛转UI的过程,在UI执行完之前,它只能等待。

shouldOverrideUrlLoading 是客户端拦截请求的关键接口,内核会同步等待,很多应用会有比较复杂的拦截规则。

shouldInterceptRequest 是客户端离线包的关键接口,内核会同步等待,很多应用会在这个接口首次回调时去解压离线包和初始化离线模块。

在一些实际应用中,优化这些回调的处理,可以给全部H5页面带来 10% 以上的性能提升。

ServiceWorker初始化

ServiceWorker是PWA的关键技术,它具有非常强大的能力,Fetch,Cache,Push和Add to home screen,能让前端开发者非常灵活的操控页面缓存。

同时,它也是有比较大的初始化成本的,比如,ServiceWorker线程启动平均要200ms,而每次访问页面,一般ServiceWorker线程至少都需要启动一次。当然,Chrome也在不断优化这块的耗时,最终预计能优化到100ms以内。

网络初始化

在网络初始化方面,一般内核网络库的初始化并不太耗时,耗时的是DNS和Connection。

用户首次访问,一般都需要去进行DNS解析和创建连接,而在后续访问时,一般都可以用上缓存或者预连接。

DNS解析,一般耗时在200ms以上,创建HTTP连接,一般耗时也在200ms以上,而创建HTTPS连接则需要600ms以上。

也就是说,用户首次访问时,如果不能提前创建连接,从性能的角度来说,是非常危险的。

这个方面我们的建议是,使用HTTPDNS提前解析和缓存DNS,提前创建连接(比如,用户点击时)。

浏览器也有这方面的优化,比如,在加载主文档时,提前发起子资源的预连接,但在一些托管网络库的应用来说,这些策略可能不会生效。

服务器初始化

页面服务器和资源服务器,是否也需要初始化呢?一般也是需要的,比如,页面访问过之后,页面服务器也会有一些缓存,用户再次访问时可以直接使用缓存而无需走完整的流程,但这些缓存应该是大部分用户都能共享的,所以实际影响不好评估。资源服务器也一样,比如,图床,很多是按用户手机屏幕和网络类型来返回不同图片的,用户访问过就会放到CDN缓存中。

暂时未有数据表明服务器初始化对页面整体性能产生明显影响。但我们有另外一份数据,在一个业务中,预创建WebView提前加载一次模版页面,能让全网平均性能优化100ms。其中,模版页是304的,里面的资源都是可缓存的,也就是说,这100ms的收益并不来于缓存,而是来于某些模块的初始化。

JS初始化

这里提到的JS初始化,并不是前面说的JS引擎相关的初始化。JS初始化是指JS文件缓存到httpcache和解析编译生成V8 Cache文件。很多数据表明,JS解析编译占JS耗时的35%以上,一些有巨型JS的页面甚至可以达到80%。在U4 2.0中,一般JS执行一次之后,就可以生成V8 Cache,虽然V8 Cache可以重复使用,但也存在被自动清理的情况,所以提前执行一次还是有收益的。

一些业务中,提前执行一次JS,在用户真实访问时,耗时从500ms降到200ms。特别是在一些超级App中,基础JS基本都一样,提前执行一次可能会带来非常明显的收益。

结束语

上面介绍了一些常见的初始化对页面性能的影响,希望大家能了解到一些隐藏的信息,能开阔Web优化的思路。当然,这些点不一定会存在很大的性能问题,比如,一些业务模块处理的非常好的App,在业务初始化方面不一定会有性能问题,需要根据自己的实际场景,具体问题具体分析。

目录
相关文章
|
1月前
|
机器学习/深度学习 前端开发 算法
利用深度学习技术提升前端图像处理性能
本文将探讨如何利用深度学习技术在前端图像处理中提升性能。通过结合深度学习算法和前端技术,我们可以实现更高效的图像处理功能,提升用户体验和系统性能。
|
1月前
|
前端开发 数据可视化 JavaScript
前端vite+vue3——可视化页面性能耗时指标(fmp、fp)
前端vite+vue3——可视化页面性能耗时指标(fmp、fp)
92 6
|
1月前
|
前端开发 Android开发 iOS开发
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
【4月更文挑战第30天】Flutter 框架实现跨平台移动应用,通过一致的 UI 渲染(Skia 引擎)、热重载功能和响应式框架提高开发效率和用户体验。然而,Android 和 iOS 的系统差异、渲染机制及编译过程影响性能。性能对比显示,iOS 可能因硬件优化提供更流畅体验,而 Android 更具灵活性和广泛硬件支持。开发者可采用代码、资源优化和特定平台优化策略,利用性能分析工具提升应用性能。
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
|
1月前
|
前端开发 JavaScript Android开发
【Uniapp 专栏】分析 Uniapp 与其他前端框架的异同
【5月更文挑战第16天】Uniapp是一个基于Vue.js的跨平台前端框架,能将代码编译成iOS、Android、H5等多个平台应用,简化跨平台开发。相比React和Angular,Uniapp更适合移动应用,减少平台适配工作。Vue.js的组件化和灵活性在Uniapp中得到延伸,增加了移动端特性。而Flutter性能优越,但学习成本高。开发者应根据项目需求和技术栈选择合适的框架。
【Uniapp 专栏】分析 Uniapp 与其他前端框架的异同
|
4天前
|
缓存 监控 前端开发
前端性能优化:从系统分析到实践策略
**前端性能优化概述** 本文探讨了前端性能优化的重要性,强调了从整体角度而非仅关注局部优化手段的必要性。作者指出,建立性能评价系统是关键,通过**性能指标**(如FP、FCP、LCP、CLS等)来量化页面性能,然后使用**性能监控**工具收集数据。文章列举了9个关键性能指标,并介绍了如何通过SDK或工具进行数据收集。 在实际操作中,文章提到了**性能优化方法论**,包括了解何时何地出现性能问题,以及如何根据性能指标采取相应优化措施。作者推荐使用Chrome的Lighthouse工具进行性能测试,并讨论了**CDN**、**缓存策略**和**懒加载**作为常见的优化手段。
28 0
|
13天前
|
Web App开发 前端开发 网络协议
性能工具之常见压力工具是否能模拟前端
【6月更文挑战7天】性能工具之常见压力工具是否能模拟前端
13 0
|
1月前
|
SQL Oracle 前端开发
Oracle效率分析,Github标星25K+超火的前端实战项目
Oracle效率分析,Github标星25K+超火的前端实战项目
|
1月前
|
前端开发 JavaScript 搜索推荐
前端网页手册(2)--菜鸟教程网站分析
前端网页手册(2)--菜鸟教程网站分析
26 2
|
1月前
|
缓存 监控 前端开发
【Flutter前端技术开发专栏】Flutter应用的性能调优与测试
【4月更文挑战第30天】本文探讨了Flutter应用的性能调优策略和测试方法。性能调优对提升用户体验、降低能耗和增强稳定性至关重要。优化布局(避免复杂嵌套,使用`const`构造函数)、管理内存、优化动画、实现懒加载和按需加载,以及利用Flutter的性能工具(如DevTools)都是有效的调优手段。性能测试包括基准测试、性能分析、压力测试和电池效率测试。文中还以ListView为例,展示了如何实践这些优化技巧。持续的性能调优是提升Flutter应用质量的关键。
【Flutter前端技术开发专栏】Flutter应用的性能调优与测试
|
1月前
|
前端开发 JavaScript 网络协议
【专栏】探讨了前端性能优化中的 Performance 工具,它能帮助开发者分析页面加载速度和交互体验
【4月更文挑战第29天】本文探讨了前端性能优化中的 Performance 工具,它能帮助开发者分析页面加载速度和交互体验。通过 Performance,可检测资源加载时间、JavaScript 执行时间、重绘与回流等关键指标,找到性能瓶颈。文中列举了三个实践案例,如优化图片加载、减少 JavaScript 执行时间和避免重绘回流,展示如何利用 Performance 改进页面性能,提升用户体验。开发者应定期使用 Performance 分析并学习新优化技术,以适应Web开发的快速发展。