近年来,Instagram发布了许多功能-咱们推出了故事,过滤器,建立工具,通知和消息直递,以及许多其余功能和优化。 可是,随着产品功能的增加,一个不幸的反作用是咱们的网络性能开始降低。 在过去的一年中,咱们有意识地努力来改善这一情况。 到目前为止,咱们的不懈努力已使Feed页的加载时间累计提高了近50%。 这一系列博客文章将概述咱们为实现这些改进所作的一些工做。前端
因为咱们已经在页面加载的尽量早的时间点将数据推送到客户端,所以,将数据发送到客户端的更快的惟一方法就是根本没必要获取或推送任何数据。promise
咱们可使用缓存优先渲染方法来实现,尽管这确实意味着咱们必须在短期内向用户显示陈旧的Feed数据信息。 经过这种方法,当页面加载完毕后,咱们会当即向用户显示其先前的提要和故事的缓存副本,而后在可用时将其替换为新数据。缓存
咱们使用Redux来管理instagram.com上的状态,整体而言,咱们实现该方法的方式是将Redux存储的子集存储在客户端上的indexedDB表中,而后在首次加载页面时从新更新该存储。 可是,因为indexedDB访问、服务器数据获取、用户交互三者间的异步特性,若是用户在缓存数据上进行交互可能会存在问题。可是咱们依旧想确保这些交互仍做用于从服务器获取的新状态数据。bash
例如,若是咱们要以简便的方式处理缓存,则可能会遇到如下问题:咱们开始同时从缓存和网络加载,而且因为已准备好缓存的数据,所以将其显示给用户。 而后,用户点击喜欢该帖子,可是一旦最新的网络数据返回,它就会用一个副本覆盖该帖子,该副本会丢失用户对于缓存副本的操做(请参见下图)。服务器
为了解决此问题,咱们须要一种将交互应用于缓存状态,同时还存储了这些交互,以便之后能够在服务器上的新状态上重放它们。markdown
若是您之前曾经使用过Git或相似的源代码控制系统,则此问题可能看起来很熟悉。 若是咱们将缓存的提要状态视为一个分支,而将服务器提要响应视为主服务器,则咱们有效地要作的是执行一个变基操做,将本地分支中的提交(喜欢,评论等)应用到主分支。网络
咱们作了如下设计:app
经过具备暂存状态,能够从新使用全部现有的reducer行为。 它还使暂存状态(具备最新数据)与当前状态保持独立。 另外,因为分段是使用Redux实现的,所以咱们只须要调度操做便可使用它!异步
function stagingAction( key: string, promise: Promise<Action>, ): AsyncAction<State, Action> function stagingCommit(key: string): AsyncAction<State, Action> 复制代码
Staging API包括两个主要函数: stagingAction & stagingCommit。async
stagingAction接受一个Promise,该Promise将解决要分派到暂存状态的动做。 它初始化暂存状态并跟踪自初始化以来已调度的全部操做。 在源代码控制的类比中,咱们能够将其视为建立本地分支,由于当新数据到达时,如今发生的任何操做都将排队,并应用于暂存状态。
stagingCommit将staging状态提交到current状态。 若是对暂存状态的任何异步操做处于暂挂状态,它将在提交以前等待。 这相似于源代码管理中的变基,由于咱们将全部本地更改(来自缓存分支)应用在主服务器(服务器中的新数据)之上,使本地分支保持最新状态。
为了启用staging,咱们用处理stagingCommit动做并将stage的动做应用于新状态。 要使用全部这些,咱们只须要调度相关的动做,一切都将为咱们处理。 例如,若是咱们要获取一个新的feed并将其应用于暂存状态,则能够执行如下操做:
function fetchAndStageFeed() { return stagingAction( 'feed', (async () => { const {data} = await fetchFeedTimeline(); return { type: FEED_LOADED, ...data, }; })(), ); } // Fetches the new feed and stages it store.dispatch(fetchAndStageFeed()); // any other actions dispatched until the stagingCommit action // will be applied to the 'feed' staged state // Commits staging to the current state store.dispatch(stagingCommit('feed')); 复制代码
对Feed和Stories功能同时使用缓存优先渲染功能,分别使显示完成时间缩短了2.5%和11%,并经过本机iOS和Android Instagram应用提供了更好的用户体验。
在第四部分,咱们讲介绍如何裁剪代码大小,而且经过代码大小和执行优化提高性能。
请关注奶爸码农公众号,第一时间得到最新信息。
『奶爸码农』从事互联网研发工做10+年,经历IBM、SAP、陆金所、携程等国内外IT公司,目前在美团负责餐饮相关大前端技术团队,按期分享关于大前端技术、投资理财、我的成长的思考与总结