mqtt client stops the button from working correctly while disconnected

ok, i have my device with one relay and one button witch connects to mqtt.
While im connected to broker button works just fine, but when im not connected to broker the device reads the state of the button and changes the state of the switch sometimes (sometimes i mean once (sometimes two) while trying to reconnect :/) but not as it should.
Something is blocking the loop where is my btnCheck() funcion but i dont know where beacouse i usually runs code without delays and that wasnt a problem before i started exploring MQTT service.
And thats how i know thats MQTT thing
GOAL:
I want my button to controll the relay properly even while client is disconnected
heres the code:

/*
	Name:       sonoffS201.ino
	Created:	09.09.2019 17:43:08
	Author:     Zabor
*/

#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Ticker.h>
#define led 13
#define btn 0
#define relay 12

const char* host = "****";
const char* ssid = "****";
const char* password = "****";
IPAddress ip(****);
uint16_t port = ****;

const char* OTApassword = "****";

char* relayTopic = "****";
char* statusTopic = "****";

WiFiClient espClient;
PubSubClient client(espClient);
Ticker ledTicker;

void callback(char* topic, byte* payload, unsigned int length) {
	String msgString = "";
	for (int i = 0; i < length; i++) {
		msgString += (char)payload[i];
	}
	if (msgString.equals("1")) {
		digitalWrite(relay, HIGH);
	}
	if (msgString.equals("0")) {
		digitalWrite(relay, LOW);
	}
}

void ledTick() {
	digitalWrite(led, !digitalRead(led));
}

unsigned long btnTimeout = 0;
bool unpressed = true;
void btnCheck() {
	if (digitalRead(btn) == 0 && unpressed && millis() - btnTimeout >= 250) {
		if (digitalRead(relay) == HIGH) {
			digitalWrite(relay, LOW);
			client.publish(relayTopic, "0", true);
		} else {
			digitalWrite(relay, HIGH);
			client.publish(relayTopic, "1", true);
		}
		unpressed = false;
	}
	if (digitalRead(btn) == 1 && !unpressed) {
		btnTimeout = millis();
		unpressed = true;
	}
}

bool boot = false;
unsigned long lastReconnectAttempt = 0;
void clientHandle() {
	if (!client.connected()) {
		digitalWrite(led, HIGH);
		if (millis() - lastReconnectAttempt > 5000) {
			lastReconnectAttempt = millis();
			if (client.connect(host, statusTopic, 1, true, "disconnected")) {
				if (!boot) {
					client.publish(statusTopic, "connected", true);
					boot = true;
				} else client.publish(statusTopic, "reconnected", true);
				client.subscribe(relayTopic, 1);
			}
			if (client.connected()) {
				digitalWrite(led, LOW);
				lastReconnectAttempt = 0;
			}
		}
	} else {
		client.loop();
	}
}

void setup() {
	pinMode(led, OUTPUT);
	pinMode(relay, OUTPUT);
	pinMode(btn, INPUT);

	WiFi.hostname(host);
	WiFi.mode(WIFI_STA);

	ledTicker.attach(0.1, ledTick);
	
	WiFi.begin(ssid, password);
	while (WiFi.status() != WL_CONNECTED) { delay(500); };

	ledTicker.detach();
	digitalWrite(led, LOW);

	ArduinoOTA.onError([](ota_error_t error) { ESP.restart(); });
	ArduinoOTA.setHostname(host);
	ArduinoOTA.setPassword(OTApassword);
	ArduinoOTA.begin();

	client.setServer(ip, port);
	client.setCallback(callback);
}

void loop() {
	ArduinoOTA.handle();
	clientHandle();
	btnCheck();
}

Just spitballing here, but try commenting out:

client.publish(relayTopic, "1", true);

in the btnCheck function to see if this is where the blocking is occurring.

Or, don't try to publish if there's no MQTT connection:

if (client.connected()) client.publish(relayTopic, "1", true);

Also, you should be checking the connection in the loop():

  if (!client.loop())
    client.connect(connectName);    //Reconnect to mqtt broker

Please let me know if I was any help.

SteveMann:
Or, don't try to publish if there's no MQTT connection:

if (client.connected()) client.publish(relayTopic, "1", true);

Thanks, that was it. Publish function stops code when client is not connected. Checking connection before publish fixed the button and now works flawlessly.

SteveMann:
Also, you should be checking the connection in the loop():

  if (!client.loop())

client.connect(connectName);    //Reconnect to mqtt broker

I handle reconnection in clientHandle()

if (!client.connected()) {
    client.connect(connectName);
} else {
    client.loop();
}

but with addition of 5 seconds "delay" between tries