I’ve decided to migrate from x11vnc to tigervnc since tigervnc may be more optimized. The script that was used previously can be slightly adapted.

start-tigervnc.sh
#!/bin/bash

VNC_PASS=/home/jerry/.vnc/passwd
LOG_FILE=/var/log/tigervnc.log
USER_XAUTH="/home/jerry/.Xauthority"
LIGHTDM_XAUTH="/var/lib/lightdm/.Xauthority"
LIGHTDM_STATE="/var/run/lightdm/root"

# Function to find the active display and its Xauthority file
find_active_display() {
    if [ -f /var/run/lightdm/root/:1 ]; then
        echo ":1 $LIGHTDM_XAUTH"
    # Check for greeter (:0, no user logged in)
    elif [ -f /var/run/lightdm/root/:0 ]; then
        echo ":0 $USER_XAUTH"
    fi
}

stop_vnc() {
    pkill -9 -f "x0vncserver" 2>/dev/null
    while pgrep -f "x0vncserver" >/dev/null; do
        sleep 1
    done
    pkill -9 -f "X0tigervnc" 2>/dev/null
    while pgrep -f "X0tigervnc" >/dev/null; do
        sleep 1
    done
}

start_vnc() {
    local display=$1
    local xauth_file=$2
    # Get current display and Xauthority

    XAUTHORITY="$xauth_file" x0vncserver -display "$display" -rfbauth $VNC_PASS -rfbport 5900 -localhost no >> $LOG_FILE 2>&1 &
}

read display xauth_file < <(find_active_display)
start_vnc "$display" "$xauth_file"

inotifywait -m "$LIGHTDM_STATE" -e create -e delete -e modify |
    while read -r directory events filename; do
        echo "Detected change in $directory: $filename ($events)" >&2
        stop_vnc
        sleep 0.5
        read display xauth_file < <(find_active_display)
        if [ -n "$display" ] && [ -n "$xauth_file" ]; then
            start_vnc "$display" "$xauth_file"
        fi
    done

systemd unit:

[Unit]
Description=tigervnc VNC Server for LightDM and User Sessions
After=lightdm.service
Wants=lightdm.service

[Service]
Type=simple
ExecStart=/usr/local/bin/start-tigervnc.sh
ExecStop=pkill -9 -f "x0vncserver" && pkill -9 -f "X0tigervnc"
Restart=always
RestartSec=5
User=root
Environment=DISPLAY=:0
ExecStartPre=/bin/sleep 2

[Install]
WantedBy=multi-user.target