Accessing width and height variables much slower in P5 Ver 2.0 compared to Ver 1.0

I’ve remembered there’s another performance trick to handle p5js Uint8ClampedArray pixels[]:
Create a 32-bit array view for it, like Int32Array or Uint32Array, like this sketch I did a long time ago:

So for your example below:

Rather than assigning to 4 RGBa separate indices [i], [i+1], [i+2] and [i+3].
We instead create 1 32-bit aBGR color and assign it to just the index [i]:

"use strict";

/**
 * 32-bit Look-Up Table (LUT) for all 256 opaque gray colors
 */
const GRAY_LUT = Int32Array.from({ length: 256 },
  (_, gray) => 0xFF000000 | gray << 0o20 | gray << 0o10 | gray
);

/**
 * 32-bit array view for the p5js Uint8ClampedArray pixels[]
 * @type {Int32Array}
 */
var pix32View;

/**
 * Cached p5js gray color
 */
var bg;

function setup() {
  createCanvas(1024, 640);
  pixelDensity(1).loadPixels();

  frameRate(60).textSize(20).fill("yellow");

  pix32View = new Int32Array(pixels.buffer);
  bg = color(200);
}

function draw() {
  background(bg);

  var timer = millis();
  const { width, height } = this;

  for (var y = 0; y < height; ++y) {
    const yw = y * width;

    for (var x = 0; x < width; ++x) {
      const idx = yw + x, gray = idx % GRAY_LUT.length;
      pix32View[idx] = GRAY_LUT[gray];
    }
  }

  updatePixels();
  timer = millis() - timer;

  const hud = timer.toFixed(2) + '\t' + (1000 / timer).toFixed(2);
  text(hud, 5, height - 5);
}

The example above caches all 256 opaque shades of gray as Int32Array GRAY_LUT.

But for a regular p5.Color, you can use this callback w/ method reduce() over the { levels } = color(r, g, b) array:

function RGBa_Arr_to_aBGR_32bit_Val(acc, val, idx) { // .reduce() callback
  return val << idx * 0o10 | acc;
}

const { levels } = color(200, 100, 50);
const abgrValue = levels.reduce(RGBa_Arr_to_aBGR_32bit_Val, 0);

You’re starting to get the limits of my expertise now, but I understand the principle. I will play around with this, so thanks.