Я работаю с относительно большим Canvas, к которому обращаются различные (сложные) вещи. Затем я хочу сохранить состояние Canvas, чтобы быстро восстановить его до состояния, в котором оно находится сейчас. Я использую getImageData для этого и храню данные в переменной. Затем я рисую еще кое-что на холст и позже верну Canvas к тому месту, где он был при сохранении его состояния, используя putImageData.
Однако оказывается, что putImageData очень медленный. Фактически, это медленнее, чем просто перерисовка всего Canvas с нуля, что включает в себя несколько drawImage, покрывающих большую часть поверхности, и более 40 000 операций lineTo, сопровождаемых штрихами и заливками.
Перерисовка холста размером примерно 2000 x 5000 пикселей с нуля занимает ~ 170 мс, с использованием putImageData, хотя и занимает колоссальные 240 мс. Почему putImageData такой медленный по сравнению с перерисовкой холста, хотя перерисовка холста включает заполнение почти всего холста с помощью drawImage, а затем снова заполнение примерно 50% холста полигонами, используя lineTo, обводку и заливку. Таким образом, при перерисовке каждый пиксель затрагивается хотя бы один раз.
Поскольку drawImage выглядит намного быстрее, чем putImageData (в конце концов, часть drawImage при перерисовке холста занимает менее 30 мс). Я решил попытаться сохранить состояние холста, не используя getImageData, а вместо этого используя canvas.toDataURL, а затем создав изображение из URL-адреса данных, который я вставил в drawImage, чтобы нарисовать его на холсте. Оказывается, вся эта процедура намного быстрее и занимает всего 35 мсек.
Так почему же putImageData намного медленнее, чем альтернативы (с использованием getDataURL или просто перерисовкой)? Как я мог ускорить процесс дальше? Есть ли и если, вообще, лучший способ сохранить состояние холста?
(Все числа измеряются с помощью Firebug из Firefox)