Очень медленно рендеринг Javascript на холст HTML

Я пытаюсь отобразить сетку на холсте 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?

Kino Bacaltos 30.07.2018 08:19

Нет, это была моя попытка удалить p5.js из моего проекта.

Oliver Braun 30.07.2018 22:02
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
296
2

Ответы 2

Прокомментировал вызов функции 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. Во всяком случае, связанный дублированный вопрос ответил на мой вопрос.

Oliver Braun 30.07.2018 22:03

Что-то вроде этого.

Краткое пояснение. 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>

Это не помогает, потому что со временем я хочу получить анимацию. Однако связанный дублированный вопрос ответил на все мои вопросы.

Oliver Braun 30.07.2018 22:02

Другие вопросы по теме