How to correctly move the character back to previous frame position

I have used a navMesh to simulate collision in my scene, my character is shaking when collide with a wall. I think this will happen because I tried to move my character back to the previous frame position when collision occur, but I don’t have a good calculation to do so, so the character keep moving back and forth so fast that cause this shaking issue. please check my character movement code the video below. Please anyone can give me an advice or provide good calculation for this problem.

This is my the movement logic for the character

class CharacterControllerComponent {
    decceleration
    acceleration
    velocity

    controlAvatar
    controlAvatarAnimationMixer

    navMesh
    up
    down
    positionVector
    collisionVector
    raycaster
    intersects
    positionOffset
    currentPosition
    newPosition

    currentPoint
    lastPoint

    AssetsLoadComponent
    InputComponent
    CameraMovementComponent

    get GetControlAvatar() {
        return this.controlAvatar;
    }

    // Get the camera object that belongs to the specific character instance
    get GetControlCamera() {
        for (let i = 0; i < this.controlAvatar.children.length; i++) {
            const childObject = this.controlAvatar.children[i]
            if (childObject.type === 'PerspectiveCamera') {
                return childObject;
            }
        }
    }

    constructor(params) {
        this.Init(params);
    }

    Init(params) {
        this.decceleration = new THREE.Vector3(-5.0, -0.0001, -5.0);
        this.acceleration = new THREE.Vector3(5.0, 0, 5.0);
        this.velocity = new THREE.Vector3(0, 0, 0);

        this.up = new THREE.Vector3(0.0, 1.0, 0.0);
        this.down = new THREE.Vector3(0.0, -1.0, 0.0);
        this.positionVector = new THREE.Vector3(0, 0, 0,);
        this.collisionVector = new THREE.Vector3(0, 0, 0,);
        this.raycaster = new THREE.Raycaster(
            this.positionVector,
            this.down,
            0.0,
            10.0
        );
        this.currentPosition = new THREE.Vector3(0, 0, 0)
        this.positionOffset = new THREE.Vector3(0, 0, 0)
        this.newPosition = new THREE.Vector3(0, 0, 0)

        this.currentPoint = new THREE.Vector3()
        this.lastPoint = new THREE.Vector3()
        
        this.AssetsLoadComponent = params.AssetsLoadComponent
        this.InputComponent = new InputComponent();
        this.CameraMovementComponent = new CameraMovementComponent(this)
    }

    // Calculate the character movement
    Update(timeInSecond) {

        if (!this.AssetsLoadComponent.GetAvatar || !this.AssetsLoadComponent.GetNavMesh) return

        if (this.controlAvatar === undefined) this.controlAvatar = this.AssetsLoadComponent.GetAvatar
        if (this.stateMachine === undefined) this.stateMachine = this.AssetsLoadComponent.GetStateMachine
        if (this.navMesh === undefined) this.navMesh = this.AssetsLoadComponent.GetNavMesh

        // Update the Camera Movement to follow the character
        this.CameraMovementComponent.Update(timeInSecond)

        // Update the Animation Mixer
        if (this.controlAvatarAnimationMixer === undefined) this.controlAvatarAnimationMixer = this.AssetsLoadComponent.GetAnimationMixer
        this.controlAvatarAnimationMixer.update(timeInSecond);

        // Update the StateMachine System
        this.stateMachine.Update(timeInSecond, this.InputComponent);

        const avatar = this.controlAvatar;

        //Calculate the character each frame position and Spawn a raycaster to detect the navMesh which determine the walkable areas on the enviroment
        avatar.getWorldPosition(this.positionVector);
        this.up.normalize();
        this.down.normalize();
        this.collisionVector.copy(this.positionVector).add(this.up.multiplyScalar(0.1));
        this.raycaster.set(this.collisionVector, this.down);
        this.intersects = this.raycaster.intersectObject(this.navMesh, true);


        // Character is on the wallkable area
        if (this.intersects.length > 0) {
            // Character Movement Logic Calculation Below
            const velocity = this.velocity;
            const frameDecceleration = new THREE.Vector3(
                velocity.x * this.decceleration.x,
                velocity.y * this.decceleration.y,
                velocity.z * this.decceleration.z
            );
            frameDecceleration.multiplyScalar(timeInSecond);
            frameDecceleration.z = Math.sign(frameDecceleration.z) * Math.min(
                Math.abs(frameDecceleration.z), Math.abs(velocity.z));

            velocity.add(frameDecceleration);

            // Running
            const acc = this.acceleration.clone();
            if (this.InputComponent.keys.shift) {
                acc.multiplyScalar(2.0);
            }

            // Walking
            if (this.InputComponent.keys.forward) {
                velocity.z += acc.z * timeInSecond;
            }
            if (this.InputComponent.keys.backward) {
                velocity.z -= acc.z * timeInSecond;
            }
            if (this.InputComponent.keys.left) {
                velocity.x += acc.x * timeInSecond;
            }
            if (this.InputComponent.keys.right) {
                velocity.x -= acc.x * timeInSecond;
            }

            const forward = new THREE.Vector3(0, 0, 1);
            forward.normalize();
            forward.multiplyScalar(velocity.z * timeInSecond);
            avatar.translateZ(forward.z)

            const sideways = new THREE.Vector3(1, 0, 0);
            sideways.normalize();
            sideways.multiplyScalar(velocity.x * timeInSecond);
            avatar.translateX(sideways.x);

            // change height when on stairs or slope
            const { point } = this.intersects[0]
            avatar.position.y = point.y + 0.03;

            // record the this current frame position
            this.positionOffset.copy(avatar.position)
            this.positionOffset.sub(this.currentPosition)
            this.currentPosition.copy(avatar.position)

            this.currentPoint = point
        }
        // Character is not on the walkable area
        // then collision should occur and the character should move back to previous frame position otherwise will get stick on the current frame position
        else {
            console.log(avatar);
            if (this.currentPoint === this.lastPoint) return
                console.log('occurs');
                this.newPosition = this.currentPosition.sub(this.positionOffset)
                avatar.position.lerp(this.currentPosition, timeInSecond * 0.01)
                this.lastPoint.copy(this.currentPoint)
            
        }
    }
};

This is where I update the movement

 tick() {
        requestAnimationFrame((t) => {

            const elapsedTime = this.clock.getElapsedTime()
            const deltaTime = elapsedTime - this.previousTime
            this.previousTime = elapsedTime

            if (this.CharacterControllerComponent) this.CharacterControllerComponent.Update(deltaTime);

            this.renderer.render(this.scene, this.camera);

            this.tick();
        });
    }