feat: update product detail caching and component loading logic for improved SPA performance

This commit is contained in:
sebseb7
2025-07-20 00:10:55 +02:00
parent 055e49c957
commit 8e6e020a1b
3 changed files with 45 additions and 18 deletions

View File

@@ -207,10 +207,11 @@ const renderPage = (
// Create script to populate window.productDetailCache for individual product pages // Create script to populate window.productDetailCache for individual product pages
let productDetailCacheScript = ''; let productDetailCacheScript = '';
if (productData && productData.product) { if (productData && productData.product) {
const productDetailCacheData = JSON.stringify(productData.product); // Cache the entire response object (includes product, attributes, etc.)
const productDetailCacheData = JSON.stringify(productData);
productDetailCacheScript = ` productDetailCacheScript = `
<script> <script>
// Populate window.productDetailCache with product data for SPA hydration // Populate window.productDetailCache with complete product data for SPA hydration
if (!window.productDetailCache) { if (!window.productDetailCache) {
window.productDetailCache = {}; window.productDetailCache = {};
} }

View File

@@ -81,15 +81,18 @@ class PrerenderProduct extends React.Component {
), ),
React.createElement( React.createElement(
Box, Box,
{ { sx: { flexGrow: 1 } },
sx: { React.createElement(
p: { xs: 2, md: 2 }, Box,
pb: { xs: 4, md: 8 }, {
maxWidth: "1400px", sx: {
mx: "auto", p: { xs: 2, md: 2 },
flexGrow: 1 pb: { xs: 4, md: 8 },
} maxWidth: "1400px",
}, mx: "auto",
flexGrow: 1
}
},
// Back button (breadcrumbs section) // Back button (breadcrumbs section)
React.createElement( React.createElement(
Box, Box,
@@ -442,6 +445,7 @@ class PrerenderProduct extends React.Component {
) )
) )
) )
)
), ),
React.createElement(Footer) React.createElement(Footer)
); );

View File

@@ -25,16 +25,28 @@ class ProductDetailPage extends Component {
window.productDetailCache && window.productDetailCache &&
window.productDetailCache[this.props.seoName] window.productDetailCache[this.props.seoName]
) { ) {
const cachedData = window.productDetailCache[this.props.seoName];
// Initialize komponenten from cached product data
const komponenten = [];
if(cachedData.product.komponenten) {
for(const komponent of cachedData.product.komponenten.split(",")) {
// Handle both "x" and "×" as separators
const [id, count] = komponent.split(/[x×]/);
komponenten.push({id: id.trim(), count: count.trim()});
}
}
this.state = { this.state = {
product: window.productDetailCache[this.props.seoName], product: cachedData.product,
loading: false, loading: false,
error: null, error: null,
attributeImages: {}, attributeImages: {},
attributes: [], attributes: cachedData.attributes || [],
isSteckling: false, isSteckling: false,
imageDialogOpen: false, imageDialogOpen: false,
komponenten: [], komponenten: komponenten,
komponentenLoaded: false, komponentenLoaded: komponenten.length === 0, // If no komponenten, mark as loaded
komponentenData: {}, // Store individual komponent data with loading states komponentenData: {}, // Store individual komponent data with loading states
komponentenImages: {}, // Store tiny pictures for komponenten komponentenImages: {}, // Store tiny pictures for komponenten
totalKomponentenPrice: 0, totalKomponentenPrice: 0,
@@ -68,7 +80,17 @@ class ProductDetailPage extends Component {
} }
componentDidMount() { componentDidMount() {
this.loadProductData(); // Only load product data if not already cached
if (!this.state.product) {
this.loadProductData();
} else {
// Product is cached, but we still need to load komponenten if they exist
if (this.state.komponenten.length > 0 && !this.state.komponentenLoaded) {
for(const komponent of this.state.komponenten) {
this.loadKomponent(komponent.id, komponent.count);
}
}
}
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
@@ -350,8 +372,8 @@ class ProductDetailPage extends Component {
window.productDetailCache = {}; window.productDetailCache = {};
} }
// Cache the product data // Cache the complete response data (product + attributes)
window.productDetailCache[this.props.seoName] = res.product; window.productDetailCache[this.props.seoName] = res;
const komponenten = []; const komponenten = [];
if(res.product.komponenten) { if(res.product.komponenten) {