significantly optimize this code. I need fetching and creation and processing to be near instant. Make it as fast as possible. give me the full optimize and compacted code.

using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine.Networking;

public class BlockFetcher : MonoBehaviour
{
    private string serverUrl = "http://localhost:8000/blocks";
    public string texturePath = "Assets/Textures";
    public Material blockMaterial;
    [Tooltip("The name of the texture file to use when a block's texture is not found (without .png extension)")]
    public string defaultTextureName = "missing_texture";
    private const int MAX_VERTICES_PER_CHUNK = 65000;
    private List<MeshChunk> meshChunks = new List<MeshChunk>();

    public string[] woodTypes;
    public Mesh slabMesh;
    public Mesh fenceMesh;
    public Mesh stairMesh;

    private class MeshChunk
    {
        public List<Vector3> vertices;
        public List<int> triangles;
        public List<Vector2> uvs;
        public bool isFull => vertices.Count + 4 >= MAX_VERTICES_PER_CHUNK;

        public MeshChunk()
        {
            vertices = new List<Vector3>(MAX_VERTICES_PER_CHUNK + 4);
            uvs = new List<Vector2>(MAX_VERTICES_PER_CHUNK + 4);
            triangles = new List<int>((MAX_VERTICES_PER_CHUNK + 4) * 2);
        }
    }

    [System.Serializable]
    public class BlockTextureConfig
    {
        public string blockName;
        public string top;
        public string bottom;
        public string front;
        public string back;
        public string left;
        public string right;
        public string side;
        public bool isBillboard;
        public Mesh customMesh;

        public void SetDefaults(string defaultName)
        {
            if (string.IsNullOrEmpty(top)) top = defaultName;
            if (string.IsNullOrEmpty(bottom)) bottom = defaultName;
            if (!string.IsNullOrEmpty(side))
            {
                front = back = left = right = side;
            }
            else
            {
                if (string.IsNullOrEmpty(front)) front = defaultName;
                if (string.IsNullOrEmpty(back)) back = defaultName;
                if (string.IsNullOrEmpty(left)) left = defaultName;
                if (string.IsNullOrEmpty(right)) right = defaultName;
            }
        }
    }

    [System.Serializable]
    public class BlockTintConfig
    {
        public string blockName;
        public Color tintColor;
        public string maskName;

        public BlockTintConfig(string blockName, Color tintColor, string maskName = null)
        {
            this.blockName = blockName;
            this.tintColor = tintColor;
            this.maskName = maskName;
        }
    }

    public BlockTextureConfig[] blockConfigs;
    public BlockTintConfig[] blockTintConfigs;

    private Texture2D textureAtlas;
    private List<BlockData> blockDataList;
    private Rect[] atlasRects;
    private Dictionary<string, int> blockNameToTextureIndex = new Dictionary<string, int>(System.StringComparer.OrdinalIgnoreCase);
    private Dictionary<string, BlockTextureConfig> blockConfigMap = new Dictionary<string, BlockTextureConfig>(System.StringComparer.OrdinalIgnoreCase);
    private int defaultTextureIndex;
    private Dictionary<int, Vector2[]> uvCache = new Dictionary<int, Vector2[]>();

    [System.Serializable]
    public struct BlockData
    {
        public string block_name;
        public int x;
        public int y;
        public int z;
        public string direction;
    }

    private static readonly Vector3[,] faceVertices =
    {
        {
            new Vector3(-0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f,  0.5f, -0.5f),
            new Vector3(-0.5f,  0.5f, -0.5f)
        },
        {
            new Vector3(-0.5f, -0.5f, 0.5f),
            new Vector3( 0.5f, -0.5f, 0.5f),
            new Vector3( 0.5f,  0.5f, 0.5f),
            new Vector3(-0.5f,  0.5f, 0.5f)
        },
        {
            new Vector3(-0.5f,  0.5f, -0.5f),
            new Vector3( 0.5f,  0.5f, -0.5f),
            new Vector3( 0.5f,  0.5f,  0.5f),
            new Vector3(-0.5f,  0.5f,  0.5f)
        },
        {
            new Vector3(-0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f, -0.5f,  0.5f),
            new Vector3(-0.5f, -0.5f,  0.5f)
        },
        {
            new Vector3(-0.5f, -0.5f, -0.5f),
            new Vector3(-0.5f, -0.5f,  0.5f),
            new Vector3(-0.5f,  0.5f,  0.5f),
            new Vector3(-0.5f,  0.5f, -0.5f)
        },
        {
            new Vector3( 0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f, -0.5f,  0.5f),
            new Vector3( 0.5f,  0.5f,  0.5f),
            new Vector3( 0.5f,  0.5f, -0.5f)
        }
    };

    private static readonly Vector3[][] billboardVertices = new Vector3[][]
    {
        new Vector3[]
        {
            new Vector3(-0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f, -0.5f,  0.5f),
            new Vector3( 0.5f,  0.5f,  0.5f),
            new Vector3(-0.5f,  0.5f, -0.5f)
        },
        new Vector3[]
        {
            new Vector3(-0.5f, -0.5f,  0.5f),
            new Vector3( 0.5f, -0.5f, -0.5f),
            new Vector3( 0.5f,  0.5f, -0.5f),
            new Vector3(-0.5f,  0.5f,  0.5f)
        }
    };

    private async void Start()
    {
        InitializeBlockConfigs();
        await CreateTextureAtlasAsync();
        await FetchBlocksAsync();
    }

    private void InitializeBlockConfigs()
    {
        blockConfigMap.Clear();
        foreach (var config in blockConfigs)
        {
            config.SetDefaults(config.blockName);
            blockConfigMap[config.blockName] = config;
        }
    }

    private async Task CreateTextureAtlasAsync()
    {
        string[] textureFiles = Directory.GetFiles(texturePath, "*.png");
        List<Texture2D> texturesList = new List<Texture2D>();
        Dictionary<string, Texture2D> maskTextures = await LoadMaskTexturesAsync();

        // Load default texture
        string defaultTexturePath = Path.Combine(texturePath, defaultTextureName + ".png");
        Texture2D defaultTexture = null;
        if (File.Exists(defaultTexturePath))
        {
            defaultTexture = await LoadTextureAsync(defaultTexturePath);
            texturesList.Add(defaultTexture);
            blockNameToTextureIndex[defaultTextureName] = 0;
            defaultTextureIndex = 0;
        }
        else
        {
            Debug.LogError($"Default texture {defaultTexturePath} not found! Creating fallback texture.");
            defaultTexture = CreateFallbackTexture();
            texturesList.Add(defaultTexture);
            defaultTextureIndex = 0;
        }

        // Load other textures asynchronously
        var textureTasks = textureFiles.Where(f => !Path.GetFileNameWithoutExtension(f).Equals(defaultTextureName, System.StringComparison.OrdinalIgnoreCase))
                                       .Select(f => LoadAndProcessTextureAsync(f, maskTextures)).ToArray();

        var loadedTextures = await Task.WhenAll(textureTasks);

        int textureIndex = 1;
        foreach (var texInfo in loadedTextures)
        {
            texturesList.Add(texInfo.texture);
            blockNameToTextureIndex[texInfo.name] = textureIndex++;
        }

        // Create texture atlas
        textureAtlas = new Texture2D(2048, 2048, TextureFormat.RGBA32, false)
        {
            filterMode = FilterMode.Point
        };
        atlasRects = textureAtlas.PackTextures(texturesList.ToArray(), 0, 2048);
        textureAtlas.Apply(false, true);
        blockMaterial.mainTexture = textureAtlas;
        blockMaterial.mainTexture.filterMode = FilterMode.Point;

        // Cleanup masks
        foreach (var maskTexture in maskTextures.Values)
        {
            Destroy(maskTexture);
        }
    }

    private async Task<Dictionary<string, Texture2D>> LoadMaskTexturesAsync()
    {
        var maskTextures = new Dictionary<string, Texture2D>(System.StringComparer.OrdinalIgnoreCase);
        string maskPath = Path.Combine(texturePath, "Masks");
        if (Directory.Exists(maskPath))
        {
            var maskFiles = Directory.GetFiles(maskPath, "*.png");
            var maskTasks = maskFiles.Select(async maskFile =>
            {
                string maskName = Path.GetFileNameWithoutExtension(maskFile);
                Texture2D maskTexture = await LoadTextureAsync(maskFile);
                return (maskName, maskTexture);
            }).ToArray();

            var loadedMasks = await Task.WhenAll(maskTasks);
            foreach (var (maskName, maskTexture) in loadedMasks)
            {
                maskTextures[maskName] = maskTexture;
            }
        }
        return maskTextures;
    }

    private async Task<(string name, Texture2D texture)> LoadAndProcessTextureAsync(string textureFile, Dictionary<string, Texture2D> maskTextures)
    {
        string fileName = Path.GetFileNameWithoutExtension(textureFile);
        Texture2D texture = await LoadTextureAsync(textureFile);

        // Apply tint if needed
        var tintConfig = blockTintConfigs.FirstOrDefault(config => config.blockName.Equals(fileName, System.StringComparison.OrdinalIgnoreCase));
        if (tintConfig != null)
        {
            ApplyTint(texture, tintConfig, maskTextures);
        }

        return (fileName, texture);
    }

    private async Task<Texture2D> LoadTextureAsync(string filePath)
    {
        byte[] fileData;
        using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true))
        {
            fileData = new byte[fs.Length];
            await fs.ReadAsync(fileData, 0, (int)fs.Length);
        }
        Texture2D texture = new Texture2D(2, 2, TextureFormat.RGBA32, false)
        {
            filterMode = FilterMode.Point
        };
        texture.LoadImage(fileData);
        return texture;
    }

    private void ApplyTint(Texture2D texture, BlockTintConfig config, Dictionary<string, Texture2D> maskTextures)
    {
        Color[] pixels = texture.GetPixels();
        if (!string.IsNullOrEmpty(config.maskName) && maskTextures.TryGetValue(config.maskName, out Texture2D maskTexture))
        {
            if (maskTexture.width == texture.width && maskTexture.height == texture.height)
            {
                Color[] maskPixels = maskTexture.GetPixels();
                for (int i = 0; i < pixels.Length; i++)
                {
                    float maskIntensity = maskPixels[i].grayscale;
                    pixels[i] = Color.Lerp(pixels[i], pixels[i] * config.tintColor, maskIntensity);
                }
            }
            else
            {
                Debug.LogWarning($"Mask texture {config.maskName} dimensions don't match block texture {config.blockName}");
            }
        }
        else
        {
            for (int i = 0; i < pixels.Length; i++)
            {
                pixels[i].r *= config.tintColor.r;
                pixels[i].g *= config.tintColor.g;
                pixels[i].b *= config.tintColor.b;
            }
        }
        texture.SetPixels(pixels);
        texture.Apply();
    }

    private Texture2D CreateFallbackTexture()
    {
        Texture2D fallback = new Texture2D(16, 16, TextureFormat.RGBA32, false)
        {
            filterMode = FilterMode.Point
        };

        Color pink = new Color(1f, 0f, 1f, 1f);
        Color black = Color.black;

        for (int y = 0; y < 16; y++)
        {
            for (int x = 0; x < 16; x++)
            {
                Color color = ((x + y) % 2 == 0) ? pink : black;
                fallback.SetPixel(x, y, color);
            }
        }

        fallback.Apply();
        return fallback;
    }

    private int GetTextureIndexForTextureName(string textureName)
    {
        if (blockNameToTextureIndex.TryGetValue(textureName, out int textureIndex))
        {
            return textureIndex;
        }

        Debug.LogWarning($"No texture found for name: {textureName}. Using default texture.");
        return defaultTextureIndex;
    }

    private Vector2[] GetUVsForTexture(string textureName)
    {
        int textureIndex = GetTextureIndexForTextureName(textureName);

        if (textureIndex >= atlasRects.Length || textureIndex < 0)
        {
            Debug.LogError($"Invalid texture index: {textureIndex} for texture: {textureName}");
            textureIndex = defaultTextureIndex;
        }

        if (!uvCache.TryGetValue(textureIndex, out Vector2[] uvs))
        {
            Rect uvRect = atlasRects[textureIndex];
            uvs = new Vector2[]
            {
                new Vector2(uvRect.x, uvRect.y),
                new Vector2(uvRect.x + uvRect.width, uvRect.y),
                new Vector2(uvRect.x + uvRect.width, uvRect.y + uvRect.height),
                new Vector2(uvRect.x, uvRect.y + uvRect.height)
            };
            uvCache[textureIndex] = uvs;
        }
        return uvs;
    }

    private async Task FetchBlocksAsync()
    {
        using (UnityWebRequest webRequest = UnityWebRequest.Get(serverUrl))
        {
            var operation = webRequest.SendWebRequest();
            while (!operation.isDone)
            {
                await Task.Yield();
            }

            if (webRequest.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError("Error fetching block data: " + webRequest.error);
            }
            else
            {
                string jsonResponse = webRequest.downloadHandler.text;
                blockDataList = JsonConvert.DeserializeObject<List<BlockData>>(jsonResponse);

                // Process blocks
                foreach (var block in blockDataList)
                {
                    AddBlockFaces(block);
                }

                CreateMesh();
            }
        }
    }

    private void AddBlockFaces(BlockData block)
    {
        Vector3 blockPosition = new Vector3(block.x, block.y, block.z);

        if (!blockConfigMap.TryGetValue(block.block_name, out BlockTextureConfig config))
        {
            config = new BlockTextureConfig { blockName = block.block_name };
            config.SetDefaults(block.block_name);
        }

        Dictionary<string, Mesh> customMeshes = new Dictionary<string, Mesh>
        {
            { "_slab", slabMesh },
            { "_fence", fenceMesh },
            { "_stairs", stairMesh }
        };
        string replace = null;
        string add = null;

        Mesh selectedMesh = config.customMesh;

        if (selectedMesh == null)
        {
            foreach (var kvp in customMeshes)
            {
                if (config.blockName.Contains(kvp.Key))
                {
                    selectedMesh = kvp.Value;
                    replace = kvp.Key;

                    if (woodTypes.Any(wt => config.front.Contains(wt)))
                    {
                        add = "_planks";
                    }
                    break;
                }
            }
        }

        if (selectedMesh != null)
        {
            AddCustomMeshToChunk(blockPosition, selectedMesh, config.front, replace, add);
        }
        else if (config.isBillboard)
        {
            AddBillboardFacesToChunk(blockPosition, config);
        }
        else
        {
            AddDefaultCubeFacesToChunk(blockPosition, config);
        }
    }

    private void AddCustomMeshToChunk(Vector3 blockPosition, Mesh customMesh, string textureName, string replace, string add)
    {
        if (replace != null)
        {
            textureName = textureName.Replace(replace, "") + add;
        }

        MeshChunk chunk = GetCurrentChunk();
        Vector2[] textureUVs = GetUVsForTexture(textureName);
        int vertCount = chunk.vertices.Count;

        Vector3[] vertices = customMesh.vertices;
        int[] triangles = customMesh.triangles;
        int vertexCount = vertices.Length;

        for (int i = 0; i < vertexCount; i++)
        {
            chunk.vertices.Add(vertices[i] + blockPosition);
            chunk.uvs.Add(textureUVs[i % 4]);
        }

        for (int i = 0; i < triangles.Length; i++)
        {
            chunk.triangles.Add(vertCount + triangles[i]);
        }
    }

    private MeshChunk GetCurrentChunk()
    {
        if (meshChunks.Count == 0 || meshChunks[meshChunks.Count - 1].isFull)
        {
            meshChunks.Add(new MeshChunk());
        }
        return meshChunks[meshChunks.Count - 1];
    }

    private void AddBillboardFacesToChunk(Vector3 blockPosition, BlockTextureConfig config)
    {
        Vector2[] textureUVs = GetUVsForTexture(config.front);

        for (int planeIndex = 0; planeIndex < 2; planeIndex++)
        {
            MeshChunk chunk = GetCurrentChunk();
            int vertCount = chunk.vertices.Count;

            for (int i = 0; i < 4; i++)
            {
                chunk.vertices.Add(billboardVertices[planeIndex][i] + blockPosition);
                chunk.uvs.Add(textureUVs[i]);
            }

            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 2);
            chunk.triangles.Add(vertCount + 1);
            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 3);
            chunk.triangles.Add(vertCount + 2);

            chunk = GetCurrentChunk();
            vertCount = chunk.vertices.Count;

            for (int i = 0; i < 4; i++)
            {
                chunk.vertices.Add(billboardVertices[planeIndex][i] + blockPosition);
                chunk.uvs.Add(textureUVs[i]);
            }

            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 1);
            chunk.triangles.Add(vertCount + 2);
            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 2);
            chunk.triangles.Add(vertCount + 3);
        }
    }

    private void AddDefaultCubeFacesToChunk(Vector3 blockPosition, BlockTextureConfig config)
    {
        string[] faceTextures = new string[]
        {
            config.front,
            config.back,
            config.top,
            config.bottom,
            config.left,
            config.right
        };

        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
        {
            MeshChunk chunk = GetCurrentChunk();
            Vector2[] textureUVs = GetUVsForTexture(faceTextures[faceIndex]);
            int vertCount = chunk.vertices.Count;

            for (int i = 0; i < 4; i++)
            {
                chunk.vertices.Add(faceVertices[faceIndex, i] + blockPosition);
                chunk.uvs.Add(textureUVs[i]);
            }

            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 2);
            chunk.triangles.Add(vertCount + 1);
            chunk.triangles.Add(vertCount + 0);
            chunk.triangles.Add(vertCount + 3);
            chunk.triangles.Add(vertCount + 2);
        }
    }

    private void CreateMesh()
    {
        GameObject chunksParent = new GameObject("ChunkedMeshes");
        chunksParent.transform.position = Vector3.zero;

        for (int i = 0; i < meshChunks.Count; i++)
        {
            MeshChunk chunk = meshChunks[i];
            GameObject chunkObject = new GameObject($"MeshChunk_{i}");
            chunkObject.transform.parent = chunksParent.transform;
            chunkObject.transform.localPosition = Vector3.zero;

            MeshFilter meshFilter = chunkObject.AddComponent<MeshFilter>();
            MeshRenderer meshRenderer = chunkObject.AddComponent<MeshRenderer>();
            Mesh mesh = new Mesh
            {
                indexFormat = UnityEngine.Rendering.IndexFormat.UInt32
            };

            mesh.SetVertices(chunk.vertices);
            mesh.SetTriangles(chunk.triangles, 0);
            mesh.SetUVs(0, chunk.uvs);
            mesh.RecalculateNormals();

            meshFilter.mesh = mesh;
            meshRenderer.material = blockMaterial;

            chunkObject.AddComponent<MeshCollider>().sharedMesh = mesh;
        }

        Debug.Log($"Created {meshChunks.Count} mesh chunks");
    }
}