```lua
-- cl_firstperson_optimized.lua

if CLIENT then
    -------------------------------------------------------------------
    -- FirstPersonView Module
    -- Enhanced first-person view implementation with robust error handling,
    -- dynamic configuration, and optimized performance.
    -------------------------------------------------------------------

    -- Define the FirstPersonView table
    local FirstPersonView = {
        -- Configuration table with default values. These can be overridden via
        -- console variables (ConVars) for dynamic configuration.
        config = {
            headBoneNames = { "ValveBiped.Bip01_Head1", "ValveBiped.Bip01_Neck1", "ValveBiped.Bip01_EyeLeft", "ValveBiped.Bip01_EyeRight", "ValveBiped.Bip01_Mouth" }, -- Priority-ordered list of head bone names
            cameraOffset = Vector(2, 0, 0.2), -- Default camera offset (modifiable via ConVar)
            drawLocalPlayer = true, -- Whether to draw the local player model in first-person
            spectatorTeam = TEAM_SPECTATOR or 8, -- Spectator team identifier (modifiable via ConVar)
            notifyOnError = true, -- Whether to notify the player on errors
            cameraSmoothness = 0.2, -- Camera smoothing factor (0 to 1)
            maxCameraDistance = 60, -- Maximum camera distance to prevent clipping
            cameraCollision = true, -- Whether to enable camera collision detection
        },

        -- Table to cache head bone indices per model
        headBoneIndices = {},

        -- Flag to ensure single initialization
        initialized = false,

        -- Rate limiter for error notifications to prevent spam
        errorRateLimiter = {
            lastErrorTime = 0,
            cooldown = 5, -- seconds
        },
    }

    -- Utility function to log messages with a prefix
    local function Log(message, isError)
        if isError then
            if FirstPersonView.config.notifyOnError then
                chat.AddText(Color(255, 0, 0), "[FirstPersonView] " .. message)
            end
            print("[FirstPersonView] " .. message)
        else
            print("[FirstPersonView] " .. message)
        end
    end

    -- Utility function to check and update the rate limiter
    local function CanNotifyError()
        local currentTime = CurTime()
        if currentTime - FirstPersonView.errorRateLimiter.lastErrorTime >= FirstPersonView.errorRateLimiter.cooldown then
            FirstPersonView.errorRateLimiter.lastErrorTime = currentTime
            return true
        end
        return false
    end

    -- Function to load and apply camera offset from ConVar
    local function LoadCameraOffset()
        local offsetX = GetConVar("fvp_camera_offset_x"):GetFloat()
        local offsetY = GetConVar("fvp_camera_offset_y"):GetFloat()
        local offsetZ = GetConVar("fvp_camera_offset_z"):GetFloat()
        FirstPersonView.config.cameraOffset = Vector(offsetX, offsetY, offsetZ)
    end

    -- Function to load head bone names from ConVar (comma-separated)
    local function LoadHeadBoneNames()
        local boneNamesString = GetConVar("fvp_head_bone_names"):GetString()
        local boneNames = string.Split(boneNamesString, ",")

        -- Trim whitespace and ensure uniqueness
        local uniqueBoneNames = {}
        for _, name in ipairs(boneNames) do
            local trimmed = string.Trim(name)
            if trimmed ~= "" and not uniqueBoneNames[trimmed] then
                table.insert(uniqueBoneNames, trimmed)
                uniqueBoneNames[trimmed] = true
            end
        end
        FirstPersonView.config.headBoneNames = uniqueBoneNames
    end

    -- Load spectator team from ConVar
    local function LoadSpectatorTeam()
        FirstPersonView.config.spectatorTeam = GetConVar("fvp_spectator_team"):GetInt()
    end

    -- Function to initialize ConVars for dynamic configuration
    local function InitializeConVars()
        CreateClientConVar("fvp_camera_offset_x", "2", true, false, "FirstPersonView: Camera offset X (forward/backward)")
        CreateClientConVar("fvp_camera_offset_y", "0", true, false, "FirstPersonView: Camera offset Y (left/right)")
        CreateClientConVar("fvp_camera_offset_z", "0.2", true, false, "FirstPersonView: Camera offset Z (up/down)")
        CreateClientConVar("fvp_head_bone_names", "ValveBiped.Bip01_Head1,ValveBiped.Bip01_Neck1,ValveBiped.Bip01_EyeLeft,ValveBiped.Bip01_EyeRight,ValveBiped.Bip01_Mouth", true, false, "FirstPersonView: Comma-separated list of head bone names")
        CreateClientConVar("fvp_spectator_team", tostring(FirstPersonView.config.spectatorTeam), true, false, "FirstPersonView: Spectator team identifier")
    end

    -- Function to refresh configuration from ConVars
    local function RefreshConfig()
        LoadCameraOffset()
        LoadHeadBoneNames()
        LoadSpectatorTeam()
    end

    -- Hook to watch for ConVar changes and refresh configuration accordingly
    local function SetupConVarChangeHooks()
        -- Camera Offset Change
        cvars.AddChangeCallback("fvp_camera_offset_x", function() LoadCameraOffset() end, "FirstPersonView_CameraOffsetX")
        cvars.AddChangeCallback("fvp_camera_offset_y", function() LoadCameraOffset() end, "FirstPersonView_CameraOffsetY")
        cvars.AddChangeCallback("fvp_camera_offset_z", function() LoadCameraOffset() end, "FirstPersonView_CameraOffsetZ")
        -- Head Bone Names Change
        cvars.AddChangeCallback("fvp_head_bone_names", function() LoadHeadBoneNames() end, "FirstPersonView_HeadBoneNames")
        -- Spectator Team Change
        cvars.AddChangeCallback("fvp_spectator_team", function() LoadSpectatorTeam() end, "FirstPersonView_SpectatorTeam")
    end

    -- Function to cache head bone indices for a given player model
    function FirstPersonView:CacheHeadBone(ply)
        if not IsValid(ply) then return end

        local model = ply:GetModel()
        if not model then return end

        -- Initialize cache for the model if not present
        if not self.headBoneIndices[model] then
            self.headBoneIndices[model] = {}
        end

        -- Clear existing cached bones for this model to handle model changes
        table.Empty(self.headBoneIndices[model])

        -- Iterate through the list of possible head bone names and cache all found bones
        for _, boneName in ipairs(self.config.headBoneNames) do
            local boneIndex = ply:LookupBone(boneName)
            if boneIndex then
                table.insert(self.headBoneIndices[model], boneIndex)
                Log("Cached head bone '" .. boneName .. "' (Index: " .. tostring(boneIndex) .. ") for model '" .. model .. "'.", false)
            end
        end

        -- If no head bones found, log warning with rate limiting
        if #self.headBoneIndices[model] == 0 then
            if CanNotifyError() then
                Log("Warning: No valid head bones found for model '" .. model .. "'. Expected bones: " .. table.concat(self.config.headBoneNames, ", "), true)
            end
        end
    end

    -- Function to get the head position and angle for the local player
    function FirstPersonView:GetHeadPos()
        local ply = LocalPlayer()
        if not IsValid(ply) then return nil, nil end

        local model = ply:GetModel()
        if not model then return nil, nil end

        local boneIndices = self.headBoneIndices[model]
        if not boneIndices or #boneIndices == 0 then
            -- Attempt to cache the head bones
            self:CacheHeadBone(ply)
            boneIndices = self.headBoneIndices[model]
            if not boneIndices or #boneIndices == 0 then
                -- Fallback to eye position if head bones not found
                Log("Using eye position as fallback for camera.", true)
                return ply:EyePos(), ply:EyeAngles()
            end
        end

        -- Calculate the average position and angle of all head bones
        local totalPos = Vector(0, 0, 0)
        local totalAng = Angle(0, 0, 0)
        for _, boneIndex in ipairs(boneIndices) do
            local bonePos, boneAng = ply:GetBonePosition(boneIndex)
            if bonePos and boneAng then
                totalPos = totalPos + bonePos
                totalAng.pitch = totalAng.pitch + boneAng.pitch
                totalAng.yaw = totalAng.yaw + boneAng.yaw
                totalAng.roll = totalAng.roll + boneAng.roll
            end
        end
        local count = #boneIndices
        local averagePos = totalPos / count
        local averageAng = Angle(totalAng.pitch / count, totalAng.yaw / count, totalAng.roll / count)

        return averagePos, averageAng
    end

    -- Variable to store the current view (for smoothing)
    local currentView = {
        origin = Vector(0,0,0),
        angles = Angle(0,0,0),
        fov = 0,
        drawviewer = false,
    }

    -- Hook to calculate and set the camera view
    function FirstPersonView:CalcView(ply, pos, angles, fov)
        if not IsValid(ply) or ply:Team() == self.config.spectatorTeam then return end

        local headPos, headAng = self:GetHeadPos()
        if not headPos or not headAng then return end

        -- Calculate the desired camera position based on the head position and camera offset
        local desiredCameraPos = headPos + headAng:Forward() * self.config.cameraOffset.x
                                      + headAng:Right() * self.config.cameraOffset.y
                                      + headAng:Up() * self.config.cameraOffset.z

        -- Implement camera collision detection to prevent clipping
        if self.config.cameraCollision then
            local trace = {}
            trace.start = headPos
            trace.endpos = desiredCameraPos
            trace.filter = ply
            trace.mask = MASK_VISIBLE_AND_NPCS
            local tr = util.TraceLine(trace)
            if tr.Hit then
                desiredCameraPos = tr.HitPos
            end
        end

        -- Apply smoothing to the camera movement
        currentView.origin = LerpVector(self.config.cameraSmoothness, currentView.origin, desiredCameraPos)
        currentView.angles = angles -- Maintain the player's view angles
        currentView.fov = fov
        currentView.drawviewer = self.config.drawLocalPlayer

        return currentView
    end

    -- Hook to determine whether to draw the local player model
    function FirstPersonView:ShouldDrawLocalPlayer()
        local ply = LocalPlayer()
        if not IsValid(ply) then return true end

        -- Do not draw the player model if in spectator mode
        if ply:Team() == self.config.spectatorTeam then
            return false
        end

        return self.config.drawLocalPlayer
    end

    -- Hook to handle player model changes
    function FirstPersonView:OnPlayerSetModel(ply)
        if ply ~= LocalPlayer() then return end
        self:CacheHeadBone(ply)
    end

    -- Hook to handle player spawn events
    function FirstPersonView:OnPlayerSpawn(ply)
        if ply ~= LocalPlayer() then return end

        -- Delay caching to ensure the model is fully loaded
        timer.Simple(0.5, function()
            if IsValid(ply) then
                self:CacheHeadBone(ply)
            end
        end)
    end

    -- Hooks to hide and show the player’s head bones during rendering
    function FirstPersonView:PrePlayerDraw(ply)
        if ply ~= LocalPlayer() then return end

        local model = ply:GetModel()
        local boneIndices = self.headBoneIndices[model]
        if boneIndices and #boneIndices > 0 then
            for _, boneIndex in ipairs(boneIndices) do
                ply:ManipulateBoneScale(boneIndex, Vector(0, 0, 0)) -- Hide head bone
            end
        end
    end

    function FirstPersonView:PostPlayerDraw(ply)
        if ply ~= LocalPlayer() then return end

        local model = ply:GetModel()
        local boneIndices = self.headBoneIndices[model]
        if boneIndices and #boneIndices > 0 then
            for _, boneIndex in ipairs(boneIndices) do
                ply:ManipulateBoneScale(boneIndex, Vector(1, 1, 1)) -- Show head bone
            end
        end
    end

    -- Function to clean up all hooks and cached data
    function FirstPersonView:RemoveHooks()
        hook.Remove("CalcView", "FirstPersonView_CalcView")
        hook.Remove("ShouldDrawLocalPlayer", "FirstPersonView_ShouldDrawLocalPlayer")
        hook.Remove("PlayerSetModel", "FirstPersonView_PlayerSetModel")
        hook.Remove("ShutDown", "FirstPersonView_ShutDown")
        hook.Remove("InitPostEntity", "FirstPersonView_Initialize")
        hook.Remove("PlayerSpawn", "FirstPersonView_PlayerSpawn")
        hook.Remove("PrePlayerDraw", "FirstPersonView_PrePlayerDraw")
        hook.Remove("PostPlayerDraw", "FirstPersonView_PostPlayerDraw")
        hook.Remove("PlayerDisconnected", "FirstPersonView_PlayerDisconnected")

        -- Clear cached bone indices
        table.Empty(self.headBoneIndices)

        self.initialized = false
        Log("All hooks removed and caches cleared.", false)
    end

    -- Hook to handle player disconnection and clean up cache
    function FirstPersonView:OnPlayerDisconnected(ply)
        if IsValid(ply) then
            local model = ply:GetModel()
            if model and self.headBoneIndices[model] then
                self.headBoneIndices[model] = nil
                Log("Cleared cached head bones for model '" .. model .. "' due to player disconnection.", false)
            end
        end
    end

    -- Initialization function
    function FirstPersonView:Initialize()
        if self.initialized then
            Log("Initialization skipped: already initialized.", false)
            return
        end

        self.initialized = true
        InitializeConVars()
        RefreshConfig()
        SetupConVarChangeHooks()

        -- Cache head bones for the local player
        self:CacheHeadBone(LocalPlayer())

        -- Register hooks
        hook.Add("CalcView", "FirstPersonView_CalcView", function(ply, pos, angles, fov)
            return self:CalcView(ply, pos, angles, fov)
        end)

        hook.Add("ShouldDrawLocalPlayer", "FirstPersonView_ShouldDrawLocalPlayer", function()
            return self:ShouldDrawLocalPlayer()
        end)

        hook.Add("PlayerSetModel", "FirstPersonView_PlayerSetModel", function(ply)
            self:OnPlayerSetModel(ply)
        end)

        hook.Add("ShutDown", "FirstPersonView_ShutDown", function()
            self:RemoveHooks()
        end)

        hook.Add("InitPostEntity", "FirstPersonView_Initialize", function()
            self:CacheHeadBone(LocalPlayer())
        end)

        hook.Add("PlayerSpawn", "FirstPersonView_PlayerSpawn", function(ply)
            self:OnPlayerSpawn(ply)
        end)

        hook.Add("PrePlayerDraw", "FirstPersonView_PrePlayerDraw", function(ply)
            self:PrePlayerDraw(ply)
        end)

        hook.Add("PostPlayerDraw", "FirstPersonView_PostPlayerDraw", function(ply)
            self:PostPlayerDraw(ply)
        end)

        hook.Add("PlayerDisconnected", "FirstPersonView_PlayerDisconnected", function(ply)
            self:OnPlayerDisconnected(ply)
        end)

        Log("FirstPersonView initialized successfully.", false)
    end

    -- Ensure initialization occurs after all entities are loaded
    hook.Add("InitPostEntity", "FirstPersonView_Start", function()
        FirstPersonView:Initialize()
    end)

    -- Prevent multiple instances by checking if already initialized
    if not FirstPersonView.initialized then
        FirstPersonView:Initialize()
    end

    -------------------------------------------------------------------
    -- End of FirstPersonView Module
    -------------------------------------------------------------------
end
```
Перечисли все возможные баги, ошибки, недочеты, утечки, излишки кода и другие проблемы.