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

相关文章

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

Ubuntu 24.04 LTS怎么关闭 Ubuntu Pro 更新提示弹窗?

《Ubuntu24.04LTS怎么关闭UbuntuPro更新提示弹窗?》Ubuntu每次开机都会弹窗提示安全更新,设置里最多只能取消自动下载,自动更新,但无法做到直接让自动更新的弹窗不出现,... 如果你正在使用 Ubuntu 24.04 LTS,可能会注意到——在使用「软件更新器」或运行 APT 命令时,

使用Vue.js报错:ReferenceError: “Vue is not defined“ 的原因与解决方案

《使用Vue.js报错:ReferenceError:“Vueisnotdefined“的原因与解决方案》在前端开发中,ReferenceError:Vueisnotdefined是一个常见... 目录一、错误描述二、错误成因分析三、解决方案1. 检查 vue.js 的引入方式2. 验证 npm 安装3.

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,