在 20 美元的功能手机上快速加载网页
介绍
背景
功能手机的限制
开发指南
结论
提示:为您的网站构建快速的核心基础可以为每个人带来良好的体验;无论他们使用的是低成本功能手机还是最新的高端智能手机。
介绍
功能手机价格实惠(低于 20-25 美元),是低端设备,让发展中国家数亿用户能够使用互联网。可以将它们视为智能手机的轻量版。
由于价格低廉,功能手机的 CPU 速度通常较慢(比高端智能手机慢 6 倍),RAM 较低(例如 256MB-512MB,通常低于 4GB),存储空间较小(4G),而且通常没有触摸屏。它们使用数字键盘或方向键进行导航。例如:
这些设备无法像高端智能手机那样处理丰富的 JavaScript 和媒体体验,因此必须特别小心发送的有效载荷。
上图展示了2019 年全球最畅销智能手机的Geekbench CPU 性能基准测试。我们还可以看到(已突出显示)热门功能手机——诺基亚 3110 的性能。JavaScript 强调单核性能(请记住,它本质上比 Web 平台的其他部分更单线程),并且受CPU 限制。这意味着在考虑发展中国家时,牢记设备特性非常重要。
这篇文章试图解决这些痛点,以便我们可以构建每个人都可以使用的网站,无论他们的设备有多快。
背景
你可能记得,也可能不记得,在智能手机出现之前,功能手机在2000年代中期一直很流行。它们体积小巧,采用键盘而非触摸屏,功能也比较基础,例如通话、短信和简单的以文本为主的网页浏览。智能手机出现后,这些手机在发达国家的普及率有所下降。
在发展中国家,并非每个人都能负担得起智能手机和4G网络的无限流量套餐。这个市场已被功能型智能手机占领,它们兼具了基础款手机的硬件和价格,以及智能手机的部分功能。
智能功能手机市场自 2017 年以来大幅增长,预计2019年全球功能手机销量将达到 4 亿部。
功能手机的增长得益于诺基亚对其经典机型 3110 和 8110(Paul Kinlan 为其提供了便捷的调试指南)的复兴。在印度,Reliance Jio 的功能手机提供了一种经济实惠且现代化的移动互联网访问方式。Jio 推动了KaiOS(一款基于 Linux 的功能手机操作系统)的发展。
功能手机市场的增长产生了对能够高效运行的网站的需求,但我们可能应该意识到一些限制。
上面是 Google Images Lite 和 Facebook mBasic,它们在功能手机上加载速度都很快,并且对客户端脚本的依赖程度极低。Proxx是一款游戏,虽然依赖脚本,但依靠积极的代码拆分来快速加载。
功能手机的限制
发展中国家的用户受到3个因素的限制:
- 少量低成本、高质量的设备
- 缺乏高质量网络
- 价格实惠的移动数据
在采用功能手机思维方式时,请记住以下限制:
- 硬件:功能手机通常运行速度较慢(1.1 GHz)的单核或双核 CPU,内存不足 512 MB。不妨将其与配备六核 CPU 和 4 GB RAM 的 iPhone XS 进行比较,了解这一限制意味着什么。
- 数据:数据套餐价格正在下降,但在功能手机将逐渐普及的地区,流量仍然会受到严重限制。尽量避免过大的网络负载,以确保您的页面加载速度快,并且不会给用户带来过多的流量开销。
- 屏幕尺寸有限:功能手机的屏幕尺寸通常比智能手机小得多。其屏幕尺寸在 2.4 英寸左右,只能容纳有限的交互。因此,应考虑尽快加载视口内容所需的资源。
- 非触控:在没有触控的情况下,屏幕上的每个功能、操作按钮或链接都需要能够通过键盘轻松访问。您肯定不想创建太多快捷方式。
- 键盘:功能手机的键盘与我们习惯使用的 QWERTY 键盘截然不同。它们大约有 15 个按钮,有些字符需要反复按下同一个按钮才能输入。因此,用户体验应该尽量减少打字的需要。
即使在日本,有限的数据计划也会影响用户的网络体验:
开发指南
以下技巧有助于在功能手机上为网站提供快速的体验。一般来说,不要让用户等待任何他们不需要的操作。尽可能缩短 JavaScript 的下载和执行时间。
为初始有效载荷设置性能预算
页面的每个字节在传输过程中都会遇到许多瓶颈。这些瓶颈包括缓慢/不稳定的网络、缓慢的 CPU,而提高性能的唯一可靠方法是设定预算并减少操作。
性能预算是团队为确保良好性能而共同遵守的一组限制。它们是对指标的限制,您承诺不会超出这些限制。在开发开始之前定义可量化指标的预算有助于确保团队在开发新功能时始终遵守这些标准。
可以预算的资源指标示例包括 JavaScript 包大小、图像字节数或 HTTP 请求数。可以为用户体验指标(例如首次内容绘制、最大内容绘制或首次输入延迟)设置用户时间预算。可以根据目标受众为每个指标定义阈值。
可以为初始应用程序逻辑、供应商/公共资源包等设置预算。预算可以在构建过程中、通过Lighthouse(LightWallet)以及持续 集成中强制执行。
PRPL-30 - 功能手机的 JavaScript 预算
Chrome 团队推荐使用PRPL 模式来精细地提供代码服务,以便在低端设备上快速实现应用的交互,尤其是在网络速度较慢的情况下。PRPL 鼓励预加载尽可能少的脚本以确保页面可用,然后利用延迟加载和(可选)Service Workers 预缓存这些脚本包,以供将来导航使用。
PRPL-50进一步扩展了这一思路,为初始资源设置了 50KB 的预算。由于功能手机的 CPU 性能更加受限,我们需要对 JavaScript 设置更严格的限制。如果针对功能手机,我建议使用PRPL-30(30KB gzip 压缩包 + 最小化后的初始包)。
在这些设置下,SSL 协商后,来自良好边缘缓存服务器的第一个字节通常大约需要 2 秒。这意味着我们有 3 秒的时间来下载、渲染初始路由的有效负载,并准备好在屏幕上供用户输入。为了获得以 JavaScript 为中心的体验,这意味着您的页面或路由的初始打包总大小(经过最小化和 gzip 压缩)应小于 30KB。
等等。30KB 的初始包?太荒唐了。我甚至连 React 和我的应用代码都塞不进去!在为性能极其受限的设备构建应用时,你必须以用户体验的名义做出艰难的权衡。例如,你可以在功能手机上使用 React,但前提是你必须 (1) 将 React 的使用限制在服务器端——这是一个完全合理的选择;或者 (2) 将应用程序逻辑块保持在非常小的范围内,并积极地使用惰性加载。(3) 则需要选择像 Preact 这样的解决方案,但我们稍后会进一步讨论这些权衡。
一个可以在 30KB 预算下运行的应用程序示例是Proxx,它的初始大小为 25 KB,交互时间 (TTI) 小于 5 秒。我们的性能预算计算器可能会在您规划自己的目标指标时有所帮助。
惰性加载路由的建议大小也小于 35 KB。30 KB 到 35 KB 之间的路由“块”仍然足够大,可以通过V8 的脚本流进行并行处理。
节约使用 JavaScript
简而言之,如果可以,请选择静态渲染或服务器渲染,并尽可能减少对脚本的依赖。如果必须使用客户端或混合渲染,请仅发送路由所需的脚本,并尽可能减少往返次数。考虑使用渐进式补液 (progressive rehydration)等技术。
JS 是功能手机的首要瓶颈
在为功能手机打造交互式体验时,请注意 JavaScript 可能是最大的瓶颈。这一点至关重要,因为您选择的页面渲染方式可能会延迟用户实际使用页面的速度,即使使用方向键也是如此。如果您选择服务器渲染或静态渲染页面,请确保交互负载尽可能小。
JavaScript 有两个关键成本:下载时间和执行时间。较慢的网络(例如 3G 的有效连接)会延迟 JavaScript 的传输速度,而较慢的 CPU 则意味着脚本的执行时间会更长。下图中,我们可以看到一个热门 JavaScript 密集型网站的 CPU 处理速度差异——请注意,低端设备的运行时间可能是高端设备的 6 倍:
不同智能手机CPU性能对比
如果页面严重依赖大型 JS 包进行渲染或交互,那么在功能手机上,用户可能需要等待 30 到 60 秒才能使用 UI。因此,为了最大限度地减少 JavaScript 的下载和处理时间,开发者需要精简 JavaScript,仅在用户可能需要时加载路由和组件所需的 JavaScript。
保持交互式有效载荷精简
- 尽可能延迟加载屏幕外或对首屏内容不重要的路由、组件和资源。
- 使用代码拆分来拆分 JavaScript,以便仅在初始路由上提供用户所需的内容。这将减少需要下载和执行的脚本数量,从而加快页面加载速度。
- 从 JavaScript 包中移除未使用的代码,使其尽可能精简。这需要您分析包并检测哪些库根本没有使用或不需要,并可能被自定义库替换。初始加载期间不需要的库也可能会被延迟加载。
- 考虑差异化加载,以便将现代 JS 加载到现代浏览器中,避免过度编译和过多的 polyfill。减少加载到现代浏览器的遗留代码量有助于提升页面加载性能。
- 如果 JS 对于渲染和获取初始用户体验交互至关重要,请预加载这些脚本。如下所示预加载脚本可以告知浏览器该脚本非常重要,应尽快加载。
<link rel="preload" as="script" href="critical.js">
明智地选择你的堆栈
虽然第三方库有助于加快开发速度并轻松完成复杂任务,但它们也可能很重,在为功能手机开发时应谨慎使用。以下指南可以帮助您以最佳方式整合外部依赖项:
- 由于功能手机的资源非常受限,请尽可能避免或限制使用 JavaScript 框架——关键在于为您的应用逻辑留出尽可能多的空间。在为了保持页面精简和高性能而应该限制 JavaScript 使用的情况下,JavaScript 框架会增加大量开销。如果您使用 React 构建,请考虑限制使用服务器渲染,或在构建时将其替换为Preact和Preact compat,以减少约 30KB 的包大小。Svelte 、lit-html和原生 JavaScript 都是轻量级包的不错选择。
- 尽量减少第三方依赖,以确保初始页面包的大小在预算范围内——可以使用bundlephobia.com等工具,它们可以很好地突出显示库的成本。请对你的包进行完整性检查,确保你使用的库精简(例如,使用date-fns或luxon,而不是 Moment.js 及其庞大的语言环境默认值)。
- 使用Redux和内联 Redux 存储管理应用程序状态时务必谨慎。Redux 状态通常内联在 HTML 中以“补充”页面内容,这往往会增加响应的大小。
避免在慢速连接上加载大量资源
提示:您可能对自适应加载 - 提高低端设备上的 Web 性能感兴趣,以了解有关此主题的更多信息。
自适应加载是一种根据用户的有效连接类型(ECT) “调整” 提供给用户的资源的技术 - 可通过网络信息 API提供给支持的浏览器。自适应服务允许网站确保连接速度较慢的用户也能获得“最佳”体验,即使保真度较低。
console.log(navigator.connection.effectiveType); // 3G
注意:即使在“快速”的 4G 上,用户也可能会遇到网络速度较慢的情况,就像您在咖啡店或会议 WiFi 上遇到的那样。
一个可以使用自适应服务的具体示例是产品项组件。网速较慢的用户可能只会看到压缩版的产品图片,而网速较快的用户则可以加载高质量图片以及需要更多 JavaScript 的增强功能,例如放大产品图片或查看不同产品图片视角的轮播。
对于功能手机来说,网速慢未必是最大的障碍。即使 4G 网络连接良好,CPU 速度慢和内存不足也更有可能影响用户体验。虽然我们目前无法访问 CPU 报告,但客户端提示提供了设备内存、视口宽度、设备像素比、网络信息和其他信号的近似值,可用于制定更精细的服务策略。
使用“保存数据”标题尊重用户的数据计划
Chrome Android 版拥有一项名为“精简模式(数据节省器)”的功能,允许注重数据流量的用户选择启用浏览器自动优化资源的功能,从而提升页面加载速度。这些优化措施包括:进一步压缩图片、延迟加载非关键资源或服务器端渲染页面预览。更多 Chrome 的优化措施,请参阅我们的“精简页面”博客文章。
当用户在支持的浏览器中启用流量节省模式(例如精简模式)时,它会将Save-Data 请求标头附加到所有 HTTP 和 HTTPS 请求中。应用开发者可以在 JavaScript 中检查此提示是否已启用,以便为启用精简模式的用户提供优化的体验(例如,有条件地关闭高负载功能)。以下代码片段可用于检查此提示是否已启用:
if ("connection" in navigator) {
if (navigator.connection.saveData === true) {
// Implement data saving operations here.
}
}
注意:虽然您的功能手机可能支持 Chrome,但这并不能保证精简模式(流量节省程序)可用。建议您将此功能的可用性视为推测。
将昂贵的应用程序逻辑和状态处理卸载到 Web Workers
提示:请务必阅读Surma 撰写的《即使在功能手机上也能让 Web 应用快速加载的技巧》。这本书非常棒。
除了运行 JavaScript 之外,浏览器的主线程还负责其他任务,例如页面布局、在屏幕上绘制像素以及跟踪用户交互。长时间运行的复杂 JavaScript 最终可能会阻塞这些其他任务。
Web Worker允许 JavaScript 代码在“后台”运行,而不会阻塞主线程。它们应该用于避免主线程承担昂贵的 JavaScript 开销,例如复杂的应用逻辑或状态管理服务。主线程和工作线程使用postMessage()函数和onmessage处理程序进行通信。postMessage 函数允许发送者发送单个参数,该参数可以是任何值或对象。像Comlink这样的库可以减少在应用中使用 Worker 的麻烦。
Surma 的Proxx案例研究(启用和禁用工作线程)非常值得一读——据观察,在 Nokia 2(1GB RAM/1.3 GHz 四核处理器)上,不使用工作线程时,应用会卡顿 6.6 秒。而使用工作线程时,同样的操作/事件的响应时间为 48 毫秒。因此,如果您的逻辑需要占用大量 CPU 资源,则有必要评估将其迁移到工作线程是否适合您的用例。
优化图像
图片通常会消耗大量数据。此外,解码也需要时间,尤其是在低端设备上,因此,在将图片传输到功能手机时,务必确保图片尺寸正确且压缩率正确。
- 使用 Imagemin 之类的工具压缩图像,以生成尺寸较小且对质量没有明显影响的图像。
- 用加载速度更快的视频替换 GIF 动图。即便如此,也要认真考虑在低端设备上需要多少大型多媒体资源。
- 尽可能延迟加载图片,但要确保所需的 JavaScript 负载不要过大。新的 native
loading
属性可以提供帮助。 - 通过创建多个版本的图像并提供最适合用户视口的图像,提供具有正确尺寸的响应式图像
- 提供适合屏幕尺寸的图像。在低端设备上加载低保真度、低分辨率的图像可以确保更快地解码图像。
检测屏幕尺寸
目前许多智能功能手机的屏幕尺寸为 QVGA,分辨率为水平 320px、垂直 240px(320 x 240)。如果您需要在页面加载时检测屏幕尺寸(例如,切换某些功能或使用自适应加载),可以使用如下代码片段:
const isFeaturePhone = Math.min(screen.width, screen.height) <= 240;
在 Chrome DevTools 中模拟功能手机
如果是为功能手机打造,强烈建议选择一款便宜的手机进行实际测试。
如果您想在 Chrome DevTools 中模拟功能手机(例如 Reliance Jio KaiOS 设备),请按以下步骤操作:
- 打开 Chrome DevTools
- 切换设备工具栏
- 设备下拉菜单 > 编辑... > 添加自定义设备
- 名称:KaiOS(或根据需要自定义)
- 宽度:240,高度:320
- UA:
Mozilla/5.0 (Mobile; LYF/F90M/LYF-F90M-000-02-23-181217; Android; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5 YouTube/1.66.51.J
- 节省
- (可选)根据需要自定义 CPU 限制,但请注意,这永远不会像在真实设备上测试那样准确。
结论
无论用户身在何处,我们都能为他们提供愉悦的体验。但这需要格外小心,因为并非所有移动硬件都一样。
手机价格越便宜,CPU 速度越慢的可能性就越大。鉴于 JavaScript 的性能取决于下载和执行时间,请务必考虑如何提供最佳体验。
虽然这对于智能手机来说很重要,但对于功能手机来说更为重要。
文章来源:https://dev.to/addyosmani/loading-web-pages-fast-on-a-20-feature-phone-8h6