实现思路:
- 大文件根据一定的规则拆分成小文件,所有小文件加载完成后,再根据拆分规则,合并处理成自己想要的数据格式
- 不通过import require script等方式导入文件,而是通过 XMLHttpRequest 的方式请求文件,在请求头上添加 cache-control: max-age=50000 (时间自己视情况配置)
实现案例
文件拆分
主要展示js的代码
import fontJson from "./HanaMinA_Regular.js";
setTimeout(() => {
// 根据拆分 规则 对文件内容 进行拆分
let font = Object.keys(fontJson.glyphs);
let fontPropertype = {};
for (const fontKey in fontJson) {
if (fontKey != "glyphs") {
fontPropertype[fontKey] = fontJson[fontKey];
}
else {
fontPropertype[fontKey] = {};
}
}
let fontChinese = font.filter((element, index, array) => {
return /[\u4E00-\u9FA5]/.test(element);
});
let fontEnglish = font.filter((element, index, array) => {
return /[a-zA-Z0-9]/.test(element);
});
let fontSignString1 = /[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~]/im;
let fontSignString2 = /[!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/im;
let fontSign = font.filter((element, index, array) => {
return fontSignString1.test(element) || fontSignString2.test(element);
});
let fontOther = font.filter((element, index, array) => {
return !fontChinese.includes(element) && !fontEnglish.includes(element) && !fontSign.includes(element);
});
alert("加载结束");
function getFontInfo(fontNameArray) {
let _map = {};
for (let i = 0 ; i < fontNameArray.length ; i++) {
_map[fontNameArray[i]] = fontJson.glyphs[fontNameArray[i]];
}
return _map;
}
// 注册点击事件 生成并下载指定的文件
let time = new Date().getTime()
document.getElementById("btn").onclick = function () {
let fontChineseMap = getFontInfo(fontChinese);
exportFile("fontChinese", fontChineseMap);
let fontEnglishMap = getFontInfo(fontEnglish);
exportFile("fontEnglish", fontEnglishMap);
let fontSignMap = getFontInfo(fontSign);
exportFile("fontSign", fontSignMap);
let fontOtherMap = getFontInfo(fontOther);
exportFile("fontOther", fontOtherMap);
exportFile("fontPropertype", fontPropertype);
};
// 生成并下载指定的文件
function exportFile(filename, data) {
//let content = 'export default ' + JSON.stringify(data)
let content = JSON.stringify(data)
let file = new Blob([content], {type : "text/plain"});
let download = document.getElementById("download");
download.download = time + "-" + filename + ".js";
download.href = window.URL.createObjectURL(file);
download.click();
}
}, 1000);
加载拆分的文件
//请求数组
let ajaxPromiseArray = [];
// runAjax是主要的执行Ajax的函数;
let addAjaxPromise = function (options) {
let xhrPromise = new Promise(resolve => {
let xhr = new XMLHttpRequest();
xhr.open(options.method, options.url, true);
// 此处是重点 !!!
xhr.setRequestHeader('cache-control', 'max-age=50000');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 304)) {
//执行回调方法
resolve(xhr);
}
};
xhr.send(options.data || null);
});
ajaxPromiseArray.push(xhrPromise);
};
//添加请求 1676354806849 -xxx 是已经拆分好的文件
addAjaxPromise({method : "GET", url : "./1676354806849-fontChinese.js"});
addAjaxPromise({method : "GET", url : "./1676354806849-fontEnglish.js"});
addAjaxPromise({method : "GET", url : "./1676354806849-fontOther.js"});
addAjaxPromise({method : "GET", url : "./1676354806849-fontSign.js"});
addAjaxPromise({method : "GET", url : "./1676354806849-fontPropertype.js"});
Promise.all(ajaxPromiseArray).then(res => {
// 这是我自己需要的数据格式, 自己的数据格式自己处理一下
let _object = {};
let glyphs = {}
for (let i = 0 ; i < res.length ; i++) {
let fileName = JSON.parse(res[i].response);
if (!fileName['familyName']){
glyphs = Object.assign(glyphs, fileName);
}else {
_object = fileName
}
}
_object.glyphs = glyphs
document.write('加载成功')
});
注意:
文件 | 大小 | 处理 | 结果 |
---|---|---|---|
HanaMinA_Regular.js | 62M左右 | Http 请求并添加请求头处理 | 不缓存 |
fontChinese.js(拆分后的文件) | 38M左右 | Http 请求并添加请求头处理 | 缓存 |
我也把js 缓存json试了,结果一样
找了好多资料,只找到了 浏览器缓存的视频文件大小 大概在10M 左右,也没找打浏览器对于各种文件的缓存大小限制到底是多少,有知道的大神可以在评论告诉我一下吗?