Как оптимизировать код js?

Ссылка скопирована
1 ответ

Есть функция анимации на js. Внутри интервал вызывающий функцию пикселизации изображения. Она занимает много времени и стопорит остальной код для прокрутки страницы. Как правильно переписать код?

function animatePixel(pixelatedImage, index) { 		let start = Date.now(); 		let timer = setInterval(() => { 			let timePassed = Date.now() - start;  			if (timePassed >= 1500) { 				clearInterval(timer); 				resolve(1) 			}  			isVisible[index] = false; 			pixelateImage(originalImage[index], Math.floor((1500 - timePassed) / 100), pixelatedImage); 		}, 100)  	}   function pixelateImage(originalImage, pixelationFactor, pixelatedImage) { 		const canvas = document.createElement("canvas"); 		const context = canvas.getContext("2d"); 		const originalWidth = originalImage.width; 		const originalHeight = originalImage.height; 		const canvasWidth = originalWidth; 		const canvasHeight = originalHeight; 		canvas.width = canvasWidth; 		canvas.height = canvasHeight; 		context.drawImage(originalImage, 0, 0, originalWidth, originalHeight); 		const originalImageData = context.getImageData( 			0, 			0, 			originalWidth, 			originalHeight 		).data; 		if (pixelationFactor !== 0) { 			for (let y = 0; y < originalHeight; y += pixelationFactor) { 				for (let x = 0; x < originalWidth; x += pixelationFactor) { 					// extracting the position of the sample pixel 					const pixelIndexPosition = (x + y * originalWidth) * 4; 					// drawing a square replacing the current pixels 					context.fillStyle = `rgba( 						${originalImageData[pixelIndexPosition]}, 						${originalImageData[pixelIndexPosition + 1]}, 						${originalImageData[pixelIndexPosition + 2]}, 						${originalImageData[pixelIndexPosition + 3]} 					)`; 					context.fillRect(x, y, pixelationFactor, pixelationFactor); 				} 			} 		} 		pixelatedImage.src = canvas.toDataURL(); 	}

function animatePixel(pixelatedImage, index) { let start = Date.now(); let timer = setInterval(() => { let timePassed = Date.now() - start; if (timePassed >= 1500) { clearInterval(timer); resolve(1) } isVisible[index] = false; pixelateImage(originalImage[index], Math.floor((1500 - timePassed) / 100), pixelatedImage); }, 100) } function pixelateImage(originalImage, pixelationFactor, pixelatedImage) { const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); const originalWidth = originalImage.width; const originalHeight = originalImage.height; const canvasWidth = originalWidth; const canvasHeight = originalHeight; canvas.width = canvasWidth; canvas.height = canvasHeight; context.drawImage(originalImage, 0, 0, originalWidth, originalHeight); const originalImageData = context.getImageData( 0, 0, originalWidth, originalHeight ).data; if (pixelationFactor !== 0) { for (let y = 0; y < originalHeight; y += pixelationFactor) { for (let x = 0; x < originalWidth; x += pixelationFactor) { // extracting the position of the sample pixel const pixelIndexPosition = (x + y * originalWidth) * 4; // drawing a square replacing the current pixels context.fillStyle = `rgba( ${originalImageData[pixelIndexPosition]}, ${originalImageData[pixelIndexPosition + 1]}, ${originalImageData[pixelIndexPosition + 2]}, ${originalImageData[pixelIndexPosition + 3]} )`; context.fillRect(x, y, pixelationFactor, pixelationFactor); } } } pixelatedImage.src = canvas.toDataURL(); }

Дополнительно:

в отдельный поток вынеси через воркер или раздроби originalHeight на части, и через промисы дорисовывай холст

  • szQocks, что за воркер
  • alOstrovsqkii,

    https://www.youtube.com/watch?v=1c4UAd7SNkk

    https://developer.mozilla.org/ru/docs/Web/API/Web_...

  • Ответы:

    У тебя дохрена всего лишнего. Как минимум, pixelatedImage.src = canvas.toDataURL(); в каждой итерации - это прямо вишенка на торте.

    показывай анимацию на канве, а не в элементе img

    Однократно:
    1) создать канву нужных размеров, кинуть на неё картинку
    2) забрать originalImageData = context.getImageData(...)
    3) создать новый targerImageData = context.createImageData(width, height)

    На каждой итерации (на каждом срабатывании таймера):
    1) Обойдя пиксели originalImageData, заполнить соответствующие квадраты в targerImageData
    2) Вызвать context.putImageData(targerImageData, 0, 0)

    Если у тебя большая картинка и это всё равно будет подтормажвиать, то стоит попробовать вынести работу с originalImageData и targerImageData в отдельный поток. При этом targerImageData нужно правильно перекидывать между потоками.

    Как вариант, можно попробовать раскурить webgl, тут подсказать не могу, не пробовал.

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Ольга Сеть Ответ

    Для оптимизации кода JavaScript можно использовать несколько методов, которые помогут улучшить производительность и эффективность вашего кода. Вот несколько советов:

    1. Уменьшение количества запросов к серверу: объединение и минимизация файлов JavaScript поможет уменьшить время загрузки страницы. Можно использовать сборщики (например, Webpack) для объединения и минимизации файлов.

    2. Использование кэширования: кэширование позволяет сохранять ресурсы на стороне клиента и уменьшить время загрузки страницы. Можно использовать HTTP-заголовки для управления кэшированием.

    3. Оптимизация циклов: избегайте вложенных циклов и используйте более эффективные методы обхода массивов, такие как методы map(), filter() и reduce().

    4. Избегайте лишних запросов к DOM: минимизируйте обращения к DOM, так как это является одним из самых медленных операций в JavaScript. Лучше сохранять ссылки на элементы DOM в переменных и обращаться к ним через переменные.

    5. Используйте события делегирования: вместо назначения обработчиков событий каждому элементу отдельно, используйте делегирование событий для уменьшения количества обработчиков событий.

    Пример оптимизированного кода на JavaScript:

    // Уменьшение количества запросов к серверу
    import { getData } from './api';
     
    const fetchData = async () => {
      const data = await getData();
      // Дальнейшие действия с полученными данными
    };
     
    // Оптимизация циклов
    const numbers = [1, 2, 3, 4, 5];
    const sum = numbers.reduce((acc, curr) => acc + curr, 0);
     
    // Избегание лишних запросов к DOM
    const button = document.getElementById('myButton');
    button.addEventListener('click', () => {
      // Действия по клику на кнопку
    });
     
    // Использование событий делегирования
    const parent = document.getElementById('parentElement');
    parent.addEventListener('click', (event) => {
      if (event.target.classList.contains('childElement')) {
        // Действия по клику на дочерний элемент
      }
    });

    // Уменьшение количества запросов к серверу import { getData } from './api'; const fetchData = async () => { const data = await getData(); // Дальнейшие действия с полученными данными }; // Оптимизация циклов const numbers = [1, 2, 3, 4, 5]; const sum = numbers.reduce((acc, curr) => acc + curr, 0); // Избегание лишних запросов к DOM const button = document.getElementById('myButton'); button.addEventListener('click', () => { // Действия по клику на кнопку }); // Использование событий делегирования const parent = document.getElementById('parentElement'); parent.addEventListener('click', (event) => { if (event.target.classList.contains('childElement')) { // Действия по клику на дочерний элемент } });

    Следуя этим советам, вы сможете значительно улучшить производительность вашего кода JavaScript.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно