2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

我们是如何构建 Twitter Lite 的?

  • 2017-04-24
  • 本文字数:2530 字

    阅读完需:约 8 分钟

我们很高兴为大家介绍全新 Twitter Lite,一款已经于 mobile.twitter.com 上正式发布的渐进式 Web 应用(PWA)。Twitter Lite 拥有快速与交互式特性、使用更少数据、占用更低存储空间且可在现代浏览器当中支持推送通知与离线使用模式。目前,Web 已经成为轻量级应用程序的运行平台,可轻松实现按需访问、顺畅安装以及逐步更新等优势。在过去一年中,我们采用了多种新型开放式 Web API,并显著提升了性能水平与用户体验。

架构概述

Twitter Lite 是一套移动端的 JavaScript 应用程序,同时亦是一款小型的简单 Node.js 服务器。该服务器负责处理用户身份验证、构建应用程序初始状态并将结果呈现至初始 HTML 应用程序 shell。在被加载至浏览器当中后,应用程序将直接通过 Twitter API 请求相关数据。这种基本架构的简单特性使得我们能够提供卓越的服务可靠性与运行效率——事实上,Twitter Lite 的运行成本相较于使用服务器渲染型桌面网站要低出一个量级。

这款客户端侧 JavaScript 应用程序已经配合多款开源库进行了开发、构建与测试,具体包括 React、Redux、Normalizr、Globalize、Babel、Webpack、Jest、WebdriverIO 以及 Yarn。凭借着现有开源软件,我们得以将更多时间与精力投入到提升用户体验、增加迭代速度以及推文数据与时间轴的处理与操作等相关解决方案当中。

我们编写的现代 JavaScript 代码(ES2015 及更高)由 Babel 编译完成,并同 Webpack 加以绑定。API 响应数据首先由 Normalizr 进行处理——其允许我们进行重复条目删除并将数据转化为更为高效的形式——而后被发送至多个 Redux 模块以实现对远程及本地数据的获取、存储以及检索。其 UI 由数百种 React 组件实现,其分别负责进行文本渲染、虚拟列表管理、延迟加载模块处理以及延迟渲染等任务。Twitter Lite 支持 42 种语言,我们还利用 Globalize 为其提供本地化数字、日期以及消息格式。

为性能而生

每个月,都有上亿用户访问 mobile.twitter.com 网站。我们希望 Twitter Lite 能够成为解决连接速度缓慢、可靠性差、性能受限或者高成本情况下的最佳 Twitter 使用途径。我们得以在其中引入一系列增量性能改进(我们将其称为 PRPL 模式),同时充分运用 Android 平台之上各类现代浏览器(例如谷歌 Chrome)中的各项新功能,具体包括 Service Worker、IndexedDB、Web App Install Banners 以及 Web 推送通知等。

可用性保障

Twitter Lite 具备网络弹性。为了与世界范围内的每一位用户顺畅对接,我们往往需要考虑网络速度缓慢且不可靠的情况。在可用性方面,无论具体网络状况如何,我们都会利用 Service Worker 确保临时性离线浏览与重复访问内容的近实时加载效果。Service Worker 负责对 HTML 应用程序 shell 与静态资产进行缓存,其中亦将包含部分常用 emoji 表情。当脚本或者数据出现加载失败时,我们提供“重试”按钮以帮助用户从故障中快速恢复。总而言之,这些变更能够共同提升可靠性,并在访问重复内容时显著加快加载与启动时间。

渐进式加载

Twitter Lite 具备渐进式特性,能够在大多数设备上立足 3G 网络于 5 秒内完成加载。目前全球大部分地区仍在使用 2G 或者 3G 网络 ; 因此快速的初始体验可谓至关重要。在过去 3 个月当中,我们将平均加载时间缩短了超过 30%,且 99% 的交互时延迟缩短了 25%。为了实现这项目标,应用数据流会首先在浏览器上进行 HTML 响应初始化、将指令发送至预加载的关键性资源处,同时由服务器端进行应用程序状态初始化。利用 webpack,应用中各脚本将进行进一步拆分并按需求加载。这意味着初始加载操作只需要当前屏幕显示内容所涉及的部分资源。(在可用性方面,Service Worker 会对其它资源进行预缓存,从而支持其它屏幕显示内容的即时导航效果。)这些变更使得我们能够实现应用的渐进式加载,以确保用户能够更快查阅及发布推文。

渲染

Twitter Lite 对资源占用率较高的渲染工作进行拆分。虽然我们以往一直高度关注组件渲染流程的优化,但推文本身就是一项复杂的综合性组件,因此对无数推文列表进行渲染显然需要进行额外的性能考量。我们构建起了自己的虚拟化列表组件 ; 其能够保证内容仅在当前视图内可见,同时利用 requestAnimationFrame API 渐进式渲染多个帧上的条目,且保留屏幕上的滚动位置。通过使用 requestIdleCallback API 将对非关键呈现内容的渲染工作推迟至空闲时段,我们成功地进一步提升了使用过程中的性能感受。

数据使用情况

Twitter Lite 会在默认情况下减少数据使用量,提供体积较小的媒体资源并高度依赖缓存数据。我们对于图像进行了优化,以确保时间轴滚动操作对数据使用量的影响最多降低 40%。“数据节约”模式能够进一步减少数据使用量,并通过使用体积更小的模糊预览图替换推文与 Direct Messages 中的图像。图像的 HEAD 请求能够帮助我们在按钮旁显示其具体大小,以便按需进行加载。作为体积仅为我们原生应用 1% 到 3% 大小的应用方案,Twitter Lite 亦可以大大节约运行所需要的设备存储空间。

设计系统与迭代速度

提升迭代速度有助于我们始终保持高水平的用户体验。我们在很大程度上依赖于 flexbox 布局,同时采用一整套小巧且数量固定的本色、字体大小与长度设计规范。Twitter Lite 由基于组件的响应设计系统进行构建,意味着该应用能够符合任何呈现形式。在 UI 组件的帮助下,我们建立起设计与工程技术团体间的共享表达词汇,鼓励双方能力协作以实现快速迭代并复用现有构建单元。我们当前最为复杂的部分功能,例如混合内容时间轴,已经能够利用 30 行代码完成从配置到接入 Redux 模块再到匹配 React 组件的整个创建流程。

展望未来

立足庞大的用户群体,构建这样一款快速高效且极具规模化水平的 Web 应用程序无疑给 Twitter 公司的设计、产品与工程研发团队带来了巨大挑战。我们对于自身取得的成绩感到振奋,并尝试利用 HTTP/2、GraphQL 以及多种替代性压缩格式以进一步降低加载时间与数据使用量。在未来的几个月中,我们还将对 Twitter Lite 的辅助功能、安全性、设计、功能以及性能作出更多细节改进。

查看原文链接: How we built Twitter Lite


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-04-24 19:002539
用户头像

发布了 24 篇内容, 共 11.3 次阅读, 收获喜欢 7 次。

关注

评论

发布
暂无评论
发现更多内容

OneCode开源低代码引擎白皮书

codebee

低代码 开发工具 低代码平台 java UI

宽表为什么横行?

王磊

Three.js 进阶之旅:物理效果-碰撞和声音 💥

dragonir

CSS JavaScript html 前端 three.js

实现一个简单的Database10(译文)

GreatSQL

sqlite myslq greatsql greatsql社区

怎样快速地迁移 MySQL 中的数据?

Java MySQL 数据库

明晚 8 点直播!OpenCloudOS 中的海光国密算法分析

OpenCloudOS

Linux

面试官:你来谈一下Synchronized-轻量级锁

Java synchronized 轻量级锁

基于文心大模型套件ERNIEKit实现文本匹配算法,模块化方便应用落地

汀丶人工智能

自然语言处理 nlp 2月月更 2月日更 文本匹配算法

从实战出发,聊聊缓存数据库一致性

Java 数据库 缓存 一致性

面试官:分库分表,真的有必要吗?

Java 分库分表

分布式事务解决方案

Java 分布式事务 事务

模块六作业

程序员小张

「架构实战营」

OKR之剑·实战篇06:OKR致胜法宝-氛围&业绩双轮驱动(下)

vivo互联网技术

团队管理 OKR

飞桨框架v2.4 API新升级!全面支持稀疏计算、图学习、语音处理等任务

飞桨PaddlePaddle

paddle API 飞桨

软件测试/测试开发 | Selenium多浏览器处理

测试人

软件测试 自动化测试 测试开发 selenium web测试

安全等保二级和三级哪个高?哪个费用更高?

行云管家

网络安全 信息安全 等保 等级保护 等级

Java Map操作解锁新姿势

派大星

ChatGPT入门案例|商务智能对话客服(一)| 社区征文

TiAmo

AI ChatGPT

Redis高级数据结构Stream和HyperLogLog

Java redis stream HyperLogLog

5 步带你入门 GaussDB (DWS) 的 GDS 导入导出

华为云开发者联盟

数据库 华为云 企业号 2 月 PK 榜 华为云开发者联盟

Linux安装ElasticSearch

Geek_7ubdnf

Java elasticsearch

2023年新广州市等保测评机构名单看这里!

行云管家

等级保护 等保测评 广州

软件测试/测试开发 | web自动化测试-执行 JavaScript 脚本

测试人

软件测试 自动化测试 测试开发 Web自动化测试 selenium

Mac 使用brew install zsh 遇到 Error: Command failed with exit 128: git

24号工程师

brew zsh

用这4招优雅的实现Spring Boot 异步线程间数据传递

小小怪下士

Java spring 程序员 springboot

微服务 SpringBoot 整合 Redis GEO 实现附近商户功能

Java redis 微服务 Spring Boot

入门数据分析师的最强秘籍,都在这4本书里!

博文视点Broadview

面试官:如果 MySQL 数据库中的数据丢失,有哪些补救的办法呢?

Java MySQL 数据库

记一次SpringBoot启动优化实践

Java spring Spring Boot

ArkUI新能力,助力应用开发更便捷

HarmonyOS开发者

HarmonyOS

我们是如何构建 Twitter Lite 的?_语言 & 开发_ Nicolas Gallagher_InfoQ精选文章