返回顶部
首页 > 资讯 > 前端开发 > node.js >如何实现web前端资源增量式更新
  • 227
分享到

如何实现web前端资源增量式更新

2024-04-02 19:04:59 227人浏览 泡泡鱼
摘要

这篇文章主要讲解了“如何实现web前端资源增量式更新”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现WEB前端资源增量式更新”吧!之前校招面试的时候遇

这篇文章主要讲解了“如何实现web前端资源增量式更新”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现WEB前端资源增量式更新”吧!

之前校招面试的时候遇到过一个很有趣的问题:

“假设有一个超超超大型的Web项目js源代码压缩之后超过10MB(实际怎么可能会有这么大的嘛=。=),每次更新之后都需要用户重新加载JS是不可接受的,那么怎么样从工程的角度解决这种问题?”

一开始立马想到了好几点解决方案,比如:

  1. 抽出基础的不常更新的模块作为长期缓存;

  2. 如果使用了 React 或者 Vue2.0 这样支持服务器端渲染的框架的话,就采用服务器端渲染然后再逐步分块加载 JS 的方法;

  3. 如果是 Hybrid 开发的话,可以考虑使用本地资源加载,类似“离线包”的想法(之前在腾讯实习的时候天天遇到这东西)。

后来在面试官的引导下想到了一种“增量式更新”的解决方案,简单地说就是在版本更新的时候不需要重新加载资源,只需要加载一段很小的 diff  信息,然后合并到当前资源上,类似 git merge 的效果。

1、用户端使用 LocalStorage 或者其它储存方案,存储一份原始代码+时间戳:

{      timeStamp: "20161026xxxxxx",      data: "aaabbbccc"  }

2、每次加载资源的时候向服务器发送这个时间戳;

3、服务器从接受到时间戳中识别出客户端的版本,和***的版本做一次 diff,返回两者的 diff 信息:

diff("aaabbbccc", "aaaggGCcc");  // 假设我们的diff信息这样表示:  // [3, "-3", "+ggg", 3]

4、客户端接收到这个 diff 信息之后,把本地资源和时间戳更新到***,实现一次增量更新:

mergeDiff("aaabbbccc", [3, "-3", "+ggg", 3]);  //=> "aaagggccc"

实践

下面把这个方案中的核心思想实现一遍,简单地说就是实现 diff 和 mergeDiff 两个函数。

今天找到了一个不错的 diff 算法

GitHub – kpdecker/jsdiff: A javascript text differencing implementation.

我们只需要调用它的 diffChars 方法来对比两个字符串的差异:

var oldStr = 'aaabbbccc';  var newStr = 'aaagggccc';  JsDiff.diffChars(oldStr, newStr);  //=>  //[ { count: 3, value: 'aaa' },  //  { count: 3, added: undefined, removed: true, value: 'bbb' },  //  { count: 3, added: true, removed: undefined, value: 'ggg' },  //  { count: 3, value: 'ccc' } ]

上面的 diff 信息略有些冗余,我们可以自定义一种更简洁的表示方法来加速传输的速度:

[3, "-3", "+ggg", 3]

整数代表无变化的字符数量,“-”开头的字符串代表被移除的字符数量,“+”开头的字符串代表新加入的字符。所以我们可以写一个 minimizeDiffInfo  函数:

function minimizeDiffInfo(originalInfo){      var result = originalInfo.map(info => {          if(info.added){              return '+' + info.value;          }          if(info.removed){              return '-' + info.count;          }          return info.count;      });      return JSON.stringify(result);  }     var diffInfo = [      { count: 3, value: 'aaa' },      { count: 3, added: undefined, removed: true, value: 'bbb' },      { count: 3, added: true, removed: undefined, value: 'ggg' },      { count: 3, value: 'ccc' }  ];  minimizeDiffInfo(diffInfo);  //=> '[3, "-3", "+ggg", 3]'

用户端接受到精简之后的 diff 信息,生成***的资源:

mergeDiff('aaabbbccc', '[3, "-3", "+ggg", 3]');  //=> 'aaagggccc'     function mergeDiff(oldString, diffInfo){      var newString = '';      var diffInfo = JSON.parse(diffInfo);      var p = 0;      for(var i = 0; i < diffInfo.length; i++){          var info = diffInfo[i];          if(typeof(info) == 'number'){              newString += oldString.slice(p, p + info);              p += info;              continue;          }          if(typeof(info) == 'string'){              if(info[0] === '+'){                  var addedString = info.slice(1, info.length);                  newString += addedString;              }              if(info[0] === '-'){                  var removedCount = parseInt(info.slice(1, info.length));                  p += removedCount;              }          }      }      return newString;  }

实际效果

有兴趣的话可以直接运行这个:

GitHub &ndash; starkwang/Incremental

使用 create-react-app 这个小工具快速生成了一个 React 项目,随便改了两行代码,然后对比了一下build之后的新旧两个版本:

var JsDiff = require('diff');  var fs = require('fs');     var newFile = fs.readFileSync('a.js', 'utf-8');  var oldFile = fs.readFileSync('b.js', 'utf-8');  console.log('New File Length: ', newFile.length);  console.log('Old File Length: ', oldFile.length);     var diffInfo   = getDiffInfo(JsDiff.diffChars(oldFile, newFile));  console.log('diffInfo Length: ', diffInfo.length);  console.log(diffInfo);     var result = mergeDiff(oldFile, diffInfo);  console.log(result === newFile);

下面是结果:

如何实现web前端资源增量式更新

可以看到 build 之后的代码有 21w 多个字符(212KB),而 diff  信息却相当短小,只有151个字符,相比于重新加载新版本,缩小了1000多倍(当然我这里只改了两三行代码,小是自然的)。

一些没涉及到的问题

上面只是把核心的思路实现了一遍,实际工程中还有更多要考虑的东西:

1、服务器不可能对每一次请求都重新计算一次 diff,所以必然要对 diff 信息做缓存;

2、用户端持久化储存的实现方案,比如喜闻乐见的 LocalStorage、Indexed DB、Web sql,或者使用 native app  提供的接口;

3、容错、用户端和服务器端的一致性校对、强制刷新的实现。

感谢各位的阅读,以上就是“如何实现web前端资源增量式更新”的内容了,经过本文的学习后,相信大家对如何实现web前端资源增量式更新这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: 如何实现web前端资源增量式更新

本文链接: https://lsjlt.com/news/85967.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何实现web前端资源增量式更新
    这篇文章主要讲解了“如何实现web前端资源增量式更新”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现web前端资源增量式更新”吧!之前校招面试的时候遇...
    99+
    2024-04-02
  • 前端音频可视化Web Audio如何实现
    这篇文章主要介绍“前端音频可视化Web Audio如何实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“前端音频可视化Web Audio如何实现”文章能帮助大家解决问题。实现思路...
    99+
    2023-07-05
  • web前端如何实现360度全景效果
    今天小编给大家分享一下web前端如何实现360度全景效果的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。使用插件:photo-...
    99+
    2023-07-05
  • php如何实现前端统计流量
    这篇文章将为大家详细讲解有关php如何实现前端统计流量,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。php实现前端统计流量的方法:1、创建一个PHP示例文件;2、定义变量;3、读取数据;4、判断是否已过去...
    99+
    2023-06-22
  • 如何在web前端里实现打字机插件
    这篇文章主要介绍了如何在web前端里实现打字机插件的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何在web前端里实现打字机插件文章都会有所收获,下面我们一起来看看吧。最简单的打字机const dom = do...
    99+
    2023-07-05
  • MySQL如何实现数据批量更新
    最近需要批量更新大量数据,习惯了写sql,所以还是用sql来实现,下面这篇文章主要给大家总结介绍了关于MySQL批量更新的方式,需要的朋友可以参考下 根据不同条件批量更新同一值 这种场景直接通过update语句更新即可,如: 1 UP...
    99+
    2023-10-20
    mysql 数据库
  • springboot vue测试平台接口定义前后端新增功能如何实现
    这篇文章主要介绍“springboot vue测试平台接口定义前后端新增功能如何实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“springboot vue测试平台接口定义前后...
    99+
    2023-06-30
  • 如何使用scrapy实现增量式爬取
    本篇内容主要讲解“如何使用scrapy实现增量式爬取”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用scrapy实现增量式爬取”吧!1.要爬取的信息在scrapy中,信息通过item来封装...
    99+
    2023-07-02
  • vue如何实现web前端登录页数字验证码
    这篇文章主要讲解了“vue如何实现web前端登录页数字验证码”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue如何实现web前端登录页数字验证码”吧!创建code.js文件夹下面是js代码...
    99+
    2023-07-02
  • MySQL如何实现数据批量更新功能
    本篇内容主要讲解“MySQL如何实现数据批量更新功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL如何实现数据批量更新功能”吧!根据不同条件批量更新同一值这种场景直接通过update语...
    99+
    2023-07-05
  • python如何实现Mysql数据库批量新增数据
    本篇内容主要讲解“python如何实现Mysql数据库批量新增数据”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python如何实现Mysql数据库批量新增数据”吧!一、批量插入数据的场景在进行...
    99+
    2023-06-29
  • web开发中如何实现前端隐藏出边界内容
    这篇文章将为大家详细讲解有关web开发中如何实现前端隐藏出边界内容,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前端隐藏出边界内容的实现方法关于“web开发中如何实现前端...
    99+
    2024-04-02
  • 详细聊聊前端如何实现token无感刷新(refresh_token)
    目录关于无感刷新的理解: 下面是关于使用vuex来实现的写法axios工具函数(请求拦截器与响应拦截器)总结关于无感刷新的理解:  实现token无感刷新对于前端...
    99+
    2022-11-13
    前端无感知刷新token 前端自动刷新token 前端怎么刷新token
  • 如何使用Redis实现分布式缓存更新
    如何使用Redis实现分布式缓存更新在分布式系统中,缓存起到了重要的作用,可以大大提升系统的性能和可扩展性。而Redis作为一种高性能的内存数据库,常用于分布式缓存的实现。本文将为您介绍如何使用Redis实现分布式缓存的更新,并给出具体的代...
    99+
    2023-11-07
    分布式 redis 缓存更新
  • vue3如何使用keep alive实现前进更新后退销毁
    这篇文章主要讲解了“vue3如何使用keep alive实现前进更新后退销毁”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue3如何使用keep alive实现前进更新...
    99+
    2023-06-30
  • 如何使用notify+rsync实现linux文件批量更新
    这篇文章主要介绍“如何使用notify+rsync实现linux文件批量更新”,在日常操作中,相信很多人在如何使用notify+rsync实现linux文件批量更新问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答...
    99+
    2023-06-28
  • MyBatis批量查询、插入、更新、删除如何实现
    今天小编给大家分享的是MyBatis批量查询、插入、更新、删除如何实现,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。1.批量查询提供两种方式。方式一,返回值: List<Cit...
    99+
    2023-07-06
  • 如何实现网站Web端表单的交互式设计
    这篇文章主要介绍“如何实现网站Web端表单的交互式设计”,在日常操作中,相信很多人在如何实现网站Web端表单的交互式设计问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何实现网站Web端表单的交互式设计”的疑...
    99+
    2023-06-10
  • 如何在MyBatis中实现数据的批量新增和删除
    这期内容当中小编将会给大家带来有关如何在MyBatis中实现数据的批量新增和删除,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。创建UserMapper接口(用户信息Mapper动态代理接口),实现用户信息...
    99+
    2023-06-06
  • Vue.set()如何实现动态新增与修改数据以及触发视图更新
    小编给大家分享一下Vue.set()如何实现动态新增与修改数据以及触发视图更新,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!参数...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作