Я пытаюсь отобразить сетку на холсте HTML путем визуализации отдельных квадратов (потому что позже все ячейки не должны выглядеть одинаково, а иметь индивидуальное поведение).
Я создал минимальный пример, который показывает мои проблемы с производительностью. Запуск этого сценария почти замораживает мой браузер, пока он не предложит мне остановить его, потому что он обнаруживает, что этот сценарий выполняется слишком медленно.
У меня есть аналогичный пример с Javascript-фреймворком p5.js, и он отлично работает с точки зрения производительности. Однако я хочу перейти на базовый Javascript без этой структуры.
Вот минимальный пример, вызывающий проблемы с производительностью. Я был бы рад любым предложениям, почему это может работать так медленно ...
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
let grid_width = 50;
let grid_height = grid_width;
let grid = [];
class Cell {
constructor(i,j) {
this.i = i;
this.j = j;
this.width = width / grid_width;
this.height = height / grid_height;
this.x = i*this.width;
this.y = j*this.height;
}
render(color) {
context.rect(this.x, this.y, this.width, this.height);
context.strokeStyle = '#000000';
context.lineWidth = .25;
if (color) {
context.fillStyle = color;
}
context.fillStyle = '#FFFFFF';
context.fill();
context.stroke();
}
}
for(let i = 0; i <= grid_width; i++) {
if (!(grid[i])) {
grid[i] = [];
}
for(let j = 0; j <= grid_height; j++) {
grid[i][j] = new Cell(i, j);
}
}
function draw() {
context.clearRect(0, 0, width, height);
grid.forEach(row => {
row.forEach(cell => {
cell.render();
});
});
requestAnimationFrame(draw);
}
// This call to draw will run very slowly!
// draw();<!DOCTYPE html>
<html>
<head>
<!-- <script src = "p5.js"></script> -->
</head>
<body>
<canvas id = "canvas" width = "800" height = "800"></canvas><br>
<script src = "sketch.js"></script>
</body>
</html>Обратите внимание, что я закомментировал вызов draw (), потому что мой скрипт также нарушает работу кнопки «Выполнить фрагмент кода» на этом сайте ...
Нет, это была моя попытка удалить p5.js из моего проекта.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Прокомментировал вызов функции requestAnimationFrame(row). Потому что нет такой функции. Теперь код у меня работает плавно.
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
let grid_width = 50;
let grid_height = grid_width;
let grid = [];
class Cell {
constructor(i,j) {
this.i = i;
this.j = j;
this.width = width / grid_width;
this.height = height / grid_height;
this.x = i*this.width;
this.y = j*this.height;
}
render(color) {
context.rect(this.x, this.y, this.width, this.height);
context.strokeStyle = '#000000';
context.lineWidth = .25;
if (color) {
context.fillStyle = color;
}
context.fillStyle = '#FFFFFF';
context.fill();
context.stroke();
}
}
for(let i = 0; i <= grid_width; i++) {
if (!(grid[i])) {
grid[i] = [];
}
for(let j = 0; j <= grid_height; j++) {
grid[i][j] = new Cell(i, j);
}
}
function draw() {
context.clearRect(0, 0, width, height);
grid.forEach(row => {
row.forEach(cell => {
cell.render();
});
});
//requestAnimationFrame(draw);
}
// This call to draw will run very slowly!
draw();<!DOCTYPE html>
<html>
<head>
<!-- <script src = "p5.js"></script> -->
</head>
<body>
<canvas id = "canvas" width = "800" height = "800"></canvas><br>
<script src = "sketch.js"></script>
</body>
</html>Я не понимаю, requestAnimationFrame () - это стандартная функция Javascript. Во всяком случае, связанный дублированный вопрос ответил на мой вопрос.
Что-то вроде этого.
Краткое пояснение. rect - это холст path command. Таким образом, fill и stroke перерисовывают все пути между beginPath() и endPath с последними версиями fillStyle и strokeStyle. В этом случае ваш цикл сначала рисует только первый прямоугольник, затем рисует первый и второй и так далее.
И да, ваш цвет, после того как вы исправите оператор if внутри метода, всегда будет применяться ко всем ячейкам.
Поэтому я намерен использовать здесь немного другой код. Первый. Я заменяю rect на strokeRect и fillRect, которые применяются немедленно. Второй. Я снимаю ваше состояние if.
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
let grid_width = 50;
let grid_height = grid_width;
let grid = [];
class Cell {
constructor(i,j) {
this.i = i;
this.j = j;
this.width = width / grid_width;
this.height = height / grid_height;
this.x = i*this.width;
this.y = j*this.height;
}
render(color) {
context.strokeStyle = '#000000';
context.lineWidth = .25;
context.fillStyle = color || '#FFFFFF';
context.strokeRect(this.x, this.y, this.width, this.height);
context.fillRect(this.x, this.y, this.width, this.height);
}
}
for(let i = 0; i <= grid_width; i++) {
if (!(grid[i])) {
grid[i] = [];
}
for(let j = 0; j <= grid_height; j++) {
grid[i][j] = new Cell(i, j);
}
}
function draw() {
context.clearRect(0, 0, width, height);
grid.forEach(row => {
row.forEach(cell => {
cell.render(Math.random()>0.5?"#FF00FF":undefined);
});
});
//requestAnimationFrame(draw);
}
// This call to draw will run very slowly!
draw();<!DOCTYPE html>
<html>
<head>
<!-- <script src = "p5.js"></script> -->
</head>
<body>
<canvas id = "canvas" width = "800" height = "800"></canvas><br>
<script src = "sketch.js"></script>
</body>
</html>Это не помогает, потому что со временем я хочу получить анимацию. Однако связанный дублированный вопрос ответил на все мои вопросы.
вы используете p5.js?