W przypadku mojego projektu (zobacz projekt BigPictu.re lub bigpicture.js na GitHubie ) mam do czynienia z potencjalnie bardzo, bardzo, bardzo dużym <div>
kontenerem.
Wiedziałem, że istnieje ryzyko słabej wydajności przy prostym podejściu, którego używam, ale nie spodziewałem się, że będzie to głównie obecne w ... Tylko Chrome!
Jeśli przetestujesz tę małą stronę (zobacz kod poniżej), panoramowanie (kliknij + przeciągnij) będzie wyglądać następująco:
- Normalny / gładki w przeglądarce Firefox
- Normalny / płynny nawet w przeglądarce Internet Explorer
- Bardzo wolno (prawie się zawiesza) w Chrome!
Oczywiście mógłbym dodać kod (w moim projekcie), aby to zrobić, gdy jesteś bardzo powiększony, tekst z potencjalnie bardzo dużą czcionką byłby ukryty. Ale nadal, dlaczego Firefox i Internet Explorer obsługują to poprawnie, a nie Chrome?
Czy istnieje sposób w JavaScript, HTML lub CSS, aby poinformować przeglądarkę, aby nie próbowała renderować całej strony (która ma tutaj szerokość 10000 pikseli) dla każdego działania? (renderuj tylko bieżącą rzutnię!)
<!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>
źródło
Odpowiedzi:
Zmiana na
position: fixed
wydaje się przyspieszać.źródło
fixed
jest oczywiście mniej skomplikowany do rozplanowania i być może mogą przeprowadzić więcej optymalizacji. Ale nie spojrzałem na kod źródłowy silnika renderującego, jeśli tak masz na myśli ;-)Użyj
transform
zamiasttop/left
:Demo na żywo w jsFiddle .
źródło
fixed
usuwa element z przepływu tekstu i oszczędza wiele ponownego renderowania. W dokumentacjitransform
MDN jest napisane: "... zostanie utworzony kontekst stosu. W takim przypadku obiekt będzie działał jako blok zawierający pozycję: ustalone elementy, które zawiera."<div style="position:relative;min-height: 900px;">Your's divs</div>
jsFiddle so doesposition:relative
prawdopodobnie z odpowiedzi, która jest podobna do odpowiedziAle połączenie odpowiedzi Teemu i geert3 - używając transform i position: fixed, sprawia, że chrome działa znacznie szybciej nawet z dużymi czcionkami.
Maksymalne rozmiary czcionek: http://jsfiddle.net/74w7yL0a/
źródło
font-size
i może to być powodem braku spowolnienia na FF. Ale wtedy powinno być też bardzo wolno w IE, ale to nie jest ... Dziwne!Oprócz odpowiedzi Teemu dotyczącej korzystania z translacji:
Które powinieneś również użyć prefiksów innych dostawców, możesz to po prostu naprawić, używając tego w treści:
a to w html:
spowoduje to jednak wyłączenie przewijania. Więc to, co zrobiłbym, to dodać
mousedown
zdarzenie do treści i zastosować te style za pomocą klasy css, gdymousedown
zostanie wyzwolona, i usunąć tę klasęmouseup
.źródło
style.transform
albo z użyciemtransform
?). Dzięki za odpowiedź @Prisoner!Odpowiedź @Teemusa prawie wszystko.
Użyj
transform
ztranslate3d
zamiasttop/left
.translate3d
włącza akcelerację sprzętową.Demo na żywo w jsFiddle .
źródło
Przeanalizowałem to i odkryłem, że pierwotny problem dotyczył architektury wyświetlania Chrome i wykorzystania wątków w tle do renderowania strony.
Jeśli chcesz mieć szybkie renderowanie, wejdź do chrome: flags, przewiń do ustawienia Malowanie po stronie implantu i ustaw „Wyłączone”, a następnie zrestartuj przeglądarkę - ruch myszy będzie płynny.
Odkryłem, że jeśli włączysz licznik FPS, raportowany FPS w tym scenariuszu jest nadal bardzo wysoki, mimo że rzeczywista wydajność na ekranie jest bardzo niska. Moje wstępne wyjaśnienie (nie będąc ekspertem od architektury wyświetlaczy Chrome) jest takie, że jeśli wątek interfejsu użytkownika i ekran są w osobnych wątkach, może wystąpić rywalizacja w renderowaniu elementu div - w przypadku, gdy wątek interfejsu użytkownika i wątek renderowania znajdują się w W tym samym wątku wątek interfejsu użytkownika nie może wysyłać wiadomości szybciej niż może renderować wątek interfejsu użytkownika.
Sugerowałbym, że powinno to zostać zgłoszone jako błąd Chrome.
źródło
Użyj
display: table
itable-layout:fixed
na div lub tabeli zawijającej div. W HTML:i CSS:
Bibliografia
źródło