How to optimize this instanced mesh in this three.js version.?

Hello, im scripting a different version which it haves a optimized form to generate minecraft terrain, and its the instancedMesh, i have this code:

<meta charset="UTF-8">
<title>Hypogenix.</title>
<script src="three.js"></script>
<script src="perlin.js"></script>
<script src="stats.js"></script>
<script type="module">
	// Show stats:
	var stats1 = new Stats();
	stats1.showPanel(0); // Panel 0 = fps
	stats1.domElement.style.cssText = 'position:absolute;top:0px;left:0px;';
	document.body.appendChild(stats1.domElement);

	var stats2 = new Stats();
	stats2.showPanel(1); // Panel 1 = ms
	stats2.domElement.style.cssText = 'position:absolute;top:0px;left:80px;';
	document.body.appendChild(stats2.domElement);

	var stats3 = new Stats();
	stats3.showPanel(2); // Panel 1 = ms
	stats3.domElement.style.cssText = 'position:absolute;top:0px;left:160px;';
	document.body.appendChild(stats3.domElement);

	function animate(){
		stats1.update();
		stats2.update();
		stats3.update();
		requestAnimationFrame(animate);
	}

	requestAnimationFrame(animate);
	
	let scene = new THREE.Scene()
	let renderer = new THREE.WebGLRenderer()
	renderer.setSize(innerWidth,innerHeight)
	document.body.appendChild(renderer.domElement)
	let camera = new THREE.PerspectiveCamera(75,innerWidth/innerHeight,0.1,1000)

	addEventListener("resize",()=>{
		renderer.setSize(innerWidth,innerHeight)
		camera.aspect=innerWidth/innerHeight
		camera.updateProjectionMatrix()
	})

	scene.background=new THREE.Color("rgb(0,127,255)")

	let box = new THREE.BoxGeometry(1,1,1)
	let lime = new THREE.MeshBasicMaterial({color:"rgba(0,255,0,1)"})
	let cesped = new THREE.MeshBasicMaterial({color:"rgba(0,255,150,1)"})

	const getSurface2D=(x,z)=>{
		return noise.perlin2(x,z)+
		noise.perlin2(x/4,z/4)*2+
		noise.perlin2(x/16,z/16)*8+
		noise.perlin2(x/64,z/64)*32
	}
	const int1=(n)=>{
		return Math.floor(n)
	}

	let depth=4

    // Definir la matriz tridimensional para almacenar información sobre los bloques
    const worldMatrix = [];

    const blockSize = 1; // Tamaño de cada bloque
    const worldSize = 64; // Tamaño del mundo (en bloques)

    const boxGeometry = new THREE.BoxGeometry(blockSize, blockSize, blockSize);

    const loader = new THREE.TextureLoader()

	var grassTexture = [
		new THREE.MeshBasicMaterial({map : loader.load("textures/side.jpg")}),
		new THREE.MeshBasicMaterial({map : loader.load("textures/side.jpg")}),
		new THREE.MeshBasicMaterial({map : loader.load("textures/top.jpg")}),
		new THREE.MeshBasicMaterial({map : loader.load("textures/bottom.jpg")}),
		new THREE.MeshBasicMaterial({map : loader.load("textures/side.jpg")}),
		new THREE.MeshBasicMaterial({map : loader.load("textures/side.jpg")})
	];

    // Crear un InstancedMesh para almacenar los bloques
    const instancedMesh = new THREE.InstancedMesh(
        boxGeometry,
        grassTexture, // Color verde
        worldSize * worldSize * worldSize // Número máximo de instancias
    );

	// Iterar sobre la matriz y configurar las instancias del InstancedMesh
	let instanceIndex = 0;
	for (let x = -worldSize; x < worldSize; x++) {
        for (let z = -worldSize; z < worldSize; z++) {
        	let surface=getSurface2D(x,z)
        	surface=int1(surface)
        	for (let y = surface; y < surface + 1; y++) {
	            // Configurar la posición de la instancia
	            const position = new THREE.Vector3(x * blockSize, y * blockSize, z * blockSize);
	            instancedMesh.setMatrixAt(instanceIndex, new THREE.Matrix4().makeTranslation(position.x, position.y, position.z));
	            instanceIndex++;
	        }
	    }
	}

    // Añadir el InstancedMesh a la escena
    scene.add(instancedMesh);

	var dirtTexture = [
		new THREE.MeshBasicMaterial({map : loader.load("textures/bottom.jpg")}),
		new THREE.MeshBasicMaterial({map : loader.load("textures/bottom.jpg")}),
		new THREE.MeshBasicMaterial({map : loader.load("textures/bottom.jpg")}),
		new THREE.MeshBasicMaterial({map : loader.load("textures/bottom.jpg")}),
		new THREE.MeshBasicMaterial({map : loader.load("textures/bottom.jpg")}),
		new THREE.MeshBasicMaterial({map : loader.load("textures/bottom.jpg")})
	];

    // Crear un InstancedMesh para almacenar los bloques
    const dirtInstancedMesh = new THREE.InstancedMesh(
        boxGeometry,
        dirtTexture, // Color verde
        worldSize * worldSize * worldSize // Número máximo de instancias
    );

	// Iterar sobre la matriz y configurar las instancias del InstancedMesh
	let dirtInstanceIndex = 0;
	for (let x = -worldSize; x < worldSize; x++) {
        for (let z = -worldSize; z < worldSize; z++) {
        	let surface=getSurface2D(x,z)
        	surface=int1(surface)
        	for (let y = surface - 3; y < surface; y++) {
	            // Configurar la posición de la instancia
	            const position = new THREE.Vector3(x * blockSize, y * blockSize, z * blockSize);
	            dirtInstancedMesh.setMatrixAt(dirtInstanceIndex, new THREE.Matrix4().makeTranslation(position.x, position.y, position.z));
	            dirtInstanceIndex++;
	        }
	    }
	}

    // Añadir el InstancedMesh a la escena
    scene.add(dirtInstancedMesh);

	//Crea los controles del mouse:
	let xa=0;
	let ya=0;
	onmousedown=()=>{
	if(document.pointerLockElement===document.body||
	document.mozPointerLockElement===document.body){
		}else{
			document.body.requestPointerLock()
		}
	}
	onmousemove=(event)=>{
	if(document.pointerLockElement===document.body||
	document.mozPointerLockElement===document.body){
		xa-=0.01*event.movementX
		if(-1.5<ya&&0<event.movementY){
			ya-=0.005*event.movementY
		}
		if(ya<1.5&&event.movementY<0){
			ya-=0.005*event.movementY
		}
	}
	}
	//Crear los controles de teclado:
	let k=[];
	onkeydown=onkeyup=(e)=>{
		k[e.keyCode]=e.type=="keydown"
	}

	function render(){
		requestAnimationFrame(render)
		renderer.render(scene,camera)
        if(-1.5>ya){ya=-1.5}
        if(1.5<ya){ya=1.5}
        camera.lookAt(
          camera.position.x+Math.sin(xa)*Math.cos(ya),
          camera.position.y+Math.sin(ya),
          camera.position.z+Math.cos(xa)*Math.cos(ya)
        )
    	let walkSpeed=0.05
    	if(k[32]){//Space.
    		camera.position.y+=walkSpeed
    	}
    	if(k[88]){//X key.
    		camera.position.y-=walkSpeed
    	}
    	//WASD Keys:
        if(k[65]){
          camera.position.x+=walkSpeed*Math.cos(xa)
          camera.position.z-=walkSpeed*Math.sin(xa)
        }
        if(k[87]){
          camera.position.x+=walkSpeed*Math.sin(xa)
          camera.position.z+=walkSpeed*Math.cos(xa)
        }
        if(k[68]){
          camera.position.x-=walkSpeed*Math.cos(xa)
          camera.position.z+=walkSpeed*Math.sin(xa)
        }
        if(k[83]){
          camera.position.x-=walkSpeed*Math.sin(xa)
          camera.position.z-=walkSpeed*Math.cos(xa)
        }
	}
	render()
</script>
<style>
body{
	margin:0px;
}
</style>

Into this file:
textures.zip (2.1 MB)

And when i put worldSize at 128 or more the fps decrease… so… there is any solution?

Check out this video and this other video by SimonDev.

Ok, i checked noise.simplex and its run better than noise.perlin2, im checking the video already…

Edit 1: I finally watched the video and… how to apply the other methods? This is my actual file:

textures v2.zip (2.1 MB)

With depth = 10 and worldsize = 32

Edit 2:
Its runs better than the past:

    // Definir la matriz tridimensional para almacenar información sobre los bloques
    let depth=10
    const worldMatrix = [];

    const blockSize = 1; // Tamaño de cada bloque
    const worldSize = 256; // Tamaño del mundo (en bloques)

image

And, the second video i need the sample code because i cant listen english, only read… sorry >_<’

This is my actual progress:

Edit 3: I know the second video means: Quitting the hidden faces of the cubes. This not is securely optimizing the game, but makes better if in the terrain isn’t too much separated meshes in render distance… im wrong?