JavaScript เป็นภาษาที่ยืดหยุ่นมาก เราสามารถเขียนรูปแบบต่าง ๆ ของรหัสตามที่เราต้องการ รูปแบบที่แตกต่างกันของรหัสจะนำไปสู่ความแตกต่างในประสิทธิภาพการดำเนินการอย่างหลีกเลี่ยงไม่ได้ ในระหว่างกระบวนการพัฒนาเราได้สัมผัสกับวิธีการมากมายในการปรับปรุงประสิทธิภาพของรหัส มาเรียงลำดับทั่วไปและง่ายต่อการหลีกเลี่ยงปัญหา
ประสิทธิภาพการดำเนินการของ JavaScript
ห่วงโซ่ขอบเขตการปิดการสืบทอดต้นแบบการประเมินและคุณสมบัติอื่น ๆ ใน JavaScript ให้ฟังก์ชั่นเวทมนตร์ที่หลากหลายในขณะที่ยังนำปัญหาประสิทธิภาพต่าง ๆ หากคุณใช้มันอย่างไม่ระมัดระวังคุณจะนำไปสู่การดำเนินการที่ไม่มีประสิทธิภาพ
1. การนำเข้าทั่วโลก
เราจะใช้ตัวแปรทั่วโลก (หน้าต่างเอกสารตัวแปรส่วนกลางที่กำหนดเอง ฯลฯ ) ในระหว่างกระบวนการเข้ารหัส ใครก็ตามที่รู้ว่าโซ่ขอบเขตจาวาสคริปต์รู้ว่าการเข้าถึงตัวแปรทั่วโลกในขอบเขตท้องถิ่นนั้นต้องการการข้ามเลเยอร์โซ่ขอบเขตทั้งหมดด้วยเลเยอร์จนกระทั่งขอบเขตระดับบนสุดและประสิทธิภาพการเข้าถึงของตัวแปรท้องถิ่นจะเร็วขึ้นและสูงขึ้น ดังนั้นเมื่อใช้วัตถุระดับโลกบางอย่างที่ความถี่สูงในขอบเขตท้องถิ่นมันสามารถนำเข้าสู่ขอบเขตท้องถิ่นได้เช่น:
การคัดลอกรหัสมีดังนี้:
// 1. ส่งผ่านเข้าไปในโมดูลเป็นพารามิเตอร์
(ฟังก์ชั่น (หน้าต่าง, $) {
var xxx = window.xxx;
$ ("#xxx1"). xxx ();
$ ("#xxx2"). xxx ();
}) (หน้าต่าง jQuery);
// 2. เก็บไว้ในตัวแปรท้องถิ่น
การทำงาน(){
var doc = เอกสาร;
var global = window.global;
-
2. ปัญหาการประเมินและชั้นเรียน
เราทุกคนรู้ว่าการประเมินสามารถใช้สตริงเป็นรหัส JS เพื่อดำเนินการและประมวลผล มีการกล่าวกันว่ารหัสที่ดำเนินการโดยใช้ Eval นั้นช้ากว่ารหัสที่ไม่ได้ใช้ Eval มากกว่า 100 เท่า (ฉันยังไม่ได้ทดสอบประสิทธิภาพเฉพาะและผู้ที่สนใจสามารถทดสอบได้)
รหัส JavaScript จะดำเนินการ "precompilation" ที่คล้ายกันก่อนที่จะดำเนินการ: อันดับแรกมันจะสร้างวัตถุที่ใช้งานอยู่ในสภาพแวดล้อมการดำเนินการปัจจุบันและตั้งค่าตัวแปรที่ประกาศด้วย VAR เป็นคุณสมบัติของวัตถุที่ใช้งานอยู่ แต่ในเวลานี้การกำหนดตัวแปรเหล่านี้จะไม่ได้กำหนดและฟังก์ชั่นที่กำหนดไว้ในฟังก์ชั่น อย่างไรก็ตามหากคุณใช้ "eval" รหัสใน "eval" (จริง ๆ แล้วสตริง) ไม่สามารถระบุบริบทของมันล่วงหน้าไม่สามารถแยกวิเคราะห์และปรับให้เหมาะสมล่วงหน้าได้เช่นการดำเนินการที่คอมไพล์ล่วงหน้าไม่สามารถทำได้ ดังนั้นประสิทธิภาพของมันจะลดลงอย่างมาก
ในความเป็นจริงผู้คนไม่ค่อยใช้ Eval ตอนนี้ สิ่งที่ฉันต้องการพูดคุยเกี่ยวกับที่นี่คือสถานการณ์ของ Eval สองประเภท (ฟังก์ชั่นใหม่ {}, settimeout, setInterver)
การคัดลอกรหัสมีดังนี้:
SettimTout ("Alert (1)", 1,000);
SetInterver ("Alert (1)", 1,000);
(ฟังก์ชั่นใหม่ ("Alert (1)")) ();
ประสิทธิภาพการดำเนินการรหัสประเภทข้างต้นจะค่อนข้างต่ำดังนั้นจึงขอแนะนำให้ผ่านวิธีการที่ไม่ระบุชื่อโดยตรงหรือการอ้างอิงถึงวิธีการตั้งถิ่นฐาน
3. หลังจากการปิดเสร็จแล้วตัวแปรที่ไม่ได้อ้างอิงจะถูกปล่อยออกมาอีกต่อไป
การคัดลอกรหัสมีดังนี้:
var f = (function () {
var a = {ชื่อ: "var3"};
var b = ["var1", "var2"];
var c = document.getElementByTagname ("li");
// **** ตัวแปรอื่น ๆ
// *** การดำเนินการบางอย่าง
var res = function () {
การแจ้งเตือน (a.name);
-
Ret Res;
-
ค่าส่งคืนของตัวแปร F ในรหัสด้านบนเป็นวิธีการที่ส่งคืนในการปิดที่ประกอบด้วยฟังก์ชั่นการดำเนินการทันที ตัวแปรนี้ยังคงอ้างอิงถึงตัวแปรทั้งหมด (a, b, c ฯลฯ ) ในการปิดนี้ ดังนั้นตัวแปรทั้งสองนี้จะอยู่ในพื้นที่หน่วยความจำโดยเฉพาะอย่างยิ่งการอ้างอิงถึงองค์ประกอบ DOM จะใช้หน่วยความจำจำนวนมาก เราใช้ค่าของตัวแปร A ใน Res เท่านั้น ดังนั้นเราสามารถปลดปล่อยตัวแปรอื่น ๆ ก่อนที่จะส่งคืน
การคัดลอกรหัสมีดังนี้:
var f = (function () {
var a = {ชื่อ: "var3"};
var b = ["var1", "var2"];
var c = document.getElementByTagname ("li");
// **** ตัวแปรอื่น ๆ
// *** การดำเนินการบางอย่าง
// ปล่อยตัวแปรที่ไม่ได้ใช้อีกต่อไปก่อนที่การปิดจะส่งคืน
b = c = null;
var res = function () {
การแจ้งเตือน (a.name);
-
Ret Res;
-
ประสิทธิภาพของการดำเนินงานของ JS
ในระหว่างกระบวนการพัฒนาเว็บคอขวดของประสิทธิภาพการดำเนินการส่วนหน้ามักจะอยู่ในการดำเนินงาน DOM การดำเนินงาน DOM เป็นสิ่งที่ใช้เวลานานมาก เราจะพยายามบันทึกประสิทธิภาพระหว่างการดำเนินงาน DOM ได้อย่างไร
1. ลด reflow
Reflow คืออะไร?
เมื่อคุณสมบัติของการเปลี่ยนแปลงองค์ประกอบ DOM (เช่นสี) เบราว์เซอร์จะแจ้งการเรนเดอร์เพื่อกำหนดองค์ประกอบที่เกี่ยวข้องใหม่ กระบวนการนี้เรียกว่าทาสีใหม่
หากการเปลี่ยนแปลงเกี่ยวข้องกับเค้าโครงองค์ประกอบ (เช่นความกว้าง) เบราว์เซอร์จะยกเลิกแอตทริบิวต์ดั้งเดิมคำนวณใหม่และส่งผลให้การเรนเดอร์ไปยังองค์ประกอบหน้า กระบวนการนี้เรียกว่า reflow
วิธีลดการรีมอน
ก่อนอื่นลบองค์ประกอบออกจากเอกสารและหลังจากเสร็จสิ้นการปรับเปลี่ยนจากนั้นนำองค์ประกอบกลับไปยังตำแหน่งเดิม (เมื่อการดำเนินการรีโมลจำนวนมากจะดำเนินการในองค์ประกอบที่แน่นอนและองค์ประกอบลูกของมันผลของวิธีการ 1 และ 2 จะชัดเจนมากขึ้น)
ตั้งค่าการแสดงผลขององค์ประกอบเป็น "ไม่มี" และหลังจากเสร็จสิ้นการปรับเปลี่ยนให้แก้ไขการแสดงผลเป็นค่าดั้งเดิม
กำหนดคลาสคลาสเมื่อแก้ไขคุณลักษณะหลายสไตล์แทนการแก้ไขแอตทริบิวต์สไตล์หลายครั้ง (แนะนำโดยนักเรียนบางคน)
ใช้ DocumentFragment เมื่อเพิ่มองค์ประกอบจำนวนมากลงในหน้า
ตัวอย่างเช่น
การคัดลอกรหัสมีดังนี้:
สำหรับ (var i = 0; i <100: i ++) {
var child = docuemnt.createelement ("li");
child.innerhtml = "เด็ก";
document.getElementById ("ผู้ปกครอง"). AppendChild (เด็ก);
-
เมื่อรหัสต้องการการเข้าถึงข้อมูลสถานะหลายอย่างขององค์ประกอบเราสามารถเก็บไว้ในตัวแปรชั่วคราวเมื่อสถานะยังคงไม่เปลี่ยนแปลงซึ่งสามารถหลีกเลี่ยงค่าใช้จ่ายหน่วยความจำที่เกิดจากการเข้าถึงหลายครั้งของ DOM ตัวอย่างทั่วไปคือ:
เมื่อค้นหาองค์ประกอบ DOM ให้พยายามหลีกเลี่ยงองค์ประกอบหน้าข้ามในพื้นที่ขนาดใหญ่ลองใช้ตัวเลือกที่แม่นยำหรือระบุบริบทเพื่อ จำกัด ช่วงการค้นหาโดยใช้ jQuery เป็นตัวอย่าง
ใช้ตัวเลือกการจับคู่แบบฟัซซี่น้อยลง: ตัวอย่างเช่น $ ("[ชื่อ*= '_ fix']"), ใช้ตัวเลือกคอมโพสิตมากขึ้นเช่น ID และค่อยๆ จำกัด ขอบเขต $ ("li.active") ฯลฯ
ระบุบริบท: ตัวอย่างเช่น $ ("#parent .class"), $ (". class", $ el) และอื่น ๆ
4. ใช้การมอบหมายกิจกรรม
สถานการณ์การใช้งาน: รายการที่มีระเบียนจำนวนมาก แต่ละระเบียนจะต้องผูกพันกับการคลิกเหตุการณ์ ฟังก์ชั่นบางอย่างจะถูกนำไปใช้หลังจากคลิกที่เมาส์ การปฏิบัติตามปกติของเราคือการผูกมัดเพื่อฟังเหตุการณ์สำหรับแต่ละระเบียน การปฏิบัตินี้จะนำไปสู่ผู้ฟังเหตุการณ์จำนวนมากในหน้าซึ่งค่อนข้างไม่มีประสิทธิภาพ
หลักการพื้นฐาน: เราทุกคนรู้ว่าเหตุการณ์จะเกิดขึ้นในข้อกำหนดของ DOM นั่นคือเหตุการณ์ขององค์ประกอบใด ๆ จะฟองไปสู่ขั้นตอนบนทีละขั้นตอนตามโครงสร้างของต้นไม้ DOM วัตถุเหตุการณ์ยังให้ Event.target (SRCELEMENT ภายใต้ IE) เพื่อชี้ไปที่แหล่งเหตุการณ์ดังนั้นเราจึงสามารถค้นหาองค์ประกอบดั้งเดิมที่สุดที่กระตุ้นเหตุการณ์แม้ว่าเราจะฟังเหตุการณ์ในองค์ประกอบหลัก นี่คือหลักการพื้นฐานของผู้แทน โดยไม่ต้องกังวลใจเพิ่มเติมตัวอย่างข้างต้น
ขึ้นอยู่กับหลักการของการตรวจสอบเหตุการณ์ที่แนะนำข้างต้นเรามาเขียนใหม่
แน่นอนว่าเราไม่จำเป็นต้องตัดสินแหล่งเหตุการณ์ทุกครั้งเราสามารถนามธรรมและส่งมอบให้กับคลาสเครื่องมือเพื่อให้เสร็จสมบูรณ์ วิธีการแทน () ใน jQuery ใช้ฟังก์ชันนี้
ไวยากรณ์เป็นเหมือน $ (ตัวเลือก) .delegate (childSelector, เหตุการณ์, ข้อมูล, ฟังก์ชั่น) ตัวอย่างเช่น:
การคัดลอกรหัสมีดังนี้:
$ ("div"). Delegate ("ปุ่ม", "คลิก", function () {
$ ("p"). slidetoggle ();
-
คำอธิบายพารามิเตอร์ (ยกมาจาก W3School)
คำอธิบายพารามิเตอร์
จำเป็นต้องมี ChildSelector ระบุว่าองค์ประกอบเด็กอย่างน้อยหนึ่งอย่างของตัวจัดการเหตุการณ์ที่จะแนบ
จำเป็นต้องมีเหตุการณ์ ระบุเหตุการณ์หนึ่งเหตุการณ์ขึ้นไปที่แนบมากับองค์ประกอบ แยกค่าเหตุการณ์หลายรายการตามช่องว่าง ต้องเป็นเหตุการณ์ที่ถูกต้อง
ข้อมูลเป็นทางเลือก ระบุข้อมูลเพิ่มเติมที่ส่งผ่านไปยังฟังก์ชั่น
ต้องการฟังก์ชั่น ระบุฟังก์ชั่นที่ทำงานเมื่อเหตุการณ์เกิดขึ้น
เคล็ดลับ: ข้อดีอีกประการหนึ่งของการมอบหมายงานคือแม้แต่เหตุการณ์ที่เกิดขึ้นกับองค์ประกอบที่เพิ่มขึ้นอย่างมีชีวิตชีวาหลังจากการเชื่อมโยงเหตุการณ์สามารถได้ยินได้เพื่อที่คุณจะได้ไม่ต้องผูกเหตุการณ์ในแต่ละครั้งที่คุณเพิ่มองค์ประกอบแบบไดนามิกลงในหน้า