前端体验优化(1)——概述

前端体验优化地最终目的就是让用户的使用体感舒适,无阻塞、流畅的得到预期想要的结果,而其中的用户可分为三层:产品用户、公司同事和研发自己。UX、性能优化其实都是体验优化的子集,前端体验犹如下图的冰山那样,在水下别有洞天。

可以将体验优化大致分为 5 个模块,分别是终端、网络、前端、后端以及数据,这 5 个模块可以形成一个闭环。

终端就是浏览器、微信等一类设备,网络就是缓存、协议等一类概念,前端和后端针对的就是技术细节,而数据其实就是最后的分析,对优化前后进行量化对比,最终得出结论,判断此次优化是否成功。

与以往的视觉体验优化(例如线框图的不同布局)不同,本文着重分析的前端体验侧重于技术端和数据分析,更偏向于前端开发人员,而不是 UI 设计人员。

下面是一张前端体验优化的思维导图,还在持续更新中。

其中终端模块的图像呈现网络模块,前端模块的 JavaScript构建都被记录在前端性能精进专栏中。

数据模块的性能指标记录在方法论之测量分析,监控体系记录在监控系统专栏内(包括 SDK存储和分析页面奔溃)。

终端优化的核心是减少渲染时间,网络优化的核心是减少延迟时间,另外三个模块都在服务于这两个模块。

下图描绘了网页在加载过程中,各阶段与上述模块之间的优化关系。

一、终端

终端最常用的就是浏览器,浏览器最需要关注的优化点是两个:图像和呈现。

  1. 在网页中充斥着图像,而图像往往会增加网页的尺寸,所以优化的重点是用尽手段减小尺寸,例如动态裁剪、响应式、WebP、加载时机的转变等等。
  2. 呈现涉及浏览器渲染和静态资源的请求,核心就是缩短渲染和资源加载时间,例如只渲染首屏、提前加载后续资源、对重要资源优先请求等等。

微信是一款国民级APP,提供了 JSSDK 和小程序的功能,JSSDK 赋予了用户部分微信的能力,依托微信的生态,小程序现在有了非常广泛的应用。所以对于这个环境,也会有各类独特的优化手段,不过我本人还不熟悉这块。

还有一个很重要的终端就是各类 APP 内置的 WebView,客户端通过 WebView 可以暴露出许多功能,帮助前端页面的优化,例如唤起客户端的登录和支付界面,还有就是最大限度的缓存网页资源,减少网络请求,例如容器化、离线包。

除此之外,还可以增加预请求的能力,将串行的网络请求优化为并行的网络请求,充分利用空闲时间。

诸如 Electron、WebRTC、多媒体等这类优化点,自己并不是很熟悉,在此也不再赘述。

二、网络

当一个请求从终端发出到服务器接收,这段网络传输的时间,其实是我们不可控的。

要优化就只能从起点和终点两处入手。最先想到的就是开启缓存:强缓存和协商缓存。

日常使用最多的是协商缓存,但是在性能提升上,决定强缓存更为明显,因为强缓存后就不会再去服务器请求资源。

不过,为了页面正确,还得设法破坏缓存,尤其是 HTML 文件,例如给 URL 包一层短链,在请求时自动加个时间戳,以此让缓存不再命中。

HTTP 是一种网络协议,目前已经可以广泛使用 HTTP/2 协议,在之前的基础上做了许多优化,例如二进制分帧层、多路通信、首部压缩等,让数据传输的更快以及更大限度的利用好带宽。

协议中的压缩字段,默认都已经开启,对于非媒体文件(例如 HTML、CSS、JavaScript 等)经过压缩后,尺寸可减少 50%,甚至 80%。

HTTP/3 协议解决了上一个协议的几个问题,例如 TCP 队首阻塞、网络切换成本等,不过目前最大的问题还是支持度不够,不能大范围的使用。

HTTPS 是 HTTP 的安全版本,目前有些浏览器默认会将 HTTP 的请求重定向到 HTTPS,这种多余的重定向完全可以避免。

CDN 是一种网络加速服务,目前有很多公司都提供了这类服务,但就是要花钱,只要花钱了,海外都能给你加速,无论静态资源还是动态接口,都可以借助 CDN 加速,现在还能提供对图像的动态裁剪和压缩的功能。

有时候浏览网页会遇到网关报出的 500、502、503、504 等错误,其实就是服务异常、找不到转发服务或转发服务在指定时间内未响应。

对于未响应,可以从相关分析平台找出性能瓶颈,然后在后端部分进行代码优化,很多时候与数据库有关。无论如何,要尽一切可能避免此类错误,这类体验最为糟糕,无法得到预期结果。

三、前端

前端现在已经离不开工程化构建,常见的 Webpack、Rollup 等打包工具提供了许多优化功能,例如压缩、合并、剪枝等,尽量减少网络请求和资源尺寸。

除此之外,尽量减少和选择轻量级的依赖库,也能降低不少的尺寸。随着 IE 这个毒瘤退出舞台,移动端兴起之后,ES6 也被广泛的支持,很多时候都没必要降级到 ES5,再也不用平白无故的多出一大段代码了。

ESBuild 也是一个构建工具,不过与之前的不同,它内部是用 go 编写的,所以说它非常快。

Vite 的开发环境依赖的就是它,但是为了快,就没有提供 AST 的操作能力,导致目前很多的插件无法使用,所以 Vite 生产环境使用的还是 Rollup,是对性能与灵活性的一种平衡。

前端三剑客之一的 JavaScript,是每个前端开发人员每日必会使用到的,对于它的优化基本上都是代码层面的优化,常见的节流和防抖,算法和数据结构,分解或异步执行长任务,本地存储等。

有个库叫 Partytown.js,比较有意思,可以将第三方脚本迁移到 Web Worker 中执行,防止阻塞主线程,不过这还只是个测试性的库。

前端为了让自己的日常工作比较爽,技术栈不能太旧,否则很多新功能都体验不到,太可惜了。在升级技术栈时,还不能影响业务,运营、产品等人可不会在意你用什么技术栈,他们在意的是业务保持稳定,并且还能持续迭代。

前端的基建包括组件化、标准化、工具化、自动化、文档化以及页面规范化,本质就是让自己组的开发效率能更高,与别人协作发生的错误能更少,产品上线后最好没有问题。一句话就是你要好,大家也要好,和谐办公。

在功能上线前,可以对新功能加个开关,万一有问题,就直接关闭新功能,粒度可以是页面级别的。不过前端发版不像客户端那么困难,毕竟做开关是要成本的。灰度和 A/B 测试,在前端也可以执行。

四、后端

传统的前端开发是不接触后端的,但是自从 Node.js 拓宽了前端的边界后,越来越多的前端开始涉足后端,那么就很有必要了解后端的体验优化。

后端的优化大致可分为两部分:Node.js 和数据库,对于它们的监控,市面上有许多成熟的平台,自己搭建的话,成本有点高。

我刚到公司时,还在用 Node.js 的 8.7 版本,明显太老,在挑选第三方库时,还得特地挑老版本,所以说,要将版本进行最适当的升级,在改造成本最小的前提下,升级到最高的那个版本。

上一节讲到基建,其中很多内容都是需要借助 Node.js 实现的,例如通用配置、脚本执行等。

还有下一节中的监控系统,也需要 Node.js 实现,并且还要涉及到消息队列、MySQL、ElasticSearch 等技术点。注意,对于那些非业务服务,需要单独分离,以免异常时影响线上业务。

在有了后端能力后,就能自己写接口,接口的响应格式很重要,在统一后,更容易分析接口的成功和失败细节。并且对于接口,要有安全意识,以及不能因为接口的问题而让页面直接异常,需要用更友好的反馈方式。

目前市面上有许多种数据库,常见的关系型数据库 MySQL,遇到比较多的问题就是数据量上去后的慢响应,很可能导致 504 异常,要么缩小查询范围,要么就是创建合适的索引。

MySQL 处理百万级的数据量绰绰有余,但千万级就比较够呛了,此时除了索引加持外,还需要进行分表、数据归档等手段,其实本质都是为了减少数据量。

与之前的 Node.js 服务类似,对于那些非业务表,可以单独生成一个库来存储,也是避免数据库异常导致线上业务出错。

MySQL 全文检索的能力不行,所以对于大数据量的全文检索需要改用 ElasticSearch,还有那些需要联多张表的情况,也可以将数据存储到 ElasticSearch 中再做查询。

Redis 其实也是一种非关系型的数据库,最大的特点就是快,若要对接口的查询进行优化, Redis 无疑是一种高效的手段。

不过在用 Redis 时需要注意,它只是一种缓存,若没有它,也要能得到预期的数据。也就是说,尽量不要让业务逻辑依赖 Redis 中的数据,Redis 只是为了加速,即使没有了它,线上业务也不应该出错。

五、数据

为了能更好的优化体验,很有必要量化性能,以及监控页面的方方面面。

首先关于性能,目前已有很多工具,例如 Lighthouse、WebPageTest 和 Chrome Devtools,它们会分析页面的性能,不过这些只能算是实验室数据,并不是真实用户的数据。

我们自研了性能监控系统,记录了一系列的指标,包括白屏、首屏等,在搜集过后,提供了多种图表进行性能分析。

力图重现真实用户的使用场景,发现性能瓶颈。前端监控也是自研的,会记录页面的异常、通信、点击等行为,同样提供了各类图表。

通过此系统,可以主动发现页面中的错误,而不是等待用户上报,并且还发现了许多冗余接口。

除此之外,每天都会推送核心指标到前端的飞书群中,包括接口慢响应占比、SLA(服务质量保证,即5XX占比)等,关注服务的健康度。

线上还会实时监控页面、接口和数据库的错误情况,当达到某一个阈值时,就会发送告警到飞书中,同样是为了在用户上报前发现问题。

为了能更好的与公司同事协作,我们组制订的每双月的需求提测率和用户满意度评分,当然,这个用户是内部员工。

之所以是提测率而不是完成率,是因为很多时候项目是要与服务端协作的,可能我们做完了,他们还没完成,而这种情况还比较普遍,所以就使用了提测率。

除了技术监控之外,前端人员还需要了解业务监控数据,其实也是为了让自己能更好的理解业务,培养产品思维。

通过埋点将某一处的动作,传输到服务器做存储,然后再经过数据分析人员,绘制成一张张的图表。埋点的采集并不复杂,常见的就是侵入式的在某一处位置加入埋点代码。

若对页面做了某种优化,涉及到业务逻辑时,可以分析埋点数据,比对前后的变化,来决定优化是否成功。

在我们公司,每一个小组都会有一个或两个北极星指标(例如用户新增数、XX营收、日志发布率等),指标的变化就是核心业务的变化。

而在这个指标下面,还有许许多多的细节指标,支撑着北极星指标,以会员为例,日付费人数、日下单量、首次充值人数等。

如果有条件的话,可以让分析人员开放些与自己有关的指标,再与相关人员紧密沟通,让这些数据更有活性。