Một div rất rất rất lớn


109

Đối với một dự án của tôi (xem BigPictu.re hoặc bigpicture.js dự án GitHub ), tôi phải đối phó với khả năng rất, rất, rất lớn <div>chứa.

Tôi biết rằng có nguy cơ hoạt động kém hiệu quả với cách tiếp cận đơn giản mà tôi sử dụng, nhưng tôi không ngờ rằng nó hầu như chỉ xuất hiện với ... Chrome!

Nếu bạn kiểm tra trang nhỏ này (xem mã bên dưới), việc di chuyển (nhấp + kéo) sẽ là:

  • Bình thường / mượt mà trên Firefox
  • Bình thường / mượt mà ngay cả trên Internet Explorer
  • Rất chậm (gần như bị lỗi) trên Chrome!

Tất nhiên, tôi có thể thêm một số mã (trong dự án của tôi) để làm điều đó khi bạn phóng to nhiều, văn bản có kích thước phông chữ rất lớn có thể sẽ bị ẩn. Tuy nhiên, tại sao Firefox và Internet Explorer lại xử lý nó một cách chính xác mà không phải Chrome?

Có cách nào trong JavaScript, HTML hoặc CSS để yêu cầu trình duyệt không cố gắng hiển thị toàn bộ trang (ở đây rộng 10000 pixel) cho mọi hành động không? (chỉ hiển thị khung nhìn hiện tại!)


<!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] Kích thước phông chữ 600K. Phải là một tính năng trợ năng cho những người có thị lực rất kém? ;-)
geert3

61
@ geert3 tôi chắc chắn rằng đó là cho một trình duyệt mặt trăng quay quanh web
David Wilkins

3
Bản trình diễn của bạn diễn ra suôn sẻ trong Chrome 41.0.2236.0 dev-m
Pier-Luc Gendreau

11
Tôi đang ở trạng thái hoàng yến (41.0.2241.0 canary) và tôi vẫn nhận được độ trễ. Các bạn nên thử nó trên một máy tính xách tay thay vì một giàn khoan chơi game, bạn sẽ thấy nó
markasoftware

3
Trái với suy nghĩ của nhiều người, IE thực sự nhanh hơn Chrome để hiển thị hầu hết các trang. Công cụ javascript của nó chậm hơn một chút.
Falanwe

Câu trả lời:


62

Thay đổi thành position: fixeddường như để tăng tốc mọi thứ.


27
Đây không phải là câu trả lời trực tiếp cho câu hỏi của anh ấy, nhưng nó là một giải pháp tiềm năng cho vấn đề ban đầu của anh ấy (phản hồi chậm trong Chrome). Tư duy bên ngoài hộp nên được khuyến khích, IMHO.
geert3

Ở đây nó có vẻ hoạt động hoàn hảo: gget.it/e0ubdh67/big-div-test_fixed.html . Bạn có biết tại sao ? :)
Basj

2
Tôi chỉ có thể đoán. fixedrõ ràng là ít phức tạp hơn để bố trí và có lẽ họ có thể thực hiện nhiều tối ưu hóa hơn. Nhưng tôi chưa xem mã nguồn của công cụ kết xuất nếu bạn muốn nói vậy ;-)
geert3

1
Câu trả lời này và câu trả lời được cung cấp bởi ViliusL, cả hai đều có cùng một nhận xét "để lại nhận xét", bởi những người khác nhau. Làm thế nào là thú vị?
Joe

2
@Joe, đây là một bộ câu trả lời tiêu chuẩn do StackOverflow cung cấp để người kiểm duyệt sử dụng. Một số cần tiết chế vừa phải hơn.
geert 3

42

Sử dụng transformthay vì top/left:

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

Bản demo trực tiếp tại jsFiddle .


2
Một điều rất lạ : trong jsFiddle của bạn, nó thực sự nhanh với Chrome. Tôi đã thực hiện chính xác sửa đổi mà bạn đề xuất trong mã gốc của tôi tại đây: gget.it/1owxq8kr/big-div-test_transform.html và liên kết cuối cùng này chạy chậm trên Chrome :( Làm sao điều này có thể xảy ra? Nó giống với jsFiddle của bạn ! [Lưu ý: kỳ diệu thay, các câu trả lời của geert3 dường như hoạt động, tôi không biết tại sao nhưng nó hoạt động: gget.it/e0ubdh67/big-div-test_fixed.html]
Basj

@Basj Có thể tùy thuộc vào phiên bản, Chrome của tôi (39.0.2171.71 m) duyệt trang được liên kết trong nhận xét của bạn mượt mà và nhanh như FF. Dù sao, thiết lập vị trí để fixedđưa phần tử ra khỏi dòng chảy văn bản và tiết kiệm rất nhiều kết xuất. Trong tài liệu của transformMDN nói: "... một ngữ cảnh xếp chồng sẽ được tạo. Trong trường hợp đó, đối tượng sẽ hoạt động như một khối chứa các phần tử vị trí: cố định mà nó chứa."
Teemu

2
Thật kỳ lạ, tôi cũng có Chrome 39.0.2171.71 m ... và gget.it/1owxq8kr/big-div-test_transform.html quay chậm, chậm như phiên bản gốc của tôi (trong câu hỏi chính nó). Oohhh có thể nó phụ thuộc vào khả năng tăng tốc phần cứng: Tôi có lẽ không có khả năng tăng tốc phần cứng, vì tôi có một máy tính xách tay với chip đồ họa kém ...
Basj

1
@Basj thêm một wrapper <div style="position:relative;min-height: 900px;">Your's divs</div>jsFiddle cũng vậy
Alfonso Rubalcava

1
@AlfonsoRubalcava Ồ được rồi ... Điều này giải thích tại sao jsfiddle mượt mà và liên kết trực tiếp không mượt (Chrome): gget.it/1owxq8kr/big-div-test_transform.html ! Cảm ơn! Vì vậy, sự cải thiện trong hoạt động xuất phát từ position:relativepropbably, mà là tương tự như câu trả lời của geert3
Basj

22
  1. Trả lời cho nhiệm vụ đầu tiên "tại sao". Một trong những vấn đề là kích thước phông chữ . bạn có kích thước phông chữ 600000px, hầu hết trình duyệt sẽ thấy nó quá cao và hiển thị nhỏ hơn, trong khi chrome cố gắng hiển thị kích thước ban đầu. Có vẻ như chrome không thể sơn lại những chữ cái lớn như vậy với phong cách bạn yêu cầu rất nhanh.

Nhưng kết hợp câu trả lời của Teemu và geert3 - sử dụng biến đổi và vị trí: cố định, giúp chrome hoạt động nhanh hơn nhiều ngay cả với các phông chữ lớn.

  1. Trả lời cho câu hỏi thứ 2: "Có cách nào ... không cố kết xuất toàn bộ trang" - bạn có thể thử áp dụng thao tác chuột cho các phần tử trong vùng chứa, không phải cho toàn bộ vùng chứa.

Kích thước phông chữ tối đa: 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
Nó thực sự có. OP đặt hai câu hỏi, câu hỏi trước được trả lời: "Tại sao FF, IE xử lý nó một cách chính xác mà không phải Chrome?"
Hans Roerdinkholder

Hấp dẫn. Bạn có lưu ý đến một số yếu tố cho thấy rằng Firefox dừng ở 10k và Chrome cố gắng hiển thị kích thước ban đầu không? (Nó sẽ rất thú vị để tham khảo trong tương lai). Cảm ơn trước @ViliusL!
Basj

1
@Basj đã thêm kích thước phông chữ tối đa cho mỗi trình duyệt (được thử nghiệm ngày hôm nay) và nó là 2k cho firefox.
ViliusL

Cảm ơn rất nhiều @ViliusL! Thật vậy, FF giới hạn font-sizevà đây có thể là lý do cho sự chậm chạp trên FF. Nhưng lẽ ra nó cũng rất chậm trên IE, nhưng nó không ... Lạ!
Basj

4

Ngoài câu trả lời của Teemu về việc sử dụng dịch:

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

Mà bạn cũng nên sử dụng các tiền tố của nhà cung cấp khác, Bạn có thể chỉ cần sửa lỗi này bằng cách sử dụng điều này trên phần thân:

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

và điều này trên html:

height: 100%;

Tuy nhiên, điều này sẽ vô hiệu hóa tính năng cuộn. Vì vậy, những gì tôi phải làm là, thêm một mousedownsự kiện vào nội dung và áp dụng các kiểu đó bằng cách sử dụng lớp css bất cứ khi nào mousedownđược kích hoạt và xóa lớp đó trên mouseup.


Tôi đã cố thêm những gì bạn đề cập ở đây: gget.it/0ufheqmt/big-div-test_prisonersolution.html , có phải ý bạn không? Ở đây, nó vẫn còn chậm khi kéo bằng Chrome. Tương tự cho bạn? (PS: Tôi không hiểu: bạn đề nghị để làm những sửa đổi CSS thay vì sử dụng style.transformhoặc sử dụng transform?). Nhân tiện, cảm ơn câu trả lời của bạn @Prisoner!
Basj

2

Câu trả lời của @Teemus gần như làm được tất cả.

Sử dụng transform vớitranslate3d thay vì top/left.

translate3d cho phép tăng tốc phần cứng.

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

Bản demo trực tiếp tại jsFiddle .


1

Tôi đã phân tích điều này và nhận thấy rằng vấn đề ban đầu liên quan đến kiến ​​trúc màn hình Chrome và việc sử dụng các chuỗi nền để hiển thị trang.

Nếu bạn muốn kết xuất nhanh, hãy vào chrome: flags, cuộn đến cài đặt Impl-side paint và đặt "Disabled", sau đó khởi động lại trình duyệt - thao tác di chuột sẽ trơn tru.

Những gì tôi nhận thấy là nếu bạn bật bộ đếm FPS, FPS được báo cáo trong trường hợp này vẫn rất cao, mặc dù hiệu suất trên màn hình thực tế là rất thấp. Lời giải thích dự kiến ​​của tôi (không phải là chuyên gia về kiến ​​trúc màn hình Chrome) là nếu chuỗi giao diện người dùng và màn hình nằm trên các chuỗi riêng biệt, thì có thể có mâu thuẫn trong việc hiển thị div - trong trường hợp chuỗi giao diện người dùng và chuỗi hiển thị nằm trên cùng một chuỗi, chuỗi giao diện người dùng không thể gửi tin nhắn nhanh hơn luồng giao diện người dùng có thể hiển thị.

Tôi đề nghị rằng điều này nên được lưu dưới dạng một lỗi Chrome.


1

Sử dụng display: tabletable-layout:fixedtrên div hoặc một bảng bao bọc div. Trong HTML:

Mô hình bảng HTML đã được thiết kế để, với sự hỗ trợ của tác giả, tác nhân người dùng có thể hiển thị bảng tăng dần (tức là khi các hàng trong bảng đến) thay vì phải đợi tất cả dữ liệu trước khi bắt đầu hiển thị.

Để tác nhân người dùng định dạng bảng trong một lần chuyển, tác giả phải thông báo cho tác nhân người dùng:

Số cột trong bảng. Vui lòng tham khảo phần cách tính số cột trong bảng để biết chi tiết về cách cung cấp thông tin này. Chiều rộng của các cột này. Vui lòng tham khảo phần tính toán chiều rộng của cột để biết chi tiết về cách cung cấp thông tin này.

Chính xác hơn, tác nhân người dùng có thể hiển thị một bảng trong một lần chuyển khi độ rộng cột được chỉ định bằng cách sử dụng kết hợp các phần tử COLGROUP và COL. Nếu bất kỳ cột nào được chỉ định theo tỷ lệ tương đối hoặc tỷ lệ phần trăm (xem phần tính toán chiều rộng của cột), tác giả cũng phải chỉ định chiều rộng của chính bảng đó.

Để hiển thị tăng dần, trình duyệt cần số lượng cột và chiều rộng của chúng. Chiều rộng mặc định của bảng là kích thước cửa sổ hiện tại (width = "100%"). Điều này có thể được thay đổi bằng cách đặt thuộc tính width của phần tử TABLE. Theo mặc định, tất cả các cột có cùng chiều rộng, nhưng bạn có thể chỉ định chiều rộng cột bằng một hoặc nhiều phần tử COL trước khi dữ liệu bảng bắt đầu.

Vấn đề còn lại là số lượng cột. Một số người đã đề xuất đợi cho đến khi hàng đầu tiên của bảng được nhận, nhưng điều này có thể mất nhiều thời gian nếu các ô có nhiều nội dung. Về tổng thể, nó có ý nghĩa hơn, khi muốn hiển thị tăng dần, để các tác giả chỉ định rõ ràng số cột trong phần tử TABLE.

Tác giả vẫn cần một cách để thông báo cho các tác nhân người dùng nên sử dụng hiển thị tăng dần hay tự động định kích thước bảng để vừa với nội dung ô. Trong chế độ tự động định cỡ hai lần vượt qua, số cột được xác định bởi lần vượt qua đầu tiên. Trong chế độ tăng dần, số lượng cột phải được nêu lên phía trước (với các phần tử COL hoặc COLGROUP).

và CSS:

17.5.2.1 Bố cục bảng cố định

Với thuật toán (nhanh) này, bố cục theo chiều ngang của bảng không phụ thuộc vào nội dung của các ô; nó chỉ phụ thuộc vào chiều rộng của bảng, chiều rộng của các cột và đường viền hoặc khoảng cách ô.

Chiều rộng của bảng có thể được chỉ định rõ ràng với thuộc tính 'width'. Giá trị 'auto' (cho cả 'display: table' và 'display: inline-table') có nghĩa là sử dụng thuật toán bố cục bảng tự động. Tuy nhiên, nếu bảng là bảng cấp khối ('display: table') trong quy trình bình thường, UA có thể (nhưng không bắt buộc) sử dụng thuật toán 10.3.3 để tính chiều rộng và áp dụng bố cục bảng cố định ngay cả khi chiều rộng được chỉ định là 'tự động'.

Người giới thiệu

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.