Para um projeto meu (ver BigPictu.re ou bigpicture.js projeto GitHub ), eu tenho que lidar com potencialmente um, muito, muito grande muito <div>
recipiente.
Eu sabia que havia um risco de desempenho ruim com a abordagem simples que uso, mas não esperava que estivesse presente principalmente com ... apenas o Chrome!
Se você testar esta pequena página (veja o código abaixo), a panorâmica (clique e arraste) será:
- Normal / suave no Firefox
- Normal / suave mesmo no Internet Explorer
- Muito lento (quase travando) no Chrome!
Claro, eu poderia adicionar algum código (em meu projeto) para fazer isso quando você aumentar muito o zoom, o texto com tamanho de fonte potencialmente muito grande ficará oculto. Mas ainda assim, por que o Firefox e o Internet Explorer lidam com isso corretamente e não com o Chrome?
Existe uma maneira em JavaScript, HTML ou CSS de dizer ao navegador para não tentar renderizar a página inteira (que tem 10000 pixels de largura aqui) para cada ação? (renderizar apenas a janela de visualização atual!)
<!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>
fonte
Respostas:
Mudar para
position: fixed
parece acelerar as coisas.fonte
fixed
é obviamente menos complexo de definir e talvez eles possam fazer mais otimizações. Mas eu não olhei para o código-fonte do mecanismo de renderização, se você quer dizer isso ;-)Use em
transform
vez detop/left
:Uma demonstração ao vivo em jsFiddle .
fonte
fixed
tira o elemento do fluxo de texto e economiza muita re-renderização. Na documentação dotransform
MDN diz: "... um contexto de empilhamento será criado. Nesse caso o objeto atuará como um bloco de contenção para a posição: elementos fixos que ele contém."<div style="position:relative;min-height: 900px;">Your's divs</div>
jsFiddle tambémposition:relative
probabilidade, que é semelhante à resposta deMas combinar as respostas Teemu e geert3 - usando transform e position: fixed, faz com que o Chrome funcione muito mais rápido, mesmo com fontes grandes.
Tamanhos máximos de fonte: http://jsfiddle.net/74w7yL0a/
fonte
font-size
e esta pode ser a razão para a não lentidão no FF. Mas deveria ter sido muito lento no IE também, mas não é ... Estranho!Além da resposta de Teemu sobre o uso de traduzir:
Que você também deve usar prefixos de outros fornecedores. Você pode simplesmente corrigir isso usando no corpo:
e isso em html:
isso, no entanto, desabilitará a rolagem. Então, o que eu faria é adicionar um
mousedown
evento ao corpo e aplicar esses estilos usando uma classe css sempre quemousedown
for acionada e removendo essa classemouseup
.fonte
style.transform
ou com usartransform
?). A propósito, obrigado pela sua resposta @Prisoner!A resposta de @Teemus quase faz tudo.
Use
transform
com emtranslate3d
vez detop/left
.translate3d
permite a aceleração de hardware.Uma demonstração ao vivo em jsFiddle .
fonte
Eu analisei isso e descobri que o problema original estava relacionado à arquitetura de exibição do Chrome e seu uso de threads de fundo para renderizar a página.
Se você quiser ter uma renderização rápida, vá para chrome: flags, vá até a configuração Impl-side painting, defina "Disabled" e reinicie o navegador - o mousemove será suave.
O que descobri é que se você ativar o contador de FPS, o FPS relatado neste cenário ainda é muito alto, embora o desempenho real na tela seja muito baixo. Minha explicação provisória (não sendo um especialista em arquitetura de exibição do Chrome) é que, se o thread da IU e a exibição estiverem em threads separados, pode haver contenção na renderização do div - no caso em que o thread da IU e o thread de renderização estão no mesmo thread, o UI thread não pode enviar mensagens mais rápido do que o UI thread pode processar.
Eu sugeriria que isso fosse arquivado como um bug do Chrome.
fonte
Use
display: table
etable-layout:fixed
na div, ou uma mesa envolvendo a div. Em HTML:e CSS:
Referências
fonte