How to import a random texture on the threejs game?

I have this code:

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
<script>
onload=()=>{
  k=[]
  xa=0
  ya=0
  onkeydown=onkeyup=(e)=>{k[e.keyCode]=e.type=="keydown"}
  document.body.requestPointerLock=document.body.requestPointerLock||document.body.mozRequestPointerLock
  document.title="Voxel Sphere."
  document.body.style.margin=0
  scene=new THREE.Scene()
  camera=new THREE.PerspectiveCamera(75,innerWidth/innerHeight,0.1,10000)
  renderer=new THREE.WebGLRenderer()
  document.body.appendChild(renderer.domElement)
  box=new THREE.BoxGeometry(1,1,1)
  dirt=new THREE.MeshLambertMaterial({color:"rgb(100,50,0)"})
  
  // Crear textura con canvas 16x16
  const canvassize = 16;
  const canvas = document.createElement('canvas');
  canvas.width = canvassize;
  canvas.height = canvassize;

  const ctx = canvas.getContext('2d');
  const imageData = ctx.createImageData(canvassize, canvassize);
  const data = imageData.data;

  for (let i = 0; i < data.length; i += 4) {
    data[i]     = 255*Math.random();       // R
    data[i + 1] = 0;   // G
    data[i + 2] = 0;   // B
    data[i + 3] = 255;     // A
  }

  ctx.putImageData(imageData, 0, 0);

  const texture = new THREE.CanvasTexture(canvas);
  texture.needsUpdate = true; // importante

  // Dimensiones
  const size = 100;
  const blockSize = 1;
  const blocks = new Set();

  // Simula todos los bloques llenos
  for (let x = 0; x < size; x++) {
    for (let y = 0; y < size; y++) {
      for (let z = 0; z < size; z++) {
        if(Math.random()<0.9){
          blocks.add(`${x},${y},${z}`);
        }
      }
    }
  }

  // Caras unitarias (de 1x1) en cada eje positivo
  const faceOffsets = [
    { dir: [1, 0, 0], verts: [[0.5, -0.5, -0.5], [0.5, 0.5, -0.5], [0.5, 0.5, 0.5], [0.5, -0.5, 0.5]] },  // Right
    { dir: [-1, 0, 0], verts: [[-0.5, -0.5, 0.5], [-0.5, 0.5, 0.5], [-0.5, 0.5, -0.5], [-0.5, -0.5, -0.5]] }, // Left
    { dir: [0, 1, 0], verts: [[-0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [0.5, 0.5, -0.5], [-0.5, 0.5, -0.5]] },  // Top
    { dir: [0, -1, 0], verts: [[-0.5, -0.5, -0.5], [0.5, -0.5, -0.5], [0.5, -0.5, 0.5], [-0.5, -0.5, 0.5]] }, // Bottom
    { dir: [0, 0, 1], verts: [[-0.5, -0.5, 0.5], [0.5, -0.5, 0.5], [0.5, 0.5, 0.5], [-0.5, 0.5, 0.5]] },   // Front
    { dir: [0, 0, -1], verts: [[0.5, -0.5, -0.5], [-0.5, -0.5, -0.5], [-0.5, 0.5, -0.5], [0.5, 0.5, -0.5]] } // Back
  ];

  const positions = [];
  const indices = [];

  let index = 0;

  for (let x = 0; x < size; x++) {
    for (let y = 0; y < size; y++) {
      for (let z = 0; z < size; z++) {
        const pos = `${x},${y},${z}`;
        if (!blocks.has(pos)) continue;

        for (const { dir, verts } of faceOffsets) {
          const [dx, dy, dz] = dir;
          const neighbor = `${x + dx},${y + dy},${z + dz}`;
          if (!blocks.has(neighbor)) {
            // Esta cara es visible, agregarla
            const face = verts.map(([vx, vy, vz]) => [
              vx + x,
              vy + y,
              vz + z
            ]);

            const baseIndex = index;
            face.forEach(v => positions.push(...v));
            indices.push(
              baseIndex, baseIndex + 1, baseIndex + 2,
              baseIndex, baseIndex + 2, baseIndex + 3
            );
            index += 4;
          }
        }
      }
    }
  }

  // Crear geometría y malla
  const geometry = new THREE.BufferGeometry();
  geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
  geometry.setIndex(indices);
  geometry.computeVertexNormals();

  const material = new THREE.MeshStandardMaterial({ map : texture });
  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  scene.background=new THREE.Color("rgb(0,127,255)")
  scene.fog=new THREE.Fog("rgb(0,127,255)",100,500)
  light=new THREE.PointLight("rgb(255,255,255)",1,500)
  scene.add(light)

  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.01*event.movementY
      }
      if(ya<1.5&&event.movementY<0){
        ya-=0.01*event.movementY
      }
    }
  }
  render=()=>{
    renderer.setSize(innerWidth,innerHeight)
    camera.aspect=innerWidth/innerHeight
    camera.updateProjectionMatrix()
    requestAnimationFrame(render)
    renderer.render(scene,camera)
  }
  render()
  setInterval(()=>{
    if(ya<-1.5)ya=-1.5
    if(ya>1.5)ya=1.5
    light.position.x=camera.position.x
    light.position.y=camera.position.y
    light.position.z=camera.position.z
    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)
    )
    if(k[65]){
      camera.position.x+=0.1*Math.cos(xa)
      camera.position.z-=0.1*Math.sin(xa)
    }
    if(k[87]){
      camera.position.x+=0.1*Math.sin(xa)
      camera.position.z+=0.1*Math.cos(xa)
    }
    if(k[68]){
      camera.position.x-=0.1*Math.cos(xa)
      camera.position.z+=0.1*Math.sin(xa)
    }
    if(k[83]){
      camera.position.x-=0.1*Math.sin(xa)
      camera.position.z-=0.1*Math.cos(xa)
    }
    if(k[32]){
      camera.position.y+=0.1
    }
    if(k[88]){
      camera.position.y-=0.1
    }
  },1)
}
</script>

And i want to generate a texture to each face of a cube without using external textures. Its possible? Thanks anyway!

I did it? I think not. This html file is very laggy: