Para un proyecto mío (ver BigPictu.re o proyecto GitHub bigpicture.js ), tengo que lidiar con un <div>
contenedor potencialmente muy, muy, muy grande .
Sabía que existía el riesgo de un rendimiento deficiente con el enfoque simple que uso, pero no esperaba que estuviera presente principalmente con ... ¡Solo Chrome!
Si prueba esta pequeña página (consulte el código a continuación), la panorámica (haga clic + arrastre) será:
- Normal / suave en Firefox
- Normal / suave incluso en Internet Explorer
- ¡Muy lento (casi fallando) en Chrome!
Por supuesto, podría agregar algún código (en mi proyecto) para hacer eso cuando se acerca mucho, el texto con un tamaño de fuente potencialmente muy grande estaría oculto. Pero aún así, ¿por qué Firefox e Internet Explorer lo manejan correctamente y no Chrome?
¿Hay alguna forma en JavaScript, HTML o CSS de decirle al navegador que no intente representar la página completa (que tiene 10000 píxeles de ancho aquí) para cada acción? (¡renderiza solo la ventana gráfica actual!)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
html, body {
overflow: hidden;
min-height: 100%; }
#container {
position: absolute;
min-height: 100%;
min-width: 100%; }
.text {
font-family: "Arial";
position: absolute;
}
</style>
</head>
<body>
<div id="container">
<div class="text" style="font-size: 600px; left:100px; top:100px">Small text</div>
<div class="text" style="font-size: 600000px; left:10000px; top:10000px">Very big text</div>
</div>
<script>
var container = document.getElementById('container'), dragging = false, previousmouse;
container.x = 0; container.y = 0;
window.onmousedown = function(e) { dragging = true; previousmouse = {x: e.pageX, y: e.pageY}; }
window.onmouseup = function() { dragging = false; }
window.ondragstart = function(e) { e.preventDefault(); }
window.onmousemove = function(e) {
if (dragging) {
container.x += e.pageX - previousmouse.x; container.y += e.pageY - previousmouse.y;
container.style.left = container.x + 'px'; container.style.top = container.y + 'px';
previousmouse = {x: e.pageX, y: e.pageY};
}
}
</script>
</body>
</html>
fuente
Respuestas:
Cambiar a
position: fixed
parece acelerar las cosas.fuente
fixed
es obviamente menos complejo de diseñar y quizás puedan hacer más optimizaciones. Pero no he mirado el código fuente del motor de renderizado si te refieres a eso ;-)Usar en
transform
lugar detop/left
:Una demostración en vivo en jsFiddle .
fuente
fixed
saca el elemento del flujo de texto y ahorra una gran cantidad de re-renderizado. En la documentación detransform
MDN dice: "... se creará un contexto de apilamiento. En ese caso el objeto actuará como un bloque contenedor para la posición: elementos fijos que contiene".<div style="position:relative;min-height: 900px;">Your's divs</div>
jsFiddle también lo haceposition:relative
probable, que es similar a la respuesta dePero la combinación de las respuestas de Teemu y geert3, usando transform y position: fixed, hace que Chrome funcione mucho más rápido incluso con fuentes grandes.
Tamaños máximos de fuente: http://jsfiddle.net/74w7yL0a/
fuente
font-size
y este podría ser el motivo de la no lentitud en FF. Pero también debería haber sido muy lento en IE, pero no es ... ¡Extraño!Además de la respuesta de Teemu de usar translate:
Que también debe usar otros prefijos de proveedores, simplemente puede arreglar esto usando esto en el cuerpo:
y esto en html:
esto, sin embargo, desactivará el desplazamiento. Entonces, lo que haría es agregar un
mousedown
evento al cuerpo y aplicar esos estilos usando una clase css siempre quemousedown
se active, y eliminar esa clase enmouseup
.fuente
style.transform
o con usartransform
?). ¡Gracias por cierto por tu respuesta @Prisoner!La respuesta de @Teemus casi lo hace todo.
Usar
transform
con entranslate3d
lugar detop/left
.translate3d
habilita la aceleración de hardware.Una demostración en vivo en jsFiddle .
fuente
Analicé esto y descubrí que el problema original estaba relacionado con la arquitectura de visualización de Chrome y su uso de subprocesos en segundo plano para representar la página.
Si desea obtener un renderizado rápido, vaya a chrome: flags, desplácese hasta la configuración Impl-side painting y configure "Disabled", luego reinicie el navegador; el movimiento del mouse será suave.
Lo que encontré es que si habilita el contador de FPS, el FPS informado en este escenario sigue siendo muy alto, aunque el rendimiento real en pantalla es muy bajo. Mi explicación tentativa (no siendo un experto en arquitectura de pantalla de Chrome) es que si el hilo de la interfaz de usuario y la pantalla están en hilos separados, entonces puede haber contención en la representación del div, en el caso de que el hilo de la interfaz de usuario y el hilo de representación estén en el mismo hilo, el hilo de la interfaz de usuario no puede enviar mensajes más rápido de lo que puede procesar el hilo de la interfaz de usuario.
Sugeriría que esto se registre como un error de Chrome.
fuente
Use
display: table
ytable-layout:fixed
en el div, o una tabla que envuelva el div. En HTML:y CSS:
Referencias
fuente