Div ที่ใหญ่มากมากมาก


109

สำหรับโครงการของฉัน (ดูโครงการ BigPictu.reหรือbigpicture.js GitHub ) ฉันต้องจัดการกับ<div>คอนเทนเนอร์ที่ใหญ่มากและใหญ่มาก

ฉันรู้ว่ามีความเสี่ยงที่จะมีประสิทธิภาพต่ำด้วยวิธีง่ายๆที่ฉันใช้ แต่ฉันไม่ได้คาดหวังว่ามันจะมีอยู่ใน ... Chrome เท่านั้น!

หากคุณทดสอบเพจเล็ก ๆ นี้ (ดูโค้ดด้านล่าง) การแพน (คลิก + ลาก) จะเป็น:

  • ปกติ / ราบรื่นบน Firefox
  • ปกติ / ราบรื่นแม้ใน Internet Explorer
  • ช้ามาก (เกือบจะขัดข้อง) บน Chrome!

แน่นอนฉันสามารถเพิ่มโค้ด (ในโปรเจ็กต์ของฉัน) เพื่อทำเช่นนั้นเมื่อคุณซูมเข้ามากข้อความที่มีขนาดฟอนต์ใหญ่มากจะถูกซ่อนไว้ แต่เหตุใด Firefox และ Internet Explorer จึงจัดการอย่างถูกต้องและไม่ใช่ Chrome

มีวิธีใน JavaScript, HTML หรือ CSS ที่จะบอกเบราว์เซอร์ไม่ให้พยายามแสดงผลทั้งหน้า (ซึ่งกว้าง 10,000 พิกเซลที่นี่) สำหรับทุกการกระทำหรือไม่? (แสดงผลวิวพอร์ตปัจจุบันเท่านั้น!)


<!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 จะต้องมีคุณลักษณะการเข้าถึงสำหรับผู้ที่มีมากสายตาไม่ดี? ;-)
geert3

61
@ geert3 ฉันแน่ใจว่าเป็นเว็บเบราว์เซอร์ที่โคจรรอบดวงจันทร์
David Wilkins

3
การสาธิตของคุณราบรื่นใน Chrome 41.0.2236.0 dev-m
Pier-Luc Gendreau

11
ฉันอยู่ในนกขมิ้น (41.0.2241.0 canary) และฉันยังคงได้รับความล่าช้า พวกคุณควรลองใช้บนแล็ปท็อปแทนที่จะเป็นอุปกรณ์เล่นเกมคุณจะเห็นมัน
markasoftware

3
ตรงกันข้ามกับความเชื่อที่เป็นที่นิยมจริงๆแล้ว IE นั้นเร็วกว่า Chrome สำหรับการแสดงผลหน้าเว็บส่วนใหญ่ เครื่องยนต์ javascript จะช้าลงเล็กน้อย
Falanwe

คำตอบ:


62

การเปลี่ยนเป็นposition: fixedดูเหมือนจะเร่งความเร็ว


27
ไม่ใช่คำตอบโดยตรงสำหรับคำถามของเขา แต่เป็นวิธีแก้ปัญหาเบื้องต้นที่เป็นไปได้ (การตอบสนองช้าใน Chrome) ควรส่งเสริมการคิดนอกกรอบ IMHO
geert3

นี่มันดูเหมือนว่าจะทำงานได้อย่างสมบูรณ์แบบ: gget.it/e0ubdh67/big-div-test_fixed.html คุณรู้ไหมว่าทำไม ? :)
Basj

2
ฉันเดาได้เท่านั้น fixedเห็นได้ชัดว่ามีความซับซ้อนน้อยกว่าในการจัดวางและบางทีพวกเขาสามารถทำการเพิ่มประสิทธิภาพได้มากขึ้น แต่ฉันไม่ได้ดูซอร์สโค้ด
เอ็นจิ้

1
คำตอบนี้และคำตอบที่จัดทำโดย ViliusL ทั้งสองมีความคิดเห็น "แสดงความคิดเห็น" เหมือนกันโดยคนอื่น จะเด็ดขนาดไหน
โจ

2
@ โจสิ่งเหล่านี้มาจากชุดคำตอบมาตรฐานที่ StackOverflow ให้ไว้เพื่อใช้โดยผู้ดูแล บางคนจำเป็นต้องดูแลมากขึ้นในระดับปานกลางแม้ว่า
geert3

42

ใช้transformแทนtop/left:

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

การสาธิตการแสดงสดที่ jsFiddle


2
แปลกมากสิ่งใน jsFiddle ของคุณก็เป็นไปอย่างรวดเร็วด้วย Chrome แน่นอน ฉันไม่ได้ว่าการเปลี่ยนแปลงที่คุณเสนอในรหัสเดิมของฉันที่นี่: gget.it/1owxq8kr/big-div-test_transform.html ? และการเชื่อมโยงที่ผ่านมานี้ช้าบน Chrome :( นี้เป็นวิธีการที่เป็นไปได้ก็จะมีลักษณะเช่นเดียวกับ jsFiddle ของคุณ ! [หมายเหตุ: คำตอบของ geert3 ดูเหมือนจะใช้ได้ผลอย่างน่าอัศจรรย์ฉันไม่รู้ว่าทำไม แต่มันใช้ได้: gget.it/e0ubdh67/big-div-test_fixed.html]
Basj

@Basj อาจจะขึ้นอยู่กับเวอร์ชัน Chrome ของฉัน (39.0.2171.71 ม.) จะเลื่อนหน้าที่เชื่อมโยงในความคิดเห็นของคุณอย่างราบรื่นและรวดเร็วเท่ากับ FF อย่างไรก็ตามการตั้งค่าตำแหน่งเพื่อfixedนำองค์ประกอบออกจากโฟลว์ข้อความและประหยัดการแสดงผลจำนวนมาก ในเอกสารของtransformMDN ระบุว่า: "... บริบทการซ้อนจะถูกสร้างขึ้นในกรณีนี้วัตถุจะทำหน้าที่เป็นบล็อกที่มีตำแหน่ง: องค์ประกอบคงที่ที่มีอยู่"
Teemu

2
แปลกฉันมี Chrome 39.0.2171.71 ม. เช่นกัน ... และgget.it/1owxq8kr/big-div-test_transform.htmlกระทะช้าช้าเท่าเวอร์ชันดั้งเดิมของฉัน (ในคำถามเอง) Oohhh อาจขึ้นอยู่กับการเร่งความเร็วของฮาร์ดแวร์: ฉันอาจไม่มีการเร่งฮาร์ดแวร์เพราะฉันมีแล็ปท็อปที่มีชิปกราฟิกไม่ดี ...
Basj

1
@Basj เพิ่มกระดาษห่อ<div style="position:relative;min-height: 900px;">Your's divs</div>jsFiddle ก็เช่นกัน
Alfonso Rubalcava

1
@AlfonsoRubalcava โอ้ตกลง ... สิ่งนี้อธิบายได้ว่าทำไม jsfiddle จึงราบรื่นและลิงก์โดยตรงไม่ราบรื่น (Chrome): gget.it/1owxq8kr/big-div-test_transform.html ! ขอบคุณ! ดังนั้นการปรับปรุงประสิทธิภาพจึงมาจากคำposition:relativeทำนายซึ่งคล้ายกับคำตอบของ
geert3

22
  1. ตอบเควสแรก "ทำไม" หนึ่งในปัญหาที่มีขนาดตัวอักษร คุณมีขนาดตัวอักษร 600000px เบราว์เซอร์ส่วนใหญ่จะเห็นว่าสูงเกินไปและแสดงผลเล็กลงในขณะที่ chrome พยายามแสดงผลขนาดดั้งเดิม ดูเหมือนว่าโครเมี่ยมจะไม่สามารถทาสีตัวอักษรขนาดใหญ่ตามสไตล์ที่คุณร้องขอได้เร็วนัก

แต่การรวมคำตอบของ Teemu และ geert3 เข้าด้วยกันโดยใช้การแปลงและตำแหน่ง: คงที่ทำให้ Chrome ทำงานได้เร็วขึ้นมากแม้จะใช้แบบอักษรขนาดใหญ่ก็ตาม

  1. ตอบคำถามที่ 2: "มีวิธี ... ที่จะไม่พยายามแสดงผลทั้งหน้า" - คุณสามารถลองใช้การดำเนินการของเมาส์สำหรับองค์ประกอบในคอนเทนเนอร์ไม่ใช่สำหรับทั้งคอนเทนเนอร์

ขนาดตัวอักษรสูงสุด: 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
มันเป็นจริง OP ถามคำถามสองข้อซึ่งก่อนหน้านี้มีคำตอบ: "เหตุใด FF, IE จึงจัดการได้อย่างถูกต้องและไม่ใช่ Chrome"
Hans Roerdinkholder

น่าสนใจ. คุณมีองค์ประกอบบางอย่างที่แสดงว่า Firefox หยุดที่ 10,000 และ Chrome พยายามที่จะแสดงขนาดดั้งเดิมหรือไม่? (น่าสนใจสำหรับการอ้างอิงในอนาคต) ขอบคุณล่วงหน้า @ViliusL!
Basj

1
@Basj เพิ่มขนาดตัวอักษรสูงสุดสำหรับแต่ละเบราว์เซอร์ (ทดสอบวันนี้) และเป็น 2k สำหรับ firefox
ViliusL

ขอบคุณมาก @ViliusL! แน่นอน FF จำกัดfont-sizeและนี่อาจเป็นสาเหตุที่ทำให้ FF ไม่ช้า แต่มันก็น่าจะช้ามากใน IE ด้วย แต่มันไม่ใช่ ... แปลก!
Basj

4

นอกเหนือจากคำตอบของ Teemu ในการใช้การแปล:

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

ซึ่งคุณควรใช้คำนำหน้าผู้ขายรายอื่นด้วยคุณสามารถแก้ไขได้โดยใช้สิ่งนี้กับเนื้อหา:

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

และสิ่งนี้ใน html:

height: 100%;

อย่างไรก็ตามสิ่งนี้จะปิดการใช้งานการเลื่อน สิ่งที่ฉันทำคือเพิ่มmousedownเหตุการณ์ลงในเนื้อหาและใช้สไตล์เหล่านั้นโดยใช้คลาส css ทุกครั้งที่mousedownถูกทริกเกอร์และลบคลาสmouseupนั้นออก


ฉันพยายามเพิ่มสิ่งที่คุณพูดถึงที่นี่: gget.it/0ufheqmt/big-div-test_prisonersolution.htmlคุณหมายถึงอะไร? ที่นี่ยังลากด้วย Chrome ได้ช้า เหมือนกันสำหรับคุณ? (PS: ผมไม่เข้าใจ: คุณแนะนำจะปรับเปลี่ยน CSS เหล่านี้แทนการใช้style.transformหรือมีใช้transform?) ขอบคุณสำหรับคำตอบของคุณ @Prisoner!
Basj


1

ฉันวิเคราะห์สิ่งนี้และพบว่าปัญหาเดิมที่เกี่ยวข้องกับสถาปัตยกรรมการแสดงผลของ Chrome และการใช้เธรดพื้นหลังเพื่อแสดงผลหน้า

หากคุณต้องการแสดงผลอย่างรวดเร็วให้ไปที่ chrome: flags เลื่อนไปที่การตั้งค่า Impl-side painting และตั้งค่า "Disabled" จากนั้นรีสตาร์ทเบราว์เซอร์ - mousemove จะราบรื่น

สิ่งที่ฉันพบคือถ้าคุณเปิดใช้งานตัวนับ FPS FPS ที่รายงานในสถานการณ์นี้ยังคงสูงมากแม้ว่าประสิทธิภาพบนหน้าจอจริงจะต่ำมากก็ตาม คำอธิบายเบื้องต้นของฉัน (ไม่ใช่ผู้เชี่ยวชาญด้านสถาปัตยกรรมการแสดงผลของ Chrome) คือถ้าเธรด UI และการแสดงผลอยู่ในเธรดที่แยกจากกันอาจมีข้อขัดแย้งในการแสดงผลของ div - ในกรณีที่เธรด UI และเธรดการแสดงผลอยู่บน เธรดเดียวกันเธรด UI ไม่สามารถส่งข้อความได้เร็วกว่าเธรด UI สามารถแสดงผลได้

ฉันขอแนะนำว่าควรยื่นเรื่องนี้เป็นข้อบกพร่องของ Chrome


1

ใช้display: tableและtable-layout:fixedบน div หรือตารางที่ตัด div ใน HTML:

โมเดลตาราง HTML ได้รับการออกแบบมาเพื่อให้ด้วยความช่วยเหลือของผู้เขียนตัวแทนผู้ใช้อาจแสดงผลตารางทีละน้อย (เช่นเมื่อแถวของตารางมาถึง) แทนที่จะต้องรอข้อมูลทั้งหมดก่อนที่จะเริ่มแสดงผล

เพื่อให้ตัวแทนผู้ใช้จัดรูปแบบตารางในรอบเดียวผู้เขียนต้องบอกตัวแทนผู้ใช้:

จำนวนคอลัมน์ในตาราง โปรดดูส่วนการคำนวณจำนวนคอลัมน์ในตารางสำหรับรายละเอียดเกี่ยวกับวิธีการจัดหาข้อมูลนี้ ความกว้างของคอลัมน์เหล่านี้ โปรดอ่านส่วนการคำนวณความกว้างของคอลัมน์สำหรับรายละเอียดเกี่ยวกับวิธีการจัดหาข้อมูลนี้

อย่างแม่นยำยิ่งขึ้นตัวแทนผู้ใช้อาจแสดงผลตารางในรอบเดียวเมื่อระบุความกว้างของคอลัมน์โดยใช้องค์ประกอบ COLGROUP และ COL ร่วมกัน หากมีการระบุคอลัมน์ใด ๆ ในรูปแบบสัมพัทธ์หรือเปอร์เซ็นต์ (ดูหัวข้อการคำนวณความกว้างของคอลัมน์) ผู้เขียนต้องระบุความกว้างของตารางด้วย

สำหรับการแสดงผลแบบเพิ่มหน่วยเบราว์เซอร์ต้องใช้จำนวนคอลัมน์และความกว้าง ความกว้างเริ่มต้นของตารางคือขนาดหน้าต่างปัจจุบัน (width = "100%") ซึ่งสามารถเปลี่ยนแปลงได้โดยการตั้งค่าแอตทริบิวต์ความกว้างขององค์ประกอบ TABLE โดยค่าเริ่มต้นคอลัมน์ทั้งหมดจะมีความกว้างเท่ากัน แต่คุณสามารถระบุความกว้างของคอลัมน์ด้วยองค์ประกอบ COL อย่างน้อยหนึ่งรายการก่อนที่ข้อมูลตารางจะเริ่มต้น

ปัญหาที่เหลือคือจำนวนคอลัมน์ บางคนแนะนำให้รอจนกว่าจะได้รับแถวแรกของตาราง แต่อาจใช้เวลานานหากเซลล์มีเนื้อหาจำนวนมาก โดยรวมแล้วมันสมเหตุสมผลกว่าเมื่อต้องการการแสดงผลแบบเพิ่มหน่วยเพื่อให้ผู้เขียนระบุจำนวนคอลัมน์อย่างชัดเจนในองค์ประกอบ TABLE

ผู้เขียนยังคงต้องการวิธีการบอกตัวแทนผู้ใช้ว่าจะใช้การแสดงผลแบบเพิ่มหน่วยหรือกำหนดขนาดตารางโดยอัตโนมัติเพื่อให้พอดีกับเนื้อหาของเซลล์ ในโหมดการปรับขนาดอัตโนมัติสองรอบจำนวนคอลัมน์จะถูกกำหนดโดยครั้งแรก ในโหมดเพิ่มจำนวนคอลัมน์จะต้องระบุไว้ข้างหน้า (ด้วยองค์ประกอบ COL หรือ COLGROUP)

และ CSS:

17.5.2.1 เค้าโครงตารางคงที่

ด้วยอัลกอริทึม (เร็ว) นี้เค้าโครงแนวนอนของตารางไม่ได้ขึ้นอยู่กับเนื้อหาของเซลล์ ขึ้นอยู่กับความกว้างของตารางความกว้างของคอลัมน์และเส้นขอบหรือระยะห่างของเซลล์เท่านั้น

ความกว้างของตารางอาจถูกระบุอย่างชัดเจนด้วยคุณสมบัติ "width" ค่าของ "อัตโนมัติ" (สำหรับทั้ง "display: table" และ "display: inline-table") หมายถึงใช้อัลกอริทึมเค้าโครงตารางอัตโนมัติ อย่างไรก็ตามหากตารางเป็นตารางระดับบล็อก ('display: table') ในโฟลว์ปกติ UA อาจ (แต่ไม่ต้อง) ใช้อัลกอริทึม 10.3.3 เพื่อคำนวณความกว้างและใช้เค้าโครงตารางคงที่แม้ว่า ความกว้างที่ระบุคือ "อัตโนมัติ"

อ้างอิง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.