Çok, çok, çok büyük bir div


109

Benim bir projem için ( BigPictu.re veya bigpicture.js GitHub projesine bakın ), potansiyel olarak çok, çok, çok büyük bir <div>konteynerle uğraşmam gerekiyor .

Kullandığım basit yaklaşımın düşük performans riski olduğunu biliyordum, ancak bunun çoğunlukla mevcut olmasını beklemiyordum ... Yalnızca Chrome!

Bu küçük sayfayı test ederseniz (aşağıdaki koda bakın), kaydırma (tıklayın + sürükle):

  • Firefox'ta normal / pürüzsüz
  • Internet Explorer'da bile normal / pürüzsüz
  • Chrome'da çok yavaş (neredeyse kilitleniyor)!

Tabii ki, çok yakınlaştırdığınızda bunu yapmak için (projemde) bazı kodlar ekleyebilirim, potansiyel olarak çok büyük yazı tipi boyutuna sahip metinler gizlenir. Ama yine de, Firefox ve Internet Explorer neden Chrome'u değil de doğru şekilde işliyor?

JavaScript, HTML veya CSS'de, tarayıcıya her işlem için tüm sayfayı (burada 10000 piksel genişliğindedir) oluşturmaya çalışmamasını söylemenin bir yolu var mı ? (sadece mevcut görüntü alanını oluştur!)


<!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>

54
[OT] 600K yazı tipi boyutu. Gözleri çok kötü olan insanlar için bir erişilebilirlik özelliği olmalı mı? ;-)
geert3

61
@ geert3 Ay yörüngesinde dönen bir web tarayıcısı için olduğundan eminim
David Wilkins

3
Demonuz Chrome 41.0.2236.0 dev-m'de sorunsuz
Pier-Luc

11
Kanaryadayım (41.0.2241.0 kanarya) ve hala gecikme yaşıyorum. Bunu bir oyun donanımı yerine bir dizüstü bilgisayarda denemelisiniz, göreceksiniz
markasoftware

3
Popüler inanışın aksine, IE çoğu sayfayı oluşturmak için aslında Chrome'dan daha hızlıdır. Javascript motoru biraz daha yavaştır.
Falanwe

Yanıtlar:


62

Olarak değiştirmek position: fixedişleri hızlandırıyor gibi görünüyor.


27
Sorusuna doğrudan bir yanıt değil, ancak ilk sorununa potansiyel bir çözüm (Chrome'da yavaş yanıt). Kutunun dışında düşünmek teşvik edilmelidir, IMHO.
geert3

Burada mükemmel çalışıyor gibi görünüyor: gget.it/e0ubdh67/big-div-test_fixed.html . Neden biliyor musun ? :)
Basj

2
Ben sadece tahmin edebilirim. fixedaçıkçası daha az karmaşıktır ve belki de daha fazla optimizasyon yapabilirler. Ama bunu kastediyorsanız, işleme motoru kaynak koduna
bakmadım

1
Bu cevap ve ViliusL tarafından sağlanan cevap, farklı kişilerin aynı "yorum bırak" yorumuna sahip. Ne kadar serin?
Joe

2
@Joe bunlar, moderatörler tarafından kullanılmak üzere StackOverflow tarafından sağlanan bir dizi standart yanıttan. Bazılarının daha ılımlı bir şekilde ılımlı olması gerekir.
geert3

42

transformBunun yerine kullanın top/left:

container.style.transform = 'translate(' + container.x + 'px, ' + container.y + 'px)';

JsFiddle'da canlı bir demo .


2
Bir çok garip şey: senin jsFiddle içinde, gerçekten de Chrome ile hızlı. Orijinal kodumda önerdiğiniz değişikliği tam olarak burada yaptım : gget.it/1owxq8kr/big-div-test_transform.html ve bu son bağlantı Chrome'da yavaştır :( Bu nasıl mümkün olabilir? JsFiddle'ınızla aynı görünüyor ! [Not: mucizevi bir şekilde, geert3'ün yanıtları işe yarıyor gibi görünüyor, nedenini bilmiyorum ama işe yarıyor: gget.it/e0ubdh67/big-div-test_fixed.html]
Basj

@Basj Belki sürüme bağlıdır, Chrome'um (39.0.2171.71 m) yorumunuzda bağlantılı sayfayı FF kadar pürüzsüz ve hızlı bir şekilde kaydırıyor. Her neyse, konumu ayarlamak fixed, öğeyi metin akışının dışına çıkarır ve çok sayıda yeniden oluşturma tasarrufu sağlar. transformMDN dokümantasyonunda şöyle der: "... bir yığın bağlamı oluşturulacak. Bu durumda nesne, konum için içeren bir blok görevi görecek: içerdiği sabit öğeler."
Teemu

2
Garip, Chrome 39.0.2171.71 m de var ... ve gget.it/1owxq8kr/big-div-test_transform.html tavalar yavaş, orijinal sürümüm kadar yavaş (sorunun kendisinde). Oohhh muhtemelen donanım hızlandırmaya bağlı: Muhtemelen donanım hızlandırmam yok, çünkü zayıf grafik yongasına sahip bir dizüstü bilgisayarım var ...
Basj

1
@Basj bir sarmalayıcı <div style="position:relative;min-height: 900px;">Your's divs</div>ekler
Alfonso Rubalcava

1
@AlfonsoRubalcava Oh tamam ... Bu jsfiddle'ın neden pürüzsüz olduğunu ve doğrudan bağlantının düzgün olmadığını açıklıyor (Chrome): gget.it/1owxq8kr/big-div-test_transform.html ! Teşekkürler! Dolayısıyla performanstaki iyileşme, position:relativemuhtemelen geert3'ün cevabına benzeyen
Basj

22
  1. İlk soru "neden" i yanıtlayın. Sorunlardan biri yazı tipi boyutudur . 600000px yazı tipi boyutuna sahipseniz, çoğu tarayıcı bunu çok yüksek olarak görecek ve daha küçük görüntüleyecektir, ancak Chrome orijinal boyutu oluşturmaya çalışacaktır. Görünüşe göre krom bu kadar büyük harfleri istediğiniz stillerle çok hızlı yeniden boyayamıyor.

Ancak Teemu ve geert3 yanıtlarını birleştirmek - dönüştürme ve konum: sabit kullanarak, kromun büyük yazı tiplerinde bile çok daha hızlı çalışmasını sağlar.

  1. 2. soruya cevap: "Sayfanın tamamını oluşturmaya çalışmamanın bir yolu var mı?" - tüm kapsayıcı için değil, kapsayıcıdaki öğeler için fare eylemi uygulamayı deneyebilirsiniz.

Maksimum yazı tipi boyutları: http://jsfiddle.net/74w7yL0a/

firefox 34 - 2 000 px
chrome 39 - 1 000 000 px
safari 8 - 1 000 000 px
ie 8-11 - 1 431 700 px

6
Aslında öyle. OP iki soru sorar, bunlardan ilki yanıtlanır: "Neden FF, IE bunu Chrome ile değil de doğru şekilde ele alıyor?"
Hans Roerdinkholder

İlginç. Aklınızda, Firefox'un 10k'da durduğunu ve Chrome'un orijinal boyutu oluşturmaya çalıştığını gösteren bazı öğeler var mı? (İleride başvurmak için ilginç olurdu). Şimdiden teşekkürler @ViliusL!
Basj

1
@Basj, her tarayıcı için maksimum yazı tipi boyutu ekledi (bugün test edildi) ve firefox için 2k.
ViliusL

Çok teşekkürler @ViliusL! Aslında, FF sınırlandırır font-sizeve bu , FF'de yavaşlamamanın nedeni olabilir. Ama o zaman IE'de de çok yavaş olmalıydı, ama bu değil ... Garip!
Basj

4

Teemu'nun çeviri kullanma cevabına ek olarak:

container.style.transform = 'translate(' + container.x + 'px, ' + container.y + 'px)';

Diğer satıcı öneklerini de kullanmanız gereken, bunu gövde üzerinde kullanarak basitçe düzeltebilirsiniz:

height: 100%;
width: 100%;
position: relative;
overflow: hidden;

ve bu html'de:

height: 100%;

ancak bu, kaydırmayı devre dışı bırakacaktır. Yapacağım şey, mousedowngövdeye bir olay eklemek ve bu stilleri her mousedowntetiklendiğinde bir css sınıfı kullanarak uygulamak ve bu sınıfı kaldırmaktır mouseup.


Burada bahsettiğiniz şeyi eklemeye çalıştım: gget.it/0ufheqmt/big-div-test_prisonersolution.html , demek istediğiniz bu mu? Burada Chrome ile sürükleme hala yavaş. Sizin için aynı? (Not: anlamadım: Bu CSS değişiklikleri yapmak önermek yerine kullanmak style.transformveya birlikte kullanılarak transform?). Cevabınız için teşekkürler @Prisoner!
Basj

2

@Teemus'un cevabı neredeyse hepsini yapıyor.

Yerine transform iletranslate3d kullanın top/left.

translate3d donanım hızlandırmayı etkinleştirir.

container.style.transform = 'translate3d(' + container.x + 'px, ' + container.y + 'px, 0)';

JsFiddle'da canlı bir demo .


1

Bunu analiz ettim ve orijinal sorunun Chrome görüntü mimarisi ve sayfayı işlemek için arka plan dizilerini kullanmasıyla ilgili olduğunu buldum.

Hızlı oluşturmaya sahip olmak istiyorsanız, chrome: flags'a gidin, Impl-side painting ayarına gidin ve "Disabled" ayarını yapın, ardından tarayıcıyı yeniden başlatın - mousemove sorunsuz olacaktır.

Bulduğum şey, FPS sayacını etkinleştirirseniz, gerçek ekran performansı çok düşük olmasına rağmen bu senaryoda bildirilen FPS'nin hala çok yüksek olduğudur. Geçici açıklamam (bir Chrome görüntü mimarisi uzmanı olmamak), UI iş parçacığı ve ekran ayrı iş parçacıkları üzerindeyse, div'in oluşturulmasında çekişme olabileceğidir - UI iş parçacığı ve oluşturma iş parçacığının üzerinde olduğu durumda aynı iş parçacığı, UI iş parçacığı iletileri UI iş parçacığının işleyebileceğinden daha hızlı gönderemez.

Bunun bir Chrome hatası olarak dosyalanmasını öneririm.


1

Kullanım display: tableve table-layout:fixeddiv üzerinde veya div kaydırma bir tablo. HTML'de:

HTML tablo modeli, yazarın yardımıyla, kullanıcı aracılarının, işlemeye başlamadan önce tüm verileri beklemek yerine tabloları artımlı olarak (yani tablo satırları geldikçe) oluşturabileceği şekilde tasarlanmıştır.

Bir kullanıcı aracısının bir tabloyu tek geçişte biçimlendirmesi için, yazarlar kullanıcı aracısına şunu söylemelidir:

Tablodaki sütun sayısı. Bu bilgilerin nasıl sağlanacağına ilişkin ayrıntılar için lütfen tablodaki sütun sayısını hesaplama bölümüne bakın. Bu sütunların genişlikleri. Bu bilgilerin nasıl sağlanacağına ilişkin ayrıntılar için lütfen sütunların genişliğini hesaplama bölümüne bakın.

Daha kesin olarak, bir kullanıcı aracısı, sütun genişlikleri COLGROUP ve COL öğelerinin bir kombinasyonu kullanılarak belirtildiğinde bir tabloyu tek geçişte oluşturabilir. Sütunlardan herhangi biri göreceli veya yüzde olarak belirtilmişse (sütunların genişliğini hesaplama bölümüne bakın), yazarlar ayrıca tablonun genişliğini de belirtmelidir.

Artımlı görüntüleme için tarayıcının sütun sayısına ve genişliklerine ihtiyacı vardır. Tablonun varsayılan genişliği, geçerli pencere boyutudur (genişlik = "% 100"). Bu, TABLE öğesinin genişlik özniteliği ayarlanarak değiştirilebilir. Varsayılan olarak tüm sütunlar aynı genişliğe sahiptir, ancak tablo verileri başlamadan önce bir veya daha fazla COL öğesiyle sütun genişliklerini belirtebilirsiniz.

Geriye kalan sorun sütun sayısıdır. Bazı insanlar tablonun ilk satırı alınana kadar beklemeyi önerdiler, ancak hücrelerde çok fazla içerik varsa bu uzun zaman alabilir. Genel olarak, artımlı gösterim istendiğinde, yazarların TABLE öğesindeki sütun sayısını açıkça belirtmesini sağlamak daha mantıklıdır.

Yazarlar, kullanıcı aracılarına artımlı görüntülemeyi mi yoksa tabloyu hücre içeriğine uyacak şekilde otomatik olarak boyutlandırmayı mı söylemenin bir yoluna ihtiyaç duymaktadır. İki geçişli otomatik boyutlandırma modunda, sütun sayısı ilk geçişle belirlenir. Artımlı modda, sütun sayısı önceden belirtilmelidir (COL veya COLGROUP öğeleriyle).

ve CSS:

17.5.2.1 Sabit masa düzeni

Bu (hızlı) algoritma ile tablonun yatay düzeni hücrelerin içeriğine bağlı değildir; yalnızca tablonun genişliğine, sütunların genişliğine ve kenarlıklara veya hücre aralığına bağlıdır.

Tablonun genişliği, 'genişlik' özelliğiyle açıkça belirtilebilir. 'Auto' değeri (hem 'display: table' hem de 'display: inline-table' için), otomatik tablo düzeni algoritmasının kullanılması anlamına gelir. Bununla birlikte, tablo normal akışta blok düzeyinde bir tablodaysa ('display: table'), bir UA, bir genişliği hesaplamak ve sabit tablo düzenini uygulamak için 10.3.3 algoritmasını kullanabilir (ancak zorunlu değildir). belirtilen genişlik "otomatik" tir.

Referanslar

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.