如何解析本地存储的大型json外部文件(约30 MB)以填充选择下拉列表,从而避免长加载时间



我试图解析一个JSON文件,该文件有大约209579个对象(大约30MB的文件大小(,并使用select选项标记在下拉菜单中填充这些对象(名称和值属性(。我可以使用jquery getJSON方法来解析整个文件,并使用传统的针对DOM元素的方式来解析和填充它,但当我选择下拉菜单时,显示内容的时间太长,并在这段时间内禁用浏览器。

我尝试过使用一个较小的数据集,其中有大约100个对象(明显更少(,页面快速呈现下拉列表,不会滞后。这就是为什么我认为我有一个问题,因为我的大型JSON对象数据集。

<!--html code-->
<h3>Select your Location:</h3>
<select id="locality-dropdown" name="locality">
</select>
//referenced from https://www.codebyamir.com/blog/populate-a-select-dropdown-list-with-json 
//(I have used the same technique)
let dropdown = document.getElementById('locality-dropdown');
dropdown.length = 0;
let defaultOption = document.createElement('option');
defaultOption.text = 'Choose State/Province';
dropdown.add(defaultOption);
dropdown.selectedIndex = 0;
const url = 'js/city_list1.json';
fetch(url)  
.then(  
function(response) {  
if (response.status !== 200) {  
console.warn('Looks like there was a problem. Status Code: ' + 
response.status);  
return;  
}
// Examine the text in the response  
response.json().then(function(data) {  
let option;
for (let i = 0; i < data.length; i++) {
option = document.createElement('option');
option.text = data[i].name;
option.value = data[i].id;
dropdown.add(option);
}    
});  
}  
)  
.catch(function(err) {  
console.error('Fetch Error -', err);  
});

我希望像在普通网站中一样呈现下拉菜单,但在我的情况下,当我点击下拉菜单时,浏览器会停止响应,并需要一段时间才能加载下拉菜单中的内容。

正如您自己所指出的,您的案例中的瓶颈是您试图同时加载整个数据集。您应该考虑将数据加载到页面(块(中,并且可能有一个窗口组件,只加载/呈现当前显示的数据。

正如其他人所指出的那样,JSON并不是存储巨大数据集的最佳格式,数据库要好得多,即使是像SQLite这样简单和小的东西也能做到

但是,如果您仍然喜欢继续使用JSON,我建议您尝试中的一个库,该库允许您解析部分JSON块,并在某种程度上模仿使用数据库和分页加载数据时的情况。

以流json(NodeJS模块,但我想人们可以很容易地为所有后端技术找到类似的东西(为例。

streamjson是node.js流组件的微库创建面向的自定义数据处理器的最小依赖关系处理巨大的JSON文件,同时需要最小的内存占用。它可以解析远远超过可用内存的JSON文件。即使单个基元数据项(键、字符串和数字(可以是逐段流动。

const { chain } = require('stream-chain')
const { parser } = require('stream-json')
const { pick } = require('stream-json/filters/Pick')
const { streamValues } = require('stream-json/streamers/StreamValues')
const fs = require('fs')
const pipeline = chain([
fs.createReadStream('sample.json'),
parser(),
pick({ filter: 'data' }),
streamValues(),
data => {
const value = data.value
return value && value.department === 'accounting' ? data : null
}
])
let counter = 0
pipeline.on('data', () => ++counter)
pipeline.on('end', () =>
console.log(`The accounting department has ${counter} employees.`)
)

"普通网站"没有带209,579选项的select字段。这里的速度并不取决于您的代码,而是主要取决于客户端机器的性能和连接速度。你必须考虑其他选择,比如自动完成功能,或者无限滚动,诸如此类的东西。

在这种情况下,您不能指望将200000条记录加载到浏览器dom中是高效的,这对用户来说将是一种可怕的体验——这肯定是显而易见的。您需要将数据存储在浏览器中的数据库或数组中,然后搜索该数据,只返回自动完成中匹配的行,然后将它们添加到表/网格中,以限制结果。这么多数据的下降听起来像是个问题。

另一个老技巧是,将您的选项数据建立在一个字符串中,并使用creatElement将其添加到dom中一次,而不是100次。

最新更新