Форум программистов, компьютерный форум, киберфорум
JavaScript для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885

Оптимизация работы с canvas. Производительность

23.01.2021, 21:34. Показов 2037. Ответов 6

Студворк — интернет-сервис помощи студентам
Всем привет
Как можно оптимизировать или ускорить работу с canvas и какие средства для этого существуют?
Так же, возможно кто-то может подсказать (приложил скриншот)
Я отрисовываю канвас, и казалось бы, всё это происходит быстро. Но вот task длинной в 200 ms и при этом все действия, вроде как - завершены, мне не нравится. Что может быть не так?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.01.2021, 21:34
Ответы с готовыми решениями:

Совместная работы функций Canvas.scale и Canvas.translate
Если указать точку опоры масштабирования в scale, то относительно неё происходит масштабирование. А что если предварительно холст...

Оптимизация и производительность Python
Здравствуйте. Ребят, всё чаще понимаю, что я всё больше и больше нуждаюсь в Python. Я изучаю C++, но есть 2 момента: 1) Чтобы...

Оптимизация Canvas
Вообщем возникла следующая проблема: имеется в буфере более 1.000.000 точек, необходимо вывести график с наименьшими затратами на время. На...

6
1786 / 1036 / 445
Регистрация: 12.05.2016
Сообщений: 2,550
23.01.2021, 21:37
EveKS, покажите код.
0
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
23.01.2021, 21:58  [ТС]
В моем случае, это видимо ангуляр с дом деревом так долго взаимодействует, но не факт
Именно _generateCanvas заставлят так долго выполняться
shvyrevvg, в моем случае не JS, а TS, но вопрос оптимизации относится к JS
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    private _generateCanvas(): void {
        const size: number = this._defaultRecSize;
        const updated: { [key: string]: boolean } = this._updated;
        const colorPoint: { [key: string]: IColRow[] } = this.colorPoint;
        const updatedColors = Object.keys(updated).filter((key) => updated[key]);
        const colors = Object.keys(colorPoint).filter((key) => updatedColors.indexOf(key) === -1);
 
        const context = this._context;
 
        for (let index = 0, length = updatedColors.length; index < length; index += 1) {
            const color = updatedColors[index];
            const points = colorPoint[color];
            if (!points) continue;
            context.fillStyle = color;
            for (let pointIndex = 0; pointIndex < points.length; pointIndex++) {
                const point = points[pointIndex];
                const x = point.col * size;
                const y = point.row * size;
 
                context.fillRect(x, y, size, size);
                this._currentUpdated[color] = true;
            }
        }
 
        const bigNumber = 1000;
        for (let index = 0; index < colors.length; index++) {
            const color = colors[index];
            const points = colorPoint[color];
            const big = points.filter((p) => p.num >= bigNumber);
            const small = points.filter((p) => p.num < bigNumber);
 
            context.strokeStyle = '#ccc';
 
            context.font = "9px Arial";
            context.textAlign = "center";
            context.textBaseline = "middle";
 
            this._fillContext(big, size);
 
            context.font = "11px Arial";
            context.textAlign = "center";
            context.textBaseline = "middle";
 
            this._fillContext(small, size);
        }
 
        setTimeout(() => this._updateCanvasPosition());
    }
Добавлено через 44 секунды
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    private _fillContext(points: IColRow[], size: number) {
        for (let pointIndex = 0; pointIndex < points.length; pointIndex++) {
            const point = points[pointIndex];
            const x = point.col * size;
            const y = point.row * size;
 
            this._context.fillStyle = '#fff';
            this._context.fillRect(x, y, size, size);
            this._context.fillStyle = '#666';
 
            this._context.strokeRect(x + 2, y + 2, size - 4, size - 4);
            this._context.fillText(point.num.toString(), (x - size / 2) + size, (y - size / 2) + size);
        }
    }
Добавлено через 22 секунды
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    private _updateCanvasPosition(): void {
        if (this.zoom === 100) return;
        const canvas = this._container.nativeElement;
        const canvasWidth = +canvas.width * this.zoom / 100;
        const canvasHeight = +canvas.height * this.zoom / 100;
        this._canvasPositionChange({ canvasWidth, canvasHeight })
    }
 
    private _canvasPositionChange({ canvasWidth, canvasHeight }): void {
        const canvas = this._container.nativeElement;
        const canvasContainer = this._canvasContainer.nativeElement;
        const canvasContainerWidth = +canvasContainer.clientWidth;
        const canvasContainerHeight = +canvasContainer.clientHeight;
        const styleValues = this._defaultView.getComputedStyle(canvas);
        const marginTop = parseInt(styleValues.getPropertyValue('margin-top'));
        const marginLeft = parseInt(styleValues.getPropertyValue('margin-left'));
 
        const left = canvasWidth < canvasContainerWidth
            ? `${(canvasContainerWidth - canvasWidth) / 2 - marginLeft}px`
            : 'unset';
        const top = canvasHeight < canvasContainerHeight
            ? `${(canvasContainerHeight - canvasHeight) / 2 - marginTop}px`
            : 'unset';
 
        this._rendered.setStyle(canvas, 'left', left);
        this._rendered.setStyle(canvas, 'top', top);
    }
Добавлено через 4 минуты
перед _generateCanvas я вызываю _generateColorPoint
Можно вынести _generateCanvas в вебвокер, так как там строится объект {} и по калбеку вызкать _generateColorPoint уже в компоненте. Но вот даст-ли это результат... Ведь я не решу проблему с _generateColorPoint
0
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
23.01.2021, 22:27  [ТС]
Вызов из воркера не помог. Даже - дольше стало.

Миниатюры
Оптимизация работы с canvas. Производительность  
0
 Аватар для web_coder2
755 / 359 / 100
Регистрация: 04.10.2018
Сообщений: 548
24.01.2021, 04:05
Привет EveKS,
я не вникал в код нет времени, извините может завтра вечером появится, но это не точно, у меня сейчас перекур=)
Но быстрый взгляд на интернеты говорит что нужно смотреть в сторону requestAnimationFrame вместо setTimeout? очень извиняюсь что пальцем в небо не попал

Use requestAnimationFrame instead of setInterval / setTimeout
Оптимизация работы элемента canvas в HTML5

и т.д.

Еще раз извините что не в тему если что, просто google "canvas performance improvements"
2
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
24.01.2021, 09:49  [ТС]
web_coder2, спасибо большое
Я сделал коекакие оптимизации и исследования
Скажу что обнаружил:
point.num.toString(), медленее чем String(point.num);

Вынес в off конвас ниженаписанный код, т.к. эта часть статична
JavaScript
1
2
3
4
5
            this._context.fillStyle = '#fff';
            this._context.fillRect(x, y, size, size);
            this._context.fillStyle = '#666';
 
            this._context.strokeRect(x + 2, y + 2, smallSize, smallSize);
Ну и банальные математические вычисления, которые можно делать не в цикле, вынес из него (это почти не дало прироста).
Но самой моей большой проблемой является вызов fillText. fillText отнимает у меня 100-150 мс. Т.к. вызываю я его около 9000+ раз. Есть мысль, формировать массив, назовем это лейзи формированием. Т.е. заранее я знаю что я буду отображать. Еще до запроса к серверу, и формировании canvas на основе ответа. В момент запроса, а это 200 мс+, я могу так же вызвать формирование нескольких тысяч канвас, и сохранить в объект (ключ, значение). И затем уже строить, используя drawImage. Почитал, drawImage - быстрее чем fillText. Если какие-то данных нет, и сервер вернул что-то, что я ранее не ожидал, то просто заполнить именно эти участки используя fillText. Возможно это даст мне 50 мс, и ни в чем другом я не проиграю.

Добавлено через 2 минуты
Еще думал в сторону OffscreenCanvas, но там с поддержкой могут быть проблемы.
2
 Аватар для EveKS
601 / 485 / 185
Регистрация: 19.04.2016
Сообщений: 1,885
24.01.2021, 18:08  [ТС]
Вышеописанный алгоритм ускорил рендеринг, теперь вместо 200+ (а не редко около 300) миллисекунд, рендеринг происходит за 40-50. И есть еще идеи что поправить =))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.01.2021, 18:08
Помогаю со студенческими работами здесь

Оптимизация Canvas
Доброго времени суток! Как мне оптимизировать код на c++ Bitmap-&gt;Canvas-&gt;Pen-&gt;Width = 7; ...

Производительность труда при выполнении некоторой работы повысилась на 40% на сколько % сократилось время необходимое для выполнения этой работы
Помогите решить: 1) Производительность труда при выполнении некоторой работы повысилась на 40% на сколько % сократилось время...

Производительность работы 1C:ERP
Форумчане, подскажите, пожалуйста! Как определить &quot;эталонную&quot; т.е. максимально возможную производительность работы 1C:ERP, если будут...

Как увеличить производительность работы?
Чтобы делать дела больше и быстрее?

Vista и производительность работы в малом бизнесе
Повышение производительности и надежности работы компьютеров Средства диагностики и мониторинга Windows System Performance Rating...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru