admin管理员组文章数量:1336710
I am new to React. I am just trying to build a table of data ing from an API which I got it fetching. But now I want to render the data into a table.
My issue is that one of the columns is a logo that es from a URL index.php?Action=GetLogo&id=51
. The number of results is more than 300. Even though I am already using pagination the table rendering is slow, particularly the logo
column. All the data gets loaded, but I can see each logo being rendered row by row, giving the user a slow experience.
Is there any way how React can approach to solve this issue? Someone please point me in the right direction how to tackle this.
Thanks everyone.
Update
Someone has advised me to use a sync/await function to load the images. Then I am updating the code. However my main issue is still with me: loading the data particularly the logo column. All the data gets rendered, but not the logo column, then each logo starts to render one by one looking very slow. I thought the async/await
function would alleviate that.
import React from 'react';
import ReactDOM from 'react-dom';
import FormData from 'form-data';
class FilterableSupplierTable extends React.Component {
constructor(props) {
super(props);
this.state = {
suppliers: []
}
}
ponentDidMount() {
let formData = new FormData();
formData.append('AjaxMethodName', 'GetSuppliers');
const options = {
method: 'POST',
headers: {
'Accept': '*/*'
},
body: formData
};
fetch(`?Model=route_to_controller`, options)
.then(response => response.json())
.then(data => {
this.setState({ suppliers: JSON.parse(data.response_data) })
});
}
async getLogos(suppliers) {
return await Promise.all(
suppliers.map(async supplier => {
supplier.new_logo = !!supplier.has_logo ?
<img style={{maxWidth: "100px"}} src={supplier.logo} alt={supplier.supplier_id} /> :
<i className="icon icon-warning no_logo"> No Logo</i>;
return supplier;
});
);
}
render() {
const rows = [];
const suppliers = this.state.suppliers;
this.getLogos(suppliers)
.then(results => {
results.map(supplier => {
rows.push(
<tr>
{/* supplier.logo is index.php?Action=GetLogo&id=51, etc */}
<td><img src={supplier.new_logo} /></td>
<td>{supplier.name}</td>
</tr>
);
});
});
return (
<table>
<thead>
<tr>
<th colSpan="4">Suppliers</th>
</tr>
<tr>
<th>Logo</th>
<th>Name</th>
</tr>
</thead>
<tbody>{rows}</tbody>
</table>
);
}
}
ReactDOM.render(
<FilterableSupplierTable />,
document.getElementById('suppliers_list')
);
I am new to React. I am just trying to build a table of data ing from an API which I got it fetching. But now I want to render the data into a table.
My issue is that one of the columns is a logo that es from a URL index.php?Action=GetLogo&id=51
. The number of results is more than 300. Even though I am already using pagination the table rendering is slow, particularly the logo
column. All the data gets loaded, but I can see each logo being rendered row by row, giving the user a slow experience.
Is there any way how React can approach to solve this issue? Someone please point me in the right direction how to tackle this.
Thanks everyone.
Update
Someone has advised me to use a sync/await function to load the images. Then I am updating the code. However my main issue is still with me: loading the data particularly the logo column. All the data gets rendered, but not the logo column, then each logo starts to render one by one looking very slow. I thought the async/await
function would alleviate that.
import React from 'react';
import ReactDOM from 'react-dom';
import FormData from 'form-data';
class FilterableSupplierTable extends React.Component {
constructor(props) {
super(props);
this.state = {
suppliers: []
}
}
ponentDidMount() {
let formData = new FormData();
formData.append('AjaxMethodName', 'GetSuppliers');
const options = {
method: 'POST',
headers: {
'Accept': '*/*'
},
body: formData
};
fetch(`?Model=route_to_controller`, options)
.then(response => response.json())
.then(data => {
this.setState({ suppliers: JSON.parse(data.response_data) })
});
}
async getLogos(suppliers) {
return await Promise.all(
suppliers.map(async supplier => {
supplier.new_logo = !!supplier.has_logo ?
<img style={{maxWidth: "100px"}} src={supplier.logo} alt={supplier.supplier_id} /> :
<i className="icon icon-warning no_logo"> No Logo</i>;
return supplier;
});
);
}
render() {
const rows = [];
const suppliers = this.state.suppliers;
this.getLogos(suppliers)
.then(results => {
results.map(supplier => {
rows.push(
<tr>
{/* supplier.logo is index.php?Action=GetLogo&id=51, etc */}
<td><img src={supplier.new_logo} /></td>
<td>{supplier.name}</td>
</tr>
);
});
});
return (
<table>
<thead>
<tr>
<th colSpan="4">Suppliers</th>
</tr>
<tr>
<th>Logo</th>
<th>Name</th>
</tr>
</thead>
<tbody>{rows}</tbody>
</table>
);
}
}
ReactDOM.render(
<FilterableSupplierTable />,
document.getElementById('suppliers_list')
);
Share
edited Jan 4, 2021 at 7:24
GalAbra
5,1385 gold badges25 silver badges43 bronze badges
asked Apr 12, 2020 at 10:05
ivantxoivantxo
6395 gold badges18 silver badges37 bronze badges
11
- sometimes the size of the images can increase load time in dev enviroment are you certain the images are web optimized? – Hadi Pawar Commented Apr 12, 2020 at 10:15
-
'Lagging' can mean more things. Try using
await
or aSuspense
block – Adrian Pascu Commented Apr 12, 2020 at 12:05 - @AdrianPascu I will check that thanks I have also updated the title. – ivantxo Commented Apr 12, 2020 at 22:06
- Could it be a case where these images are extremely 'heavy'? High resolution and also not optimized which can lead to large filesizes to render in the table ponent? – Malakai Commented Apr 12, 2020 at 22:20
- @AdrianPascu. Can you give me an example how can I use those blocks? – ivantxo Commented Apr 13, 2020 at 2:30
2 Answers
Reset to default 7 +50Your issue can be solved with a ponent that updates a "global loading state".
Only after all images have updated that they finished loading, they bee visible together:
function MyImage(props) {
const onLoad = () => {
props.onLoad();
};
return (
<div>
{props.isCurrentlyLoading && <div>Loading</div>}
<img
src={props.src}
onLoad={onLoad}
style={
props.isCurrentlyLoading
? { width: "0", height: "0" } // You can also use opacity, etc.
: { width: 100, height: 100 }
}
/>
</div>
);
}
function ImagesBatch() {
const [loadedImagesCounter, setLoadedImagesCounter] = useState(0);
const [isAllLoaded, setIsAllLoaded] = useState(false);
const updateLoading = () => {
if (loadedImagesCounter + 1 === imagesUrls.length) {
setIsAllLoaded(true);
}
setLoadedImagesCounter(prev => prev + 1);
};
return (
<div>
{imagesUrls.map((url, index) => {
return (
<MyImage
key={url}
src={url}
index={index + 1}
isCurrentlyLoading={!isAllLoaded}
onLoad={updateLoading}
/>
);
})}
</div>
);
}
You can check the full code here (preferably with an open console), where I used an arbitrary ~6MB image, as an example.
I think you got your issues resolved. But, apart from that I suggest you checkout React Virtualized, https://github./bvaughn/react-virtualized
Hope this helps some day.
本文标签: javascriptReact table slow loading when displaying img rowsStack Overflow
版权声明:本文标题:javascript - React table slow loading when displaying img rows - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742295317a2448607.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论