Particle.publish() took very long time up to ~12+ s to return

I would try a delay after Particle.publish() - comment / uncomment to try the two different delays out below:

if(Particle.connected()) {
  Particle.publish();
  //delay(1000);     // this will block for 1000ms allowing only ONE Particle.process()
  // or
  for(uint32_t _ms = millis(); millis() - _ms < 1000; Particle.process());  // many calls of Particle.process()
}

The rest of your code in loop() should be non-blocking. If you are using SYSTEM_MODE(MANUAL) you will need to place Particle.process() in your loop().

Also, there is a library you might check out where you can publish asynchronously (Great Stuff !!):
https://community.particle.io/t/publishqueueasyncrk-and-large-datasets/52733/20