当我们将游戏构建发布到web平台时,勾选Md5 Cache选项可以开启MD5 Pipe,它的作用是给构建后的资源加上md5后缀,避免浏览器的缓存导致部分资源不是最新,因为使用了md5后缀后,当资源内容发生变化时,资源的名字就不一样了,缓存就会失效。

比如6e056173-d285-473c-b206-40a7fff5386e.json,在开启了MD5 Cache选项之后再构建会生成6e056173-d285-473c-b206-40a7fff5386e.a548e.json,在文件后缀.json前加上了一个简化的md5——a548e。

开启 MD5 PIPE

勾选了Md5 Cache选项后进行构建,生成的web-mobile/src/settings.xxx.js文件中会设置一个全局变量_CCSettings,该变量中有一个md5AssetsMap字段记录所有资源文件的简化md5。

    md5AssetsMap: {
"08/08ddbd1c9.json": "ade93",
"6e/6e056173-d285-473c-b206-40a7fff5386e.json": "a548e",
"assets/6e/6e056173-d285-473c-b206-40a7fff5386e.png": "68270"
}

在Creator生成的main.xxx.js中会获取_CCSettings变量进行处理,一个关键的地方就是cc.AssetLibrary.init,将settings.md5AssetsMap传入AssetLibrary。

cc.AssetLibrary.init({
libraryPath: 'res/import',
rawAssetsBase: 'res/raw-',
rawAssets: settings.rawAssets,
packedAssets: settings.packedAssets,
md5AssetsMap: settings.md5AssetsMap
});

在cc.AssetLibrary.init中,根据md5AssetsMap变量决定是否创建MD5Pipe,将md5Pipe插入到cc.loader.assetLoader之后。

    var md5AssetsMap = options.md5AssetsMap;
if (md5AssetsMap) {
var md5Pipe = new MD5Pipe(md5AssetsMap, _libraryBase, _rawAssetsBase);
cc.loader.insertPipeAfter(cc.loader.assetLoader, md5Pipe);
cc.loader.md5Pipe = md5Pipe;
}

在一些核心模块中,我们可以看到直接使用url时,都会检测是否存在cc.loader.md5Pipe,有则调用其transformURL对url进行处理,比如CCVideoPlayer.js,这些处理属于不走Pipeline的路径处理,属于这些组件的内部逻辑。

    _updateVideoSource: function () {
var sgNode = this._sgNode;
let url = '';
if (this.resourceType === ResourceType.REMOTE) {
url = this.remoteURL;
}
else if (this._clip) {
url = this._clip.nativeUrl || '';
}
if (url && cc.loader.md5Pipe) {
url = cc.loader.md5Pipe.transformURL(url);
}
sgNode.setURL(url);
},

MD5 PIPE的实现

Md5 Pipe的实现非常简单(位于load-pipeline下的md5-pipe.js),它只对res/import或res/raw-开头的url进行处理,根据md5AssetsMap对应的精简md5值,重新组装url。

MD5Pipe.prototype.transformURL = function (url, hashPatchInFolder) {
var index = url.indexOf('?');
var key = url;
if (index !== -1) {
key = url.substr(0, index);
}
// 如果是以libraryBase开头'res/import',去掉这个前缀
if (key.startsWith(this.libraryBase)) {
key = key.slice(this.libraryBase.length);
// 如果是以rawAssetsBase开头'res/raw-',也去掉这个前缀
} else if (key.startsWith(this.rawAssetsBase)) {
key = key.slice(this.rawAssetsBase.length);
} else {
// 其他情况不处理,比如是一个完整的http链接
return url;
} // 取出该资源对应的精简md5
let hashValue = this.md5AssetsMap[key];
if (hashValue) {
// 如果hashPatchInFolder为true则将这个md5组装到目录下
// JSB下的Spine、Label都有使用hashPatchInFolder
if (hashPatchInFolder) {
var dirname = cc.path.dirname(url);
var basename = cc.path.basename(url);
url = `${dirname}.${hashValue}/${basename}`;
} else {
// 正常情况是将精简md5插入到文件扩展名之前
var matched = false;
url = url.replace(ExtnameRegex, (function(match, p1) {
matched = true;
return "." + hashValue + p1;
}));
if (!matched) {
url = url + "." + hashValue
}
}
}
return url;
};

Cocos Creator 资源加载流程剖析【四】——额外流程(MD5 PIPE)的更多相关文章

  1. Cocos Creator 资源加载流程剖析【一】——cc.loader与加载管线

    这系列文章会对Cocos Creator的资源加载和管理进行深入的剖析.主要包含以下内容: cc.loader与加载管线 Download部分 Load部分 额外流程(MD5 Pipe) 从编辑器到运 ...

  2. Cocos Creator 资源加载流程剖析【二】——Download部分

    Download流程的处理由Downloader这个pipe负责(downloader.js),Downloader提供了各种资源的"下载"方式--即如何获取文件内容,有从网络获取 ...

  3. Cocos Creator 资源加载流程剖析【三】——Load部分

    Load流程是整个资源加载管线的最后一棒,由Loader这个pipe负责(loader.js).通过Download流程拿到内容之后,需要对内容做一些"加载"处理.使得这些内容可以 ...

  4. Cocos Creator 资源加载流程剖析【六】——场景切换流程

    这里讨论场景切换的完整流程,从我们调用了loadScene开始切换场景,到场景切换完成背后发生的事情.整个流程可以分为场景加载和场景切换两部分,另外还简单讨论了场景的预加载. 加载场景的流程 load ...

  5. Cocos Creator 资源加载流程剖析【五】——从编辑器到运行时

    我们在编辑器中看到的资源,在构建之后会进行一些转化,本章将揭开Creator对资源进行的处理. 资源处理的整体规则 首先我们将Creator的开发和运行划分为以下几个场景: 编辑器 当我们将资源放到编 ...

  6. Cocos Creator 资源加载(笔记)

    cc.loader 加载资源动态加载资源要注意两点,一是所有需要通过脚本动态加载的资源,都必须放置在 resources 文件夹或它的子文件夹下.resources 需要在 assets 文件夹中手工 ...

  7. 【原】从一个bug浅谈YUI3组件的资源加载

    篇前声明:为了不涉及业务细节,篇内信息统一以某游戏,某功能代替 前不久,某游戏准备内测客户端,开发人员测试过程中发现某功能突然不灵了,之前的测试一切ok,没有发现任何异常,第一反应是,游戏内浏览器都是 ...

  8. 记一次cocos项目的加载速度优化

    半个月前,我们用cosos creator做了一个简单的小游戏,也许算不上小游戏吧..一边学cocos,一边做,几经波折后终于上线了.然鹅,功能是实现了,但是加载速度十分感人(毕竟没经验嘛,无辜脸). ...

  9. 细谈unity资源加载和卸载

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.概要 在了解unity的资源管理方式之后,接下来细谈一下Unity的资源是如何从磁盘中加载到运行时的内存中,以及又是如 ...

随机推荐

  1. 【软件工具】easyExcel简明使用指南

    easyExcel简介 Java领域解析.生成Excel比较有名的框架有Apache poi.jxl等.但他们都存在一个严重的问题就是非常的耗内存.如果你的系统并发量不发的话可能还行,但是一旦并发上来 ...

  2. 在开发Thinkphp5.0智慧软文个人微信个人支付宝企业支付宝接口时遇到的坑

    在开发Thinkphp5.0智慧软文个人微信个人支付宝企业支付宝接口时遇到回调后提示成功但是不能自动充值的情况,现在记录一下: 两种情况 1.个人支付宝  个人微信遇到的情况 因为个人支付宝 个人微信 ...

  3. PAT甲级专题|链表

    PAT链表专题 关于PAT甲级的链表问题,主要内容 就是"建立链表" 所以第一步学会模拟链表,pat又不卡时间,这里用vector + 结构体,更简洁 模拟链表的普遍代码 cons ...

  4. Java判断字符串相等"=="和"equal"详解

    在初学Java时,可能会经常碰到下面的代码: public static void main(String[] args) { //两种声明方式,有所差别 String s1="hello& ...

  5. Asp.net Core 3.0 Identity 使用smtp账户确认和密码恢复

    当新建一个core项目后,使用identity基架后,确认邮件出现了错误,并不能正常使用. 建立文档在这里 https://docs.microsoft.com/zh-cn/aspnet/core/s ...

  6. redis数据类型--hash

    /** Redis应用之Hash数据类型* 问题1:操作命令* 问题2:存储实现原理和数据结构* 问题3:应用场景* */ 先了解下什么是hash,什么是hash碰撞:hash:是包含键值对的kv的数 ...

  7. luogu P2650 弹幕考察

    题意简化:求某个区间在一组区间中覆盖的数量 对于这个问题,我们很容易想到线段树,或者树状数组,但是maxlongint不能让我们这么做 30分思路: 对于m个区间,枚举n个区间判断与它是否重合 但是O ...

  8. nbuoj 2080 洛谷p1025 数的划分

    链接:http://www.nbuoj.com/v8.83/Problems/Problem.php?pid=2820 链接:https://www.luogu.org/problem/P1025 题 ...

  9. BZOJ1014 火星人的prefix

    火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字 ...

  10. ARTS-S cmake,googletest使用

    编译gtest 下载指定tag的源代码 git clone https://github.com/google/googletest.git cd googletest git checkout ta ...