Наше приложение использует два элемента в каждом контейнере, переключаясь между ними, чтобы обеспечить плавный переход. Один обновляется новым содержимым с помощью srcdoc, и после загрузки мы переключаем его видимость на текущий активный файл . Ранее активные затем очищаются и скрываются.
Однако со временем этот подход может вызвать утечку памяти (например, Google Chrome, Edge, Opera). Использование памяти продолжает увеличиваться даже после очистки неиспользуемой памяти. Firefox, похоже, не страдает от утечки памяти, однако видео в HTML-файлах постепенно замедляется.
Вопросы:
- Какой рекомендуемый способ динамического обновления контента без утечек памяти в современных браузерах?
- Существует ли более эффективный шаблон управления и очистки ресурсы при использовании srcdoc?
Вот логика обновления свойства srcdoc и обработки события загрузки:
Код: Выделить всё
if (received_data.html) {
var inactiveIframe = document.getElementById(iframeIds.inactiveIframe);
// Update the srcdoc of the inactive iframe, which triggers content loading
inactiveIframe.srcdoc = received_data.html;
// Handle the iframe size if provided
if (received_data.width && received_data.height) {
inactiveIframe.style.width = received_data.width + "px";
inactiveIframe.style.height = received_data.height + "px";
inactiveIframe.parentNode.style.height = received_data.height + "px";
inactiveIframe.parentNode.parentNode.style.height = received_data.height + "px";
}
// Set up the onload event handler to switch iframes after the new content has loaded
inactiveIframe.onload = async function() {
await switchIframe(iframeIds);
// Optionally, remove the event listener after the switch
inactiveIframe.onload = null;
};
validateResources(received_data.html);
}
Код: Выделить всё
function switchIframe(iframeIds) {
// Swap the active and inactive iframe IDs
let temp = iframeIds.activeIframe;
iframeIds.activeIframe = iframeIds.inactiveIframe;
iframeIds.inactiveIframe = temp;
// Hide the previously active iframe
const inactiveIframeElement = document.getElementById(iframeIds.inactiveIframe);
inactiveIframeElement.style.zIndex = '999997';
inactiveIframeElement.style.opacity = '0';
// Clear the content of the inactive iframe
inactiveIframeElement.srcdoc = '';
let frameDoc = inactiveIframeElement.contentDocument || inactiveIframeElement.contentWindow.document;
if (frameDoc) {
frameDoc.documentElement.innerHTML = '';
}
// Remove event listeners
inactiveIframeElement.onload = null;
// Show the new active iframe
const activeIframeElement = document.getElementById(iframeIds.activeIframe);
activeIframeElement.style.zIndex = '999998';
activeIframeElement.style.opacity = '1';
}
Испробованы альтернативные подходы:
Мы пробовали разные стратегии, чтобы избежать утечек памяти, но ни одна из них не увенчалась успехом:
- Восстановите : Вместо повторно используя inactive, мы удалили его из DOM и повторно добавили новый с тот же идентификатор:
Код: Выделить всё
const inactiveIframeElement = document.getElementById(iframeIds.inactiveIframe);
inactiveIframeElement.srcdoc = '';
inactiveIframeElement.parentElement.innerHTML = `
`;
- Очистка HTML с помощью InnerHTML: Очищено содержимое с помощью InnerHTML, как показано ниже:
Код: Выделить всё
let frameDoc = inactiveIframeElement.contentDocument || inactiveIframeElement.contentWindow.document;
if (frameDoc) {
frameDoc.documentElement.innerHTML = '';
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... -javascrip
Мобильная версия