前端遇上Go: 静态资源增量更新的新实践

开发者盛宴来袭!7月28日51CTO首届开发者大赛决赛带来技术创新分享

 为什么要做增量更新

美团金融的业务在过去的一段时间里发展非常快速。在业务增长的同时,我们也注意到,很多用户的支付环境,其实是在弱网环境中的。

大家知道,前端能够服务用户的前提是 JavaScript 和 CSS 等静态资源能够正确加载。如果网络环境恶劣,那么我们的静态资源尺寸越大,用户下载失败的概率就越高。

根据我们的数据统计,我们的业务中有2%的用户流失与资源加载有关。因此每次更新的代价越小、加载成功率越高,用户流失率也就会越低,从而就能够变相提高订单的转化率。

作为一个发版频繁的业务,要降低发版的影响,可以做两方面优化:

更高效地使用缓存,减少静态资源的重复下载。

使用增量更新,降低单次发版时下发的内容尺寸。

针对第一点,我们有自己的模块加载器来做,这里先按下不表,我们来重点聊聊增量更新的问题。

增量更新是怎么一个过程

看图说话。

前端遇上Go: 静态资源增量更新的新实践

增量更新的客户端流程图

我们的增量更新通过在浏览器端部署一个 SDK 来发起,这个 SDK 我们称之为 Thunder.js 。

Thunder.js 在页面加载时,会从页面中读取最新静态资源的版本号。同时, Thunder.js 也会从浏览器的缓存(通常是 localStorage)中读取我们已经缓存的版本号。这两个版本号进行匹配,如果发现一致,那么我们可以直接使用缓存当中的版本;反之,我们会向增量更新服务发起一个增量补丁的请求。

增量服务收到请求后,会调取新旧两个版本的文件进行对比,将差异作为补丁返回。Thunder.js 拿到请求后,即可将补丁打在老文件上,这样就得到了新文件。

总之一句话:老文件 + 补丁 = 新文件。

增量补丁的生成,主要依赖于 Myers 的 diff 算法。生成增量补丁的过程,就是寻找两个字符串最短编辑路径的过程。算法本身比较复杂,大家可以在网上找一些比较详细的算法描述,比如这篇 《The Myers diff algorithm》,这里就不详细介绍了。

补丁本身是一个微型的 DSL(Domain Specific Language)。这个 DSL 一共有三种微指令,分别对应保留、插入、删除三种字符串操作,每种指令都有自己的操作数。

例如,我们要生成从字符串“abcdefg”到“acdz”的增量补丁,那么一个补丁的全文就类似如下:

=1\t-1\t=2\t-3\t+z

这个补丁当中,制表符\t是指令的分隔符,=表示保留,-表示删除,+表示插入。整个补丁解析出来就是:

保留1个字符

删除1个字符

保留2个字符

删除3个字符

插入1个字符:z

具体的 JavaScript 代码就不在这里粘贴了,流程比较简单,相信大家都可以自己写出来,只需要注意转义和字符串下标的维护即可。

增量更新其实不是前端的新鲜技术,在客户端领域,增量更新早已经应用多年。看过我们《美团金融扫码付静态资源加载优化实践》的朋友,应该知道我们其实之前已有实践,在当时仅仅靠增量更新,日均节省流量达30多GB。而现在这个数字已经随着业务量变得更高了。

那么我们是不是就已经做到万事无忧了呢?

我们之前的增量更新实践遇到了什么问题

我们最主要的问题是增量计算的速度不够快。

之前的优化实践中,我们绝大部分的优化其实都是为了优化增量计算的速度。文本增量计算的速度确实慢,慢到什么程度呢?以前端比较常见的JS资源尺寸——200KB——来进行增量计算,进行一次增量计算的时间依据文本不同的数量,从数十毫秒到十几秒甚至几十秒都有可能。

对于小流量业务来说,计算一次增量补丁然后缓存起来,即使第一次计算耗时一些也不会有太大影响。但用户侧的业务流量都较大,每月的增量计算次数超过 10 万次,并发计算峰值超过 100 QPS 。

那么不够快的影响是什么呢?

前端遇上Go: 静态资源增量更新的新实践

我们之前的设计大致思想是用一个服务来承接流量,再用另一个服务来进行增量计算。这两个服务均由 Node.js 来实现。对于前者, Node.js 的事件循环模型本就适合进行 I/O 密集型业务;然而对于后者,则实际为 Node.js 的软肋。 Node.js 的事件循环模型,要求 Node.js 的使用必须时刻保证 Node.js 的循环能够运转,如果出现非常耗时的函数,那么事件循环就会陷入进去,无法及时处理其他的任务。常见的手法是在机器上多开几个 Node.js 进程。然而一台普通的服务器也就8个逻辑CPU而已,对于增量计算来说,当我们遇到大计算量的任务时,8个并发可能就会让 Node.js 服务很难继续响应了。如果进一步增加进程数量,则会带来额外的进程切换成本,这并不是我们的最优选择。

更高性能的可能方案

“让 JavaScript 跑的更快”这个问题,很多前辈已经有所研究。在我们思考这个问题时,考虑过三种方案。

Node.js Addon

相关推荐
新闻聚焦
猜你喜欢
热门推荐
  • 微软AI面试题有多难?这里有一份样卷

      究竟什么样的AI人才能被微软这样的巨头聘用呢?今天,文摘君就淘来了几道微软AI 面试题,同时给出了最基本的解答......

    06-25    来源:澎湃新闻网

    分享
  • 全球最聪明的大脑怎么看AI?他们预测了

      2017年AI领域取得了诸多成果。2018年AI又将何去何从?以下是来自世界顶级研究人员和行业领军人物对2018年AI领域发展作......

    02-20    来源:虎嗅网

    分享
  • 2017JavaScript框架战报 - React分战场

      我们来看看与React有关的软件包的生态系统。当Facebook构建React时,就有许多来自开源社区的第三方软件包。为提供完......

    02-27    来源:湖北新闻网

    分享
  • 小白学数据:教你用Python实现简单监督学

      监督学习作为运用最广泛的机器学习方法,一直以来都是从数据挖掘信息的重要手段。即便是在无监督学习兴起的近......

    03-05    来源:今日头条

    分享
  • 现代编程语言Swift、Kotlin等十大有趣功能

      最近学习了一些现代编程语言,比如Reason,Swift,Kotlin和Dart。这些编程语言提供了许多新功能,本文主要分享了我认......

    04-29    来源:祁东新闻网

    分享
  • 领域场景分析的6W模型

      组成场景的要素常常被称之为6W模型,即描写场景的过程必须包含Who,What,Why,Where,When与hoW这六个要素。......

    04-30    来源:砍柴网

    分享
  • 开源应用服务器WildFly 12发新季度交付模式

      WildFly 12 Final版本现在已经可以下载了,WildFly是一款灵活的开源应用服务器,支持开发人员构建轻量级应用程序。支持......

    05-10    来源:青岛新闻网

    分享
  • 基于Spring Cloud的微服务落地

      微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务。但如果要将微服务架构运用到生产项目上,......

    06-04    来源:广西新闻网

    分享
  • 为什么阿里工程师纷纷在内网晒代码?

      前阵子,在阿里一个小黑屋里,5名对代码有着极致追求的工程师参与阿里代码领域最高荣誉“多隆奖”的最终角逐。......

    06-08    来源:四川新闻网

    分享
  • 央企Car Hacking Team诚招各路安全大咖

      传统安全行业做腻了?这里有新鲜、有趣、好玩的岗位等你来挑战!“数”驱产业变革“智”领汽车未来中国汽车技......

    02-24    来源:西安新闻网

    分享
返回列表
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。