@ray_d another thing I should point out about the script I posted above (which may not be immediately obvious) is that when processing a sheet, it starts from the bottom and works its way up. This is absolutely vital. If you start from the top and work down, then you run the risk of deleting the wrong rows. This is because as soon as you delete a row, the indexes of all the following rows will change, and so you have an immediate off by one error.
Working from the bottom up avoids this problem. When you delete a row, the row indexes below will still change. But because those rows have already been processed, it doesn’t matter.
In terms of timing, although using an On Change trigger is relatively fast, it will still take up to a minute or two before the change is reflected in the app.
This is why I use the ‘Is Deleted?’ flag + visibility approach. It allows you to give the impression that the deletion is instant, even though the row is still there.