Is "currentRenderList.finish();" necessary?

Hello everyone, I will read the source code of three.js again today. I noticed that line 1031 of WebGLRender.js did a puzzling treatment. I analyzed it and compared two different versions of webgl_test_memory.html and webgl_test_memory2.html , and did not find that canceling this line would cause a memory leak .Or,can I modify the loop of the finish() function in WebGLRenderLists.js to a sentence renderItems.length=0; to clear the reference?But I believe there must be a reason for this, otherwise it would be a waste of performance. Can you tell why? Thank you!

You can read more about this here:

cleanup() was later renamed to finish().

Thank you very much, but I didn’t see why I traversed to clear the reference? And also keep the current frame in useless objects occupying memory after that? Imagine if I didn’t run renderer.render() every frame? Has this part of the memory been wasted in vain soon? Besides, the efficiency is definitely far lower than the direct renderItems.length=0; I am thinking whether there is a better solution, I have a little idea, I hope you can give suggestions, I can only use code to express mine Ideas:

function WebGLRenderList(properties) {
	const renderItems = [];

	const opaque = [];
	const transparent = [];

	const defaultProgram = { id: -1 };
	
	// There is no need for init() here, because we have solved our own troubles in every frame

	function getNextRenderItem(object, geometry, material, groupOrder, z, group) {
		return {
			id: object.id,
			object: object,
			geometry: geometry,
			material: material,
			program: properties.get(material).program || defaultProgram,
			groupOrder: groupOrder,
			renderOrder: object.renderOrder,
			z: z,
			group: group,
		};
	}

	function push(object, geometry, material, groupOrder, z, group) {
		const renderItem = getNextRenderItem(
			object,
			geometry,
			material,
			groupOrder,
			z,
			group
		);

		(material.transparent === true ? transparent : opaque).push(renderItem);
	}

	function unshift(object, geometry, material, groupOrder, z, group) {
		const renderItem = getNextRenderItem(
			object,
			geometry,
			material,
			groupOrder,
			z,
			group
		);

		(material.transparent === true ? transparent : opaque).unshift(renderItem);
	}

	function sort(customOpaqueSort, customTransparentSort) {
		if (opaque.length > 1) opaque.sort(customOpaqueSort || painterSortStable);
		if (transparent.length > 1)
			transparent.sort(customTransparentSort || reversePainterSortStable);
	}
	
	// `currentRenderList.finish();` is executed at the end of the `render()`, before `currentRenderList = null;`.

	function finish() {
		renderItems.length = 0;
		opaque.length = 0;
		transparent.length = 0;
	}

	return {
		opaque: opaque,
		transparent: transparent,

		init: init,
		push: push,
		unshift: unshift,
		finish: finish,

		sort: sort,
	};
}

I didn’t see why I traversed to clear the reference? … Besides, the efficiency is definitely far lower than the direct renderItems.length=0;

If you make the array empty then all of the objects in it will have to be recreated the next frame. The goal is to create as few new objects as you can every frame by pooling them so they can be reused. If you create too many unnecessary objects and release them over time the garbage collector will have to run and may stall the frame.

Thank you very much,as I said before, what if I do not execute render() in a loop.
Imagine if I didn’t run renderer.render() every frame?
I know that it will cause lag in gc, but this situation only occurs when I perform loop rendering, and a large amount of memory is recycled. For this case, I don’t think there will be any obvious lag. Maybe this is where the browser needs to be improved. If one day gc will not affect this? I tested it, and my dilapidated laptop did not show any noticeable freezes. :joy:
Maybe give users more choices?Open this option?

Imagine if I didn’t run renderer.render() every frame?

Yes for this case it wouldn’t be a problem but the render loop is designed to work in all situations.

Maybe give users more choices? Open this option?

Why do you need to clear this memory? Can you demonstrate a case where this is causing problems? Otherwise it sounds like pretty micro optimization.

This situation is definitely not a problem at present, but for customers who do not need to loop rendering, it wastes memory and execution speed. This is to be expected.

Can you demonstrate a case where this is causing problems?

This is certainly not a bug, but you can’t deny that it should be resolved for cases where rendering is only necessary.I believe that there are also a large number of users who do not use three.js to develop games. After all, the original intention of three.js was not to be a game engine. So why do you only optimize for the loop rendering situation without considering another situation?

you can’t deny that it should be resolved for cases where rendering is only necessary

If it can’t be demonstrated that there’s tangible benefit then why should it be changed? The memory and time it takes to iterate over the array should be insignificant compared to scene objects and rendering time. And the case you’re describing where a scene is rendered once is less performance sensitive than the case where a render happens every frame so optimizing the finish function is less consequential, anyway.

And the case you’re describing where a scene is rendered once is less performance sensitive than the case where a render happens every frame so optimizing the finish function is less consequential, anyway.

I don’t think the case of on-demand rendering is less sensitive.In fact, many users do this, after all, everyone does not want to waste cpu in vain.In actual applications, it is impossible for me to provide cpu only to three.js.The benefits are also obvious. The more objects in a scene, the more obvious the effect. After all, so many cycles are saved.As for the memory saved may be really insignificant…