feat: Implement lazy loading for existing sign images with a shimmer effect to improve performance.

This commit is contained in:
Suherdy Yacob 2026-03-16 14:20:06 +07:00
parent 5b4d441d9c
commit f6f2852b30
3 changed files with 38 additions and 4 deletions

View File

@ -48,4 +48,20 @@ body div.o_sign_sign_item.o_sign_image_item span.o_placeholder {
justify-content: center; justify-content: center;
width: 100%; width: 100%;
height: 100%; height: 100%;
position: relative;
}
.o_sign_image_loading {
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: o_sign_image_shimmer 1.5s infinite linear;
}
@keyframes o_sign_image_shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.o_sign_image_lazy {
transition: opacity 0.5s ease-in-out;
} }

View File

@ -107,6 +107,24 @@ patch(SignablePDFIframe.prototype, {
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
}); });
// Performance Fix: Lazy Load existing images
const lazyImg = el.querySelector('.o_sign_image_lazy');
if (lazyImg && lazyImg.dataset.src) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
lazyImg.src = lazyImg.dataset.src;
lazyImg.onload = () => {
lazyImg.classList.remove('o_sign_image_loading');
lazyImg.style.opacity = 1;
};
observer.unobserve(lazyImg);
}
});
}, { rootMargin: '200px' }); // Load 200px before reaching viewport
observer.observe(lazyImg);
}
} }
}, },

View File

@ -8,7 +8,7 @@
<div t-if="type == 'image'" t-att-data-id="id" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item o_sign_image_item" t-att-style="style" t-att-data-value="value" t-att-data-type="'image'" style="text-align:center; display:flex; align-items:center; justify-content:center;"> <div t-if="type == 'image'" t-att-data-id="id" t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item o_sign_image_item" t-att-style="style" t-att-data-value="value" t-att-data-type="'image'" style="text-align:center; display:flex; align-items:center; justify-content:center;">
<input type="file" accept="image/*" class="o_sign_image_upload_input" style="display:none"/> <input type="file" accept="image/*" class="o_sign_image_upload_input" style="display:none"/>
<t t-if="value"> <t t-if="value">
<img t-att-src="value" style="max-width:100%; max-height:100%; object-fit:contain;"/> <img t-att-data-src="value" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="o_sign_image_lazy o_sign_image_loading" style="max-width:100%; max-height:100%; object-fit:contain; opacity: 0; transition: opacity 0.3s;"/>
</t> </t>
<t t-else=""> <t t-else="">
<span class="o_placeholder" style="font-size:12px !important; color:#666; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; line-height:1;"> <span class="o_placeholder" style="font-size:12px !important; color:#666; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; line-height:1;">
@ -24,7 +24,7 @@
<div t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item o_sign_image_item" t-att-data-id="id" t-att-style="style" t-att-data-type="'image'" style="text-align:center; display:flex; align-items:center; justify-content:center;"> <div t-att-title="role" t-attf-class="{{classes}} o_sign_sign_item o_sign_image_item" t-att-data-id="id" t-att-style="style" t-att-data-type="'image'" style="text-align:center; display:flex; align-items:center; justify-content:center;">
<div class="sign_item_body"> <div class="sign_item_body">
<t t-if="value"> <t t-if="value">
<img t-att-src="value" style="max-width:100%; max-height:100%; object-fit:contain;"/> <img t-att-data-src="value" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="o_sign_image_lazy o_sign_image_loading" style="max-width:100%; max-height:100%; object-fit:contain; opacity: 0; transition: opacity 0.3s;"/>
</t> </t>
<t t-else=""> <t t-else="">
<span class="o_placeholder" style="font-size:12px !important; color:#666; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; line-height:1;"> <span class="o_placeholder" style="font-size:12px !important; color:#666; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; line-height:1;">