Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

170
Vistas
Use GPU para dibujar en HTML5 Canvas en Google Chrome

Estoy usando un lienzo para dibujar un marcador (en SVG) cientos (a veces miles) de veces. El tamaño del lienzo es de 300x300 píxeles y el SVG es de 18x25 píxeles.

El código es bastante sencillo, tengo un ciclo for donde dibujo los marcadores en el lienzo:

 drawNewTile = (canvas, points) => { const drawn = {}; const context = canvas.getContext('2d'); if (points.length === 0) return; for (let i = points.length; i -= 1;) { const [x, y] = points[i]; if (!drawn[`${x}:${y}`]) { drawn[`${x}:${y}`] = true; this.drawMarker(context, x, y); } } }; drawMarker = (context, x, y) => { const x_ = Math.floor(x - this.MARKER_WIDTH / 2 + this.MAX_DIMENSION_OF_MARKER); const y_ = Math.floor(y - this.MARKER_HEIGHT + this.MAX_DIMENSION_OF_MARKER); context.drawImage(this.marker, x_, y_, this.MARKER_WIDTH, this.MARKER_HEIGHT); };

Ya he implementado algunas optimizaciones: como el ciclo for, solo dibuja aquellos puntos que aún no están dibujados, usa coordenadas enteras, etc.

Después de eso, tengo algunos buenos resultados, pero mi página se atasca un poco en Google Chrome. Sin embargo, para mi sorpresa, en Firefox va muy rápido, muy, muy rápido. Así que investigué un poco con la pestaña de rendimiento de Google Chrome y descubrí que mi código estaba usando una gran cantidad de CPU y eso es lento.

También encontré este artículo donde dice que Chrome usa algunas heurísticas para determinar si usa una CPU o una GPU para dibujar el lienzo.

Entonces, mi pregunta es, ¿cómo fuerzo el uso de GPU en Chrome? ¿Hay alguna bandera que pueda configurar o algo similar? ¿Tienes alguna otra forma de acelerar el proceso de dibujo?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

El problema es que aparentemente Chrome mantiene las imágenes SVG en la CPU y las rasteriza en cada nueva llamada a drawImage() .

Simplemente rasterizarlo usted mismo hará que el rendimiento de Chrome crezca instantáneamente.

Para hacer eso, use el método createImageBitmap() , que creará un ImageBitmap que el navegador podrá almacenar directamente en la memoria de la GPU.
Safari acaba de exponer este método en la versión más reciente de su navegador, por lo que es posible que aún desee utilizar un polyfill para ello. Si bien en este caso, simplemente dibujar en un lienzo sería suficiente, hice un polyfill que incluye algunas características que la mayoría de los navegadores aún no admiten.

 (async () => { const canvas = document.querySelector("canvas"); const ctx = canvas.getContext("2d"); const select = document.querySelector("select"); const html_img = new Image(); const svg_str = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 25" width="18" height="25"> <circle cx="9" cy="9" r="6"/> </svg>`; const svg_blob = new Blob([svg_str], { type: "image/svg+xml" }); ctx.font = "20px sans-serif"; ctx.fillStyle = "red"; html_img.src = URL.createObjectURL(svg_blob); const sources = { html_img, bitmap: await createImageBitmap(svg_blob) }; const times = []; await html_img.decode(); anim(); function anim() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (let y = 0; y < canvas.width; y += 10) { for (let x = 0; x < canvas.width; x += 5) { ctx.drawImage(sources[select.value], x, y); } } requestAnimationFrame(anim); // ultra rough FPS counter const now = performance.now(); while (times.length > 0 && times[0] <= now - 1000) { times.shift(); } times.push(now); fps = times.length; ctx.fillText(fps + "FPS", 30, 30); } })();
 <!-- createImageBitmap polyfill for old browsers --> <script src="https://cdn.jsdelivr.net/gh/Kaiido/createImageBitmap/dist/createImageBitmap.js"></script> source: <select> <option value="bitmap">ImageBitmap</option> <option value="html_img">HTMLImage</option> </select><br> <canvas width="300" height="300"></canvas>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda