-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cherry-pick 270745@main (78e4577). https://bugs.webkit.org/show_bug.c…
…gi?id=263521 Memory consumption/leak with img out of viewport and lazy loading https://bugs.webkit.org/show_bug.cgi?id=263521 Reviewed by Chris Dumez. This change fixes the problem with dangling of dynamically created (in JS) HTMLImageElement when it is detached from the document before loading the resource starts. It happened when img element was created (dynamically) with lazy loading and the element was outside the viewport (the loading of resource is deferred until the img element becomes visible). If the element was removed from document it becomes dangling element and will never be deleted by GC. * Source/WebCore/loader/ImageLoader.cpp: (WebCore::ImageLoader::hasPendingActivity const): To avoid leaking of the dynamically created element, the pending activity of the element should check has the load of the resource actually started. Similar check is done in case of static HTMLImageElement in ImageLoader::updatedHasPendingEvent. * Source/WebCore/loader/ImageLoader.h: (WebCore::ImageLoader::hasPendingActivity const): Deleted. Moved implementation to cpp file. * LayoutTests/fast/dom/dynamic-image-with-lazy-loading-leak-expected.txt: Added. * LayoutTests/fast/dom/dynamic-image-with-lazy-loading-leak.html: Added. Canonical link: https://commits.webkit.org/270745@main
- Loading branch information
1 parent
4e521e2
commit 60afb60
Showing
4 changed files
with
93 additions
and
1 deletion.
There are no files selected for viewing
20 changes: 20 additions & 0 deletions
20
LayoutTests/fast/dom/dynamic-image-with-lazy-loading-leak-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Tests that lazy image loading doesn't cause leaks when 'img' element is created and removed dynamically. | ||
|
||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". | ||
|
||
|
||
PASS internals.isElementAlive(imgElementId) is true | ||
PASS internals.isElementAlive(imgElementId) is true | ||
PASS internals.isElementAlive(imgElementId) is true | ||
PASS internals.isElementAlive(imgElementId) is true | ||
PASS internals.isElementAlive(imgElementId) is true | ||
PASS internals.isElementAlive(imgElementId) is true | ||
PASS internals.isElementAlive(imgElementId) is true | ||
PASS internals.isElementAlive(imgElementId) is true | ||
PASS internals.isElementAlive(imgElementId) is true | ||
PASS internals.isElementAlive(imgElementId) is true | ||
PASS The img element didn't leak. | ||
PASS successfullyParsed is true | ||
|
||
TEST COMPLETE | ||
|
64 changes: 64 additions & 0 deletions
64
LayoutTests/fast/dom/dynamic-image-with-lazy-loading-leak.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<body> | ||
<script src="../../resources/js-test.js"></script> | ||
<div style="height: 2000px"></div> | ||
<div id="below-viewport-img-container" style="height: 1000px"></div> | ||
<script> | ||
description("Tests that lazy image loading doesn't cause leaks when 'img' element is created and removed dynamically."); | ||
jsTestIsAsync = true; | ||
|
||
checkCount = 0; | ||
|
||
const imgCount = 10; | ||
imgs = []; | ||
const image_path = 'image.png'; | ||
imgElementIds = []; | ||
|
||
function runTest() | ||
{ | ||
handle = setInterval(() => { | ||
gc(); | ||
for (let imgElementId of imgElementIds) { | ||
if (!internals.isElementAlive(imgElementId)) { | ||
clearInterval(handle); | ||
testPassed("The img element didn't leak."); | ||
finishJSTest(); | ||
return; | ||
} | ||
} | ||
checkCount++; | ||
if (checkCount > 1000) { | ||
clearInterval(handle); | ||
testFailed("The img elements leaked."); | ||
finishJSTest(); | ||
} | ||
}, 10); | ||
} | ||
|
||
onload = () => { | ||
for (let i = 0; i < imgCount; i++) { | ||
img = document.getElementById("lazy-loaded-img-"+i); | ||
imgElementId = internals.elementIdentifier(img); | ||
shouldBeTrue("internals.isElementAlive(imgElementId)"); | ||
imgElementIds.push(imgElementId); | ||
document.getElementById('below-viewport-img-container').removeChild(img); | ||
img = null; | ||
} | ||
imgs = []; | ||
setTimeout(runTest, 0); | ||
}; | ||
|
||
for (let i = 0; i < imgCount; i++) { | ||
img = new Image(); | ||
img.id = "lazy-loaded-img-"+i; | ||
img.loading = 'lazy'; | ||
img.src = image_path; | ||
document.getElementById('below-viewport-img-container').append(img); | ||
imgs.push(img); | ||
img = null; | ||
} | ||
|
||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters