TV端Web页面性能优化实践

01

   背景

随着互联网技术的持续创新和电视行业的高速发展,通过电视观看在线视频已经逐渐成为大众的重要娱乐方式。奇异果App作为在TV设备上用户活跃度最高的应用之一,为广大用户提供了丰富的内容播放服务,除此之外,同样有会员运营、专题活动等上线效率要求极高的服务提供给用户。为满足后者的诉求,我们调研了目前主流的动态化和跨端技术:H5、Flutter 和 React Native,最终从开发效率、人力成本、动态能力和性能上选择用H5方案,目前,H5页面承担了奇异果App内大量的收银、运营活动、专题等业务。然而,H5页面在TV设备上加载耗时过长是我们面临的主要困难,如何提升 H5页面在TV设备上的用户体验,是我们迫切需要解决的问题。

02

   面临的挑战

挑战1:TV设备换机周期较长,系统碎片化问题严重,目前TV端 5.0系统以下的设备占比约 30%,占比很高。优化首先面临的是版本的跨度,兼容低版本是首要考虑。下图为TV端系统版本占比情况:

f73dcacd50a2cadf51cb2990ce9d284a.png

挑战2:TV设备性能偏低,TV设备主要分为三种:电视、盒子和投影仪,以上设备的的配置严重低于同时期的主流手机配置,在我们的性能等级划分中,CPU为4核A53架构且内存超过1.5G就已可划分为高性能设备,在低性能设备中,仍存在较多A7架构处理器或内存为512M的设备。

挑战3:App版本碎片化严重,由于电视行业合作现状的复杂性,渠道较多;传统电视厂商追求稳定,对于升级较为慎重;有较多廉价设备在售,且售出后接近不维护状态;合作模式的复杂导致定制较多,升级困难,对SDK层面的优化和上线有较大挑战。

03

   优化历程


1、准备工作

在优化之前,最重要的工作是统一性能口径、制定统计指标。在口径层面上我们没有采取常规的前端页面加载耗时,采取了更符合用户真实体验的场景:从用户点击按钮开始到真正用户可见。虽然这样会导致我们统计的指标整体耗时增加,但评估后这个指标更利于我们后续优化工作的方向展开。指标口径说明如下

1)页面可见耗时:从客户端点击开始—>客户端页面跳转—>web容器初始化—>前端DOM渲染完成可见。

2)可交互总耗时:页面可见耗时 + 可响应用户遥控器按键总时间。

3)native页面耗时:客户端页面跳转耗时。

4)webview初始化:web容器初始化耗时。

5)调用h5耗时:loadUrl到h5开始执行第一行代码耗时。

6)h5加载耗时:h5开始执行第一行代码到页面可见耗时。

7)h5可交互耗时:h5页面可见到页面可响应耗时。

统计口径统一后,我们在webSDK层面对以上时间点进行投递,并回收线上数据,根据指标反馈的问题进行针对性的优化。在未经优化的情况下,H5的加载速度平均约为 5.5 秒左右,用户体验很差。通过线上数据分析H5加载耗时在整体占比较大,优化H5加载耗时是我们亟需解决的问题。


2、H5加载耗时优化

H5加载耗时主要依赖于前端部分的优化,由于文章篇幅有限,常规的H5页面优化工作不再赘述,如:

1) 资源合并

2) 数据请求合并

3) 业务逻辑优化

4) DOM结构优化

5) 同地址下不同模式Async路由化加载

3、SSR优化

除以上优化之外,SSR(服务器端预渲染)技术进入我们的视线之内,SSR是一种优化Web应用性能和SEO的技术,通过在服务器端生成初始HTML,提高了页面加载速度、搜索引擎优化和用户体验。通过选择适合的框架、创建路由、编写组件、服务器配置和数据获取,开发人员可以实现服务器端渲染,从而为用户提供更好的Web应用体验,保证首屏更快的渲染。

这种降低端上处理压力的方式,非常适合TV端设备性能较差的场景。SSR虽然也有自己的缺点,如虽然可以提高页面整体加载速度,但不利于页面的渐进加载。经过反复实验和线上数据,我们仍然认为SSR的收益整体是正向的,并研发上线。实验证明,SSR方案显著提升了H5页面加载速度。

68652cc1560bb8f4cc1a53cb7bd0369a.png

通过SSR优化后的H5页面加载流程如下图所示:

94dca63b54d5076869e43fb48f49dcc9.png

经过前端上述方案优化后,各个版本的加载速度都得到了显著提升。H5渲染部分的耗时从平均4秒减少至1.5s以下,总耗时减少至3.5秒左右。此时,单纯从前端角度继续优化遇到了瓶颈,投入产出比也较低,需要从客户端整体角度上继续思考优化手段。

4、资源离线缓存

CDN会部署一些关键的H5资源(如css、js、png、ttf等),其中有不少是在前端版本周期内不变的,且较大,客户端在适当的时候进行预下载。在渲染页面时,我们可以利用 WebView内核的 shouldInterceptRequest 回调来拦截在线 H5 URL 的加载请求,如果离线缓存中没有找到该资源,那么就通过在线网络进行加载;如果离线缓存中找到了该资源,则直接从本地磁盘读取资源,返回给 WebView。这种方法能够较大提升加载资源的速度。

离线缓存方案的大致流程图如下:

74bb3d6113aa8c33281779b1c97b0830.jpeg

同时在做的过程中我们发现在低版本上Android原生的请求库HttpUrlConnection还处于http1.0的阶段,不能享受http2.0的优化(如通道复用),这就使得预加载时的请求耗时较高。而TV端目前还有大量版本为5.0以下的低版本设备,因此我们选择了切换到TV端自主研发的网络库,这个网络库支持http2.0,从而提升了低版本设备的请求性能。另外我们看到从用户点击到H5页面打开是有一定的系统调度时间,这个时间也是可以用来做优化的即下面说的并行加载。

5、并行加载

除了上述提前缓存JS/CSS等资源的方案外,提前缓存html页面也是业界常用的优化手段,在页面未SSR化之前,由于性能瓶颈并不在html数据下载上,这种缓存机制并未取得较好的效果,在页面SSR化之后,这种方式又进入了我们的视野,在渲染数据已经生成完毕之后,这样的缓存机制理论上能够发挥更大的作用。

但同时我们又遇到了其他困难,由于个性化算法在业务中的应用已经非常广泛,将页面提前缓存并在一定时间内保持内容不变的方式,与业务上保持页面数据实时刷新的诉求形成了冲突。这使得我们需要找到更加适合业务场景的优化的技术方案。

Android系统在做Activity页面跳转切换时会有系统耗时,这个耗时和设备性能成反比,我们在页面跳转切换的同时拦截用户点击 web 页面的行为来提前启动任务并行加载H5页面的SSR数据。然后,根据 URL 和 cookie 参数生成一个唯一的令牌。在真正走到WebView 渲染时,将 URL 重定向到缓存中。同时,使用多线程锁同步和超时机制,以进一步提高H5的加载速度。

并行加载方案的大致流程图如下:

4ed3c2f258c63871631c125918650f4c.jpeg

在完成这些优化后,我们的加载速度从3.5秒继续优化到了2.8秒左右,提升了约23%。经过上述的一系列优化措施,我们的H5加载时间从最初的平均5.5秒降低到了2.8秒左右。然而,相比于纯原生(Native)页面,这个加载速度仍然存在较大的差距,需要我们继续寻找更有效的优化手段。为了进一步提高用户体验,我们进行了各种技术尝试、并通过与其他技术团队的积极交流与合作,我们又有了新的思路。

6、容器预热

在APP启动并且主线程空闲的时候,我们可以预热WebView引擎,并构建WebView缓存池,这样就能实现预热容器的复用,从而提升WebView的加载速度。这种优化策略主要针对中高性能设备和内存较大的低性能设备。在设备空闲时,我们进行WebView容器的预热,并将预热的容器添加到缓存池中。

在我们后续的使用过程中,我们直接从WebView缓存池中获取预热的WebView容器。这样可以节省创建web容器和jscore的时间。

7、页面预渲染

在TV端H5有很多业务实时场景限制,特别是运营活动这一类有很强的时效性,这对我们的优化带来了一定的限制。但是,我们找到了一些可定制化优化的场景,如:当非会员用户在观看会员专享内容的时候,通常会有6分钟的免费试看时间,试看时间结束后会自动跳转到H5。这类场景为我们进行预渲染提供了天然的优势,在类似场景下,当开始倒计时自动触发预渲染,使得H5内容得以提前加载,实现H5的秒开效果。如下GIF图所示,上图是未进行优化的加载过程,可以看到明显的黑屏和加载过程;下图是进行了预渲染优化的结果,实现了真正的秒开。

8626bed7153dee18887d73388614e08d.gif

397e18a115667e096b1f178f635556d9.gif

在完成以上这些优化措施后,对比去年的同期的数据,我们从线上数据中看到,加载时间进一步降低,从最初的非SSR平均5.5秒、SSR场景下3.5秒降至现在的平均2秒左右,对用户体验起到了明显的改善作用。

758179ffc56722fcf2771d360a518a60.png

04

   成果

我们对端上的优化进行了AB实验。经过打散平均后的试验数据显示,我们的优化措施使得订单生成页转化率平均提升了约21%,同时支付成功率的转化也平均提升了2.4%。

dbaaf48d2b9c1fa0c83d47be3cf5877c.jpeg

518ee5b0a38e8bef00f743c32716fa14.jpeg

实验证明,提升关键业务页面的加载速度和用户体验,对业务有非常直接的正向提升作用,这也为我们后续持续推进优化提供了充足的信心和动力。

05

   未来规划

未来,我们期望通过寻找更多方法,进一步降低性能指标,将页面平均耗时控制在2秒以内,并且控制劣化。

此外,我们注意到,平均数据并不能完全反映实际的用户体验,一些尾部用户仍然面临较差的使用体验,我们将继续分析90分位值之后的用户遇到的实际情况,并进行针对性优化。同时,我们将继续针对重要的业务场景如收银台进行定制化的优化,进一步提升关键业务的加载速度,从而不断改善用户体验和提高业务转化。

a7d01f2d5d6c15b22e34cf33687f8cad.jpeg

也许你还想看

安卓TV插件化9.0内联崩溃原因及解决方案

维护几十种语言和站点,爱奇艺国际站WEB端网页优化实践

爱奇艺知识WEB前端组件化实践

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/310282.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

超维空间S2无人机使用说明书——52、初级版——使用PID算法进行基于yolo的目标跟踪

引言:在实际工程项目中,为了提高系统的响应速度和稳定性,往往需要采用一定的控制算法进行目标跟踪。这里抛砖引玉,仅采用简单的PID算法进行目标的跟随控制,目标的识别依然采用yolo。对系统要求更高的,可以对…

buuctf-Misc 题目解答分解100-102

100.[ACTF新生赛2020]明文攻击 下载下来,就是一个压缩包,里面有压缩文件,解压出来 压缩包里面flag 但是加密了 用notepad 打开图片,发现是有flag 线索的 用notepad 打开 在末尾发现 压缩包不完整,找到了PK 所在的16…

独立站的个性化定制:提升用户体验的关键

随着电子商务的竞争加剧,用户体验成为了企业赢得市场的关键因素之一。独立站作为企业品牌形象和产品展示的重要平台,其个性化定制的程度直接影响着用户体验。本文将探讨独立站的个性化定制如何提升用户体验,并通过代码示例说明实现个性化定制…

3D视觉-结构光测量-线结构光测量

概述 线结构光测量中,由激光器射出的激光光束透过柱面透镜扩束,再经过准直,产生一束片状光。这片光束像刀刃一样横切在待测物体表面,因此线结构光法又被成为光切法。线结构光测量常采用二维面阵 CCD 作为接受器件,因此…

将本地工作空间robot_ws上传到gitee仓库

git config --global user.name "geniusChinaHN" git config --global user.email "12705243geniuschinahnuser.noreply.gitee.com" cd ~/robot_ws #git init#创建原始仓库时候用 git add . git commit -m "上传文件内容描述" #git remote add r…

QT上位机开发(倒计时软件)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 倒计时软件是生活中经常遇到的一种场景。比如运动跑步,比如学校考试,比如论文答辩等等,只要有时间限制规定的地…

CentOS7安装部署Zookeeper

文章目录 CentOS7安装部署Zookeeper一、前言1.简介2.架构3.集群角色4.特点5.环境 二、正文1.部署服务器2.基础环境1)主机名2)Hosts文件3)关闭防火墙4)JDK 安装部署 3.单机部署1)下载和解压2)配置文件3&…

centos 7.9 升级系统默认的python2.7到python 2.7.18

centos 7.9 升级系统默认的python2.7到python 2.7.18 备份旧版本 mv /usr/bin/python /usr/bin/python_2.7.5 下载新版本 Download Python | Python.org Python Release Python 2.7.18 | Python.org wget https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz cd /…

QT中的信号与槽的讲解

文章目录 信号及其特点槽及其特点代码演示标准信号与标准槽函数方式一方式二 自定义信号和槽connect()函数信号和槽函数存在函数重载的情况下Qt的信号槽机制注意事项 信号及其特点 信号:是一种特殊的函数,又称信号函数,俗称信号,…

Peter算法小课堂—浮点数危机

大家先想想下面这个代码运行结果&#xff1a; #include <bits/stdc.h> using namespace std; int main(){double x5.2;double y4.11.1;cout<<(x<y)<<endl;cout<<x-y<<endl;return 0; } 最终发现&#xff0c; &#xff1f;&#xff1f;&…

力扣:63. 不同路径 II(动态规划)

题目&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那…

Android 理解Context

文章目录 Android 理解ContextContext是什么Activity能直接new吗&#xff1f; Context结构和源码一个程序有几个ContextContext的作用Context作用域获取ContextgetApplication()和getApplicationContext()区别Context引起的内存泄露错误的单例模式View持有Activity应用正确使用…