U8G2 library in Page Buffer - Freeze Display?

I've been playing around with the U8G2 library as a relative novice to display drivers. I'm using in conjunction with a NHD-2.8-25664UCB2 display (SD1322 driver).

I'm using in page buffer mode, which I admit I don't fully understand. Occasionally I encounter flicker issues (probably from the number of pixels I'm trying to drive?) and from everything I've read the solution is either 1)Processor Speed 2)Buffer Mode 3)Selectively updating the display.

My question is, with the page buffer mode, is there a way to tell the screen which pixels you want on and then freeze them until it needs updating again? I can't seem to figure out how to do that with the Page/NextPage commands. Code below if applicable:

#include <Arduino.h>
#include <SPI.h>
#include <U8g2lib.h>
#include <SparkFun_Qwiic_Button.h>
QwiicButton button;

U8G2_SSD1322_NHD_256X64_1_4W_SW_SPI u8g2(U8G2_R0, /*clock*/13, /*data*/11,/* cs*/10, /*dc*/9, /*reset*/ 8); 

bool last_buttonstate = false;
bool button_state = false;
int menu_selec = 0;

void setup(void) {
  u8g2.begin();

  Serial.begin(115200);
  Serial.println("Qwiic button examples");
  Wire.begin(); //Join I2C bus

  //check if button will acknowledge over I2C
  if (button.begin() == false) {
    Serial.println("Device did not acknowledge! Freezing.");
    while (1);
  }
  Serial.println("Button acknowledged.");
  
}

void loop(void) {

  button_state = button.isPressed();

  if (button_state != last_buttonstate ) {
    if (button_state == true){
      if (menu_selec < 2){
          menu_selec += 1;
        }
      else {
        menu_selec = 0;
        }
    }
 }

  last_buttonstate = button_state;
  
  u8g2.firstPage();
  do {
    u8g2.setContrast(255);
    u8g2.setDrawColor(1);
    u8g2.setFont(u8g2_font_courB18_tr);
    u8g2.drawStr(0,64,"POWER SETTING XXXXXXXXX");

    switch (menu_selec) {
      case 0:
        u8g2.setDrawColor(0);
        u8g2.drawBox(158,14,91,15);
        u8g2.setDrawColor(1);

        u8g2.drawBox(0,0,102,15);
        
        u8g2.drawStr(159,14,"TIMER 2:00");
        u8g2.drawStr(0,38,"CANCEL?");
               
        u8g2.setDrawColor(0);
        u8g2.drawStr(0,14,"RUN?");
      break;

      case 1:
        u8g2.setDrawColor(0);
        u8g2.drawBox(0,0,102,15);
        u8g2.setDrawColor(1);
        u8g2.drawStr(0,14,"RUN?");

        u8g2.drawStr(159,14,"TIMER 2:00");
  
        u8g2.drawBox(0,24,84,15);
        
        u8g2.setDrawColor(0);
        u8g2.drawStr(0,38,"CANCEL?");
      break;

      case 2:
        u8g2.setDrawColor(0);
        u8g2.drawBox(0,24,84,15);
        u8g2.setDrawColor(1);

        u8g2.drawBox(158,0,91,15);

        u8g2.drawStr(0,14,"RUN?");
        
        u8g2.drawStr(0,38,"CANCEL?");
       
        u8g2.setDrawColor(0);
        u8g2.drawStr(159,14,"TIMER 2:00");
      break;

     default:
     break; 
    }
      
  } while ( u8g2.nextPage() );
  //delay(1000); 
}

Life is much simpler with a _F_xxx constructor i.e. Full Buffer.
But you can't afford the SRAM memory in a Uno / Nano.

I also note that you are using xxx_1_4W_SW_SPI() constructor.
HW_SPI is much faster. xxx_F_4W_HW_SPI() is best if you have sufficient SRAM.

The most important step in any project is : only update screen when something has changed.

David.

So that's kinda my question, should I be running:

u8g2.firstPage();
do {
Draw Graphics
} while ( u8g2.nextPage() );

once with the initial setup, then not calling that again until I draw different graphics?

Yes