js增量更新算法研究

2024-09-01 11:58
文章标签 算法 更新 js 增量 研究

本文主要是介绍js增量更新算法研究,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文链接:https://caelumtian.github.io/2017/09/18/js增量更新算法研究/

serviceWorker 方案 - js增量更新算法研究

调研背景
根据之前 serviceWorker 的调研,当服务端文件更新后,serviceWorker 会做对比,并请求这些新的文件。所有发生变化的文件都会被更新。现在 new-mini 内嵌页面,js 都被压缩成了一个文件。这样每次很小的文件改动,都会导致客户端需要下载整个js文件,这样会造成流量的浪费,同时也对服务器造成过大的流量压力。为此我们需要减少更新文件的体积,来更好的完成 serviceWorker 的架构。

js 增量更新算法
利用增量更新算法,我们大大的降低每次文件变动后传输的大小。这里调研了4中常见的js 增量更新算法:

基于chunk的增量更新算法
首先将旧的文件分成n块并并编号
a.png
然后在新文件上进行,滚动查找。如果找到匹配的则记录块号,如果没找到则块往前移动 1 个字符,并把上个字符压入新数据块,然后扫描下一块,最终得到一个新数据和数据块号的组合的增量文件(这一步可以用上线 JavaScript 时用的打包工具或者请求 JavaScript 服务器程序实时计算出来)。
b.png
最终得到的增量文件如下所示:

1, data1, 2, 3, data2, 4, 5, 6

进一步合并顺序快得到:

[1, 1], data1, [2, 2], data2, [4, 4]

客户端根据旧文件的 chunk 数据和增量更新数据,我们可以得出新版本数据由如下数据组成:

chunk0+data1+chunk1+chunk2+data2+chunk3+chunk4+chunk5

例如以 s = ‘‘1345678abcdefghijklmnopq’ 修改为 a = ‘‘13456f78abcd2efghijklmnopq’为例, 设块长度为4 则, 源文件分成:

通过滚动查找,得到新文件

最终增量文件表示如下数组: [“a=‘1”,2,”f”,3,”cd2ef”,5,6,7]。 进一步合并顺序块,可用一个js数组表示为: [“a=‘1”,[2,1],“f”,[3,1],“cd2ef”,[5,3]。
在 serviceWorker 客户端这边,调用如下函数,进行文件更新:

//source 是上一个版本内容,trunkSize 是块大小,checksumcode 是两个版本间的增量文件数组
var rsyncjs = function(source,trunkSize,checksumcode){
var strResult="";
for(var i = 0; i < checksumcode.length; i++){
var code = checksumcode[i];
if(typeof code === ‘string’){
strResult+=code;
}
else{
var start = code[0] * trunkSize;
var len = code[1] * trunkSize;
var oldcode = source.substr(start, len);
strResult += oldcode;
}
}
return strResult;
}
该方法存在的问题为:增量更新的精确度依赖于chunk的大小,在实际使用中总是会有不少代码需要冗余下载。

Myer’s diff algorithm
Myer’s diff algorithm 首次出是在1986年一篇论文中“An O(ND) Difference Algorithm and Its Variations”, 在文中实现上介绍了两种此diff算法 的实现。两种实现的核心思想是一致的,只是在具体的实现过程中,为进一步提升算法的性能及空间利用率,采取了不一致的迭代方式。
算法原理比较复杂,github 上有根据该算法实现的 jsdiff 插件
简单的演示如下:

require(‘colors’);
let jsdiff = require(‘diff’);
let oldStr = ‘bcdsgaff2 123’;
let newStr = ‘accdgadff2 42356’;
let diff = jsdiff.diffChars(oldStr, newStr);
console.log(diff);
diff.forEach(part => {
let color = part.added ? ‘green’ : part.removed ? ‘red’ : ‘gray’;
process.stderr.write(part.value[color]);
})

{% asset_img 5.png %}  
可以清楚的看到差异信息,这里我们利用下面这个函数 简化一下jsdiff输出信息,方便传输。    
```javascript  
function minimizeDiffInfo(originalInfo){let result = originalInfo.map(info => {if(info.added){return '+' + info.value;}if(info.removed){return '-' + info.count;}return info.count;});return JSON.stringify(result);
}
输出结果为:
6.png
客户端,采用如下函数,更新 serviceWorker 中的资源:function mergeDiff(oldString, diffInfo){let newString = '';let diffInfo = JSON.parse(diffInfo);let index = 0;for(var i = 0; i < diffInfo.length; i++){let info = diffInfo[i];if(typeof info === 'number'){newString += oldString.slice(index, index + info);index += info;continue;}if(typeof info === 'string'){if(info[0] === '+'){let addedString = info.slice(1, info.length);newString += addedString;}if(info[0] === '-'){let removedCount = parseInt(info.slice(1, info.length));index += removedCount;}}}return newString;
}
该方案,实际测试结果很糟糕,对于文件很大的内容比对时间都够我睡一觉了。基于编辑距离的比对算法
什么是编辑距离
编辑距离是针对二个字符串(例如英文字)的差异程度的量化量测,量测方式是看至少需要多少次的处理才能将一个字符串变成另一个字符串。编辑距离可以用在自然语言处理中,例如拼写检查可以根据一个拼错的字和其他正确的字的编辑距离,判断哪一个(或哪几个)是比较可能的字。DNA也可以视为用A、C、G和T组成的字符串,因此编辑距离也用在生物信息学中,判断二个DNA的类似程度。Unix 下的 diff 及 patch 即是利用编辑距离来进行文本编辑对比的例子。求解算法
比如要计算cafe和coffee的编辑距离。cafe→caffe→coffe→coffee。先创建一个6×8的表(cafe长度为4,coffee长度为6,各加2):
8.png
接着,在如下位置添加数字
9.png
从3,3格开始,开始计算。取以下三个值的最小值:如果最上方的字符等于最左方的字符,则为左上方的数字。否则为左上方的数字+1。(对于3,3来说为0)
左方数字+1(对于3,3格来说为2)
上方数字+1(对于3,3格来说为2)
因此为格3,3为0:
10.png
循环操作,推出下表:
11.png
取右下角,得编辑距离为3。

这篇关于js增量更新算法研究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1126870

相关文章

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Oracle 通过 ROWID 批量更新表的方法

《Oracle通过ROWID批量更新表的方法》在Oracle数据库中,使用ROWID进行批量更新是一种高效的更新方法,因为它直接定位到物理行位置,避免了通过索引查找的开销,下面给大家介绍Orac... 目录oracle 通过 ROWID 批量更新表ROWID 基本概念性能优化建议性能UoTrFPH优化建议注

VSCode中配置node.js的实现示例

《VSCode中配置node.js的实现示例》本文主要介绍了VSCode中配置node.js的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一.node.js下载安装教程二.配置npm三.配置环境变量四.VSCode配置五.心得一.no

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

Redis中6种缓存更新策略详解

《Redis中6种缓存更新策略详解》Redis作为一款高性能的内存数据库,已经成为缓存层的首选解决方案,然而,使用缓存时最大的挑战在于保证缓存数据与底层数据源的一致性,本文将介绍Redis中6种缓存更... 目录引言策略一:Cache-Aside(旁路缓存)策略工作原理代码示例优缺点分析适用场景策略二:Re

Pandas利用主表更新子表指定列小技巧

《Pandas利用主表更新子表指定列小技巧》本文主要介绍了Pandas利用主表更新子表指定列小技巧,通过创建主表和子表的DataFrame对象,并使用映射字典进行数据关联和更新,实现了从主表到子表的同... 目录一、前言二、基本案例1. 创建主表数据2. 创建映射字典3. 创建子表数据4. 更新子表的 zb

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各