Raphael.js ทำให้เกิดคอขวดของเลย์เอาต์แบบซิงโครนัสแบบบังคับ

ฉันตรวจสอบเวลาในการโหลดหน้าเว็บสำหรับเว็บไซต์ของฉันใน Chrome (โดยใช้ไทม์ไลน์) และได้รับคำเตือนหลายร้อยรายการที่ระบุว่า "รูปแบบซิงโครนัสที่บังคับอาจเป็นคอขวดของประสิทธิภาพที่เป็นไปได้" สำหรับการเรียก Raphael.js ทั้งหมด:

ป้อนคำอธิบายรูปภาพที่นี่

ฉันไม่รู้วิธีแก้ไขนี้ :/

มีความคิดเห็นว่าจะดูที่ไหน?

โดยปกติแล้วฉันสร้างข้อความบนเพจด้วยวิธีต่อไปนี้:

currentPaper.text(width,height,"text")
            .attr({opacity:.8, fill: "#333", 'font-size':10})
            .id = "someId";

//Or, to be exact:

currentPaper.text(x_pos+(width/2), 
                  y_pos-height/8, 
                  lopaLayoutArray.x[s].y1[r].y2[x])
            .attr({opacity:.8, fill: "#333", 'font-size':(10*size)})
            .id = seatName+"-textLabel";

ขอบคุณ!


person Katie    schedule 19.02.2015    source แหล่งที่มา
comment
เป็นไปได้ไหมที่จะรวมโค้ดของคุณมากกว่านี้? ยากที่จะเข้าใจว่าอะไรจะเกิดขึ้นผิดพลาดจากข้อความเพียงข้อความเดียว   -  person konkked    schedule 19.02.2015
comment
@konkked อาจจะ! ฉันไม่แน่ใจว่าจะหาได้ที่ไหน :( ฉันหวังว่าจะมีหมายเลขบรรทัดบางประเภทในไทม์ไลน์ แต่มันแค่ชี้ไปที่ไลบรารี Raphael :/ หมายเลขบรรทัด LopaView คือบรรทัดที่ฉันรวมไว้ในคำถาม ทำ คุณรู้ไหมว่าฉันควรมองหาอะไร มีฟังก์ชัน Raphael.js ที่ฉันควรหลีกเลี่ยงการใช้หรือไม่   -  person Katie    schedule 19.02.2015
comment
สิ่งเดียวที่ฉันคิดได้คือคุณกำลังผูกตรรกะของคุณกับการเปลี่ยนแปลงในอนาคตกับผลลัพธ์ของโครงร่าง dom ก่อนหน้า ทำให้การดำเนินการซิงโครนัสอย่างมีประสิทธิภาพ บางทีถ้าคุณระบุตำแหน่งที่คุณได้รับตัวแปร lopaLayoutArray จากที่สามารถช่วยคิดได้อย่างชัดเจนว่าสิ่งนี้อยู่ที่ไหน กำลังเกิดขึ้น   -  person konkked    schedule 20.02.2015
comment
@konkked อืม .. ใช่ฉันคิดว่าฉันจะต้องเปลี่ยนรหัสสักหน่อย ฉันค้นคว้าข้อมูลและเรียกว่า Layout Thrashing และนั่นคือสิ่งที่กำลังเกิดขึ้น: blog.idrsolutions.com/2014/08/   -  person Katie    schedule 20.02.2015
comment
ใช่ นั่นคือสิ่งที่ฉันกำลังพูดยกเว้นว่าพวกเขารู้จริงๆ ว่าพวกเขากำลังพูดถึงอะไร ฉันสามารถแปลงความคิดเห็นของฉันเป็นคำตอบได้หรือไม่ แม้จะคิดว่ามันไม่ถูกต้อง 100% ด้วยแนวคิดพื้นฐานและไม่มีใครโพสต์คำตอบ   -  person konkked    schedule 21.02.2015
comment
@konkked แน่นอนถ้าคุณต้องการ! :)   -  person Katie    schedule 21.02.2015


คำตอบ (1)


ปัญหา:

ปัญหานี้เรียกว่า "Layout Thrashing" และเกิดขึ้นเนื่องจากเบราว์เซอร์พยายามรีเฟรช / วาดใหม่ทันทีหลังจากการวาด Raphael ทุกครั้ง

ตัวอย่างเช่น สิ่งนี้จะทำให้เลย์เอาต์พัง:

var a = document.getElementById('element-a');
var b = document.getElementById('element-b');

a.clientWidth = 100;
var aWidth = a.clientWidth;

b.clientWidth = 200;
var bWidth = b.clientWidth;

"ในตัวอย่างง่ายๆ นี้ เบราว์เซอร์จะอัปเดตเลย์เอาต์ทั้งหมดสองครั้ง เนื่องจากหลังจากตั้งค่าความกว้างขององค์ประกอบแรกแล้ว คุณจะต้องดึงข้อมูลความกว้างขององค์ประกอบ เมื่อดึงคุณสมบัติ css เบราว์เซอร์จะรู้ว่าจำเป็นต้องอัปเดตข้อมูล ดังนั้น จากนั้นไปอัปเดตแผนผัง DOM ทั้งหมดในหน่วยความจำ เมื่อนั้น ก็จะดำเนินการต่อไปยังบรรทัดถัดไป ซึ่งในไม่ช้าจะทำให้เกิดการอัปเดตอีกครั้งเนื่องจากเหตุผลเดียวกัน"

สิ่งนี้สามารถแก้ไขได้โดยเปลี่ยนลำดับของโค้ดดังนี้:

var a = document.getElementById('element-a');
var b = document.getElementById('element-b');

a.clientWidth = 100;
b.clientWidth = 200;

var aWidth = a.clientWidth;
var bWidth = b.clientWidth;

"ตอนนี้ เบราว์เซอร์จะอัปเดตคุณสมบัติทั้งสองทีละรายการโดยไม่ต้องอัปเดตแผนผัง"

แหล่งที่มา:

https://blog.idrsolutions.com/2014/08/beware-javascript-layout-thrashing/

http://www.codeproject.com/Articles/758790/Debugging-and-ulating-the-Forced-Synchronous-Layou

http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-Performance-making-your-javascript-slow/

https://dev.opera.com/articles/efficient-javascript/?page=3#reflow

จิตวิญญาณ:

วิธีหนึ่งในการแก้ไขปัญหานี้ (วิธีที่รวดเร็วและสกปรกมาก) คือการ hide() div ที่คุณกำลังวาดไป จากนั้นเมื่อคุณทำเสร็จแล้ว show() มัน . ฉันเคยประสบผลสำเร็จมาแล้วกับราฟาเอล และมันก็ออกมาแปลกๆ ด้วยวิธีนี้ อย่างไรก็ตาม มันจะเร็วขึ้น...

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

นี่คือผลลัพธ์:

ป้อนคำอธิบายรูปภาพที่นี่

วิธีนี้ใช้ได้ผลสำหรับฉัน!

person Katie    schedule 20.02.2015
comment
ไม่เป็นไร นี่เป็นคำตอบที่ดีกว่าที่ฉันจะให้ได้ - person konkked; 23.02.2015