تېر کال د ۲۰۱۷ کال د فبرورۍ په ۲مه، این ټیلر په CodeInWP کې یوه مقاله ولیکله: ۱۲ هغه شیان چې موږ یې په ۲۰۱۷ کې د ورډپریس پاڼې جوړوونکو څخه د لیدلو هیله لرو + چا لا دمخه سم کړي دي. موږ له یو کال څخه زیات وخت راهیسې په پرله پسې ډول د Page Builder Sandwich د ښه کولو هڅه کوو: موږ خپله څېړنه کوو، د خپلو پیرودونکو خبرو ته غوږ نیسو، نو موږ فکر کاوه چې Page Builder Sandwich به د CodeInWP د “چا دا سم کړي دي” مقالې ته لاره ومومي. مګر موږ د کمزورې کارکردګۍ له امله ونهشو کړای.
نو موږ له این څخه په دې اړه وپوښتل، او هغې په ځواب کې وویل:
…ما له وړیا نسخې سره یو څه کار وکړ. دا خورا هیله بښونکې ده: ډېر ماډلونه، خورا اسانه او روان کارن انټرفیس (UI)، د WYSIWYG عالي تجربه، هر څه په اسانۍ سره کش او ځای پر ځای کېږي. په هرصورت، کله چې ما په پاڼه کې شاوخوا ۱۰ ماډلونه لرل، د سمون د ټیټ سرعت له امله ورسره د کار دوام ستونزمن شو…
نو د هغې په وینا، Page Builder Sandwich د کارکردګۍ ستونزې لري. او له هغه ځایه چې موږ تل نظرونو ته غوږ نیسو، موږ دا وڅېړله.
د کارکردګۍ ازمویل
موږ د PBS کارکردګۍ د چک کولو لپاره یوې لارې ته اړتیا درلوده؛ له هغه ځایه چې PBS ډېری د جاواسکریپټ له لارې په براوزر کې چلیږي، د کروم د مهالوېش پروفایلر (Chrome’s Timeline profiler) د دې کار لپاره سم اوزار و. د مهالوېش پروفایلر کولی شي وپیژني او اندازه کړي چې د چلېدو په وخت کې په یوه ویب پاڼه کې کومې پروسې ترسره کیږي، چې دا د سرعت د خنډونو د موندلو لپاره خورا غوره دی.
موږ فکر وکړ چې موږ باید لومړی تر ټولو ساده ګامونه و ازمایو – د موږک (ماوس) کرسر په ګڼو عناصرو او قطارونو تېرول. ساده ده، سمه ده؟ موږ باوري وو چې موږ به د داسې ساده کار سره د کارکردګۍ ستونزو سره مخ نه شو. له بده مرغه، موږ تېروتي وو.
کله چې موږ د ریکارډ تڼۍ کېکاږله، موږ شاوخوا ۲ ثانیې ماوس په سکرین وڅرخاوه، او بیا مو د درولو (stop) تڼۍ کېکاږله. دلته د پروفایلر د پایلې مهالوېش دی:
او وګورئ! دا د کارکردګۍ له خنډونو ډک دی!
په ګراف کې ډېر شیان پیښیږي، مګر تر ټولو ښکاره ستونزه دا ده چې په هغه کې ډېرې ارغواني ساحې شتون لري (چې باید داسې نه وای). پر دې سربېره، دا ارغواني ساحې په څرګند ډول خورا پراخې دي، او داسې ښکاري چې ټول د ګراف تر لوړې کچې رسېږي. تاسو به دا هم وګورئ چې ګراف تل ډک هم دی، او دا ارغواني سیمې تقریبا هېڅکله صفر ته نه راټیټیږي. داسې ښکاري چې براوزر تل په یو څه بوخت وي، او تقریبا هېڅکله آرام نه کوي.
خو دا ټولې ارغواني ساحې په حقیقت کې څه معنی لري؟
پروفایلر دومره مهربانه و چې موږ ته یې وویل چې دوی ته reflows ویل کیږي. دلته د ګوګل ډیولپر سایټ:
ریفلو (Reflow) په سند کې د عناصرو د موقعیتونو او جیومیټري د بیا محاسبې لپاره د ویب براوزر د پروسې نوم دی.. ریفلو په براوزر کې د کارونکي مخنیوی کوونکی عملیات دی.
نو دا پدې مانا ده چې په PBS کې ستاسو د ماوس ګرځول د ریفلوګانو یو ډېر لوی مقدار رامنځته کوي. تر دې بدتره دا ده چې هر ریفلو براوزر د یوې شیبې لپاره ودروي ترڅو خپل حسابونه پای ته ورسوي. ډېر ریفلوګانې د براوزر د ډېرو ځنډونو معنی لري، او تجربه نوره هم بېثباته (janky) کیږي. په ساده اصطلاحاتو کې، ډېرې ارغواني ساحې = بد حالت.
نو معلومه شوه چې این سمه وه: موږ په رښتیا هم د کارکردګۍ یو لوی خنډ لرو، نو زموږ ټیم سمدلاسه کار پیل کړ ترڅو دا ژر تر ژره حل کړي.
زموږ د Reflow / Jank ستونزې حل کول
تر هر څه وړاندې، موږ اړتیا درلوده چې یو څه څېړنه وکړو ترڅو معلومه کړو چې په لومړي سر کې د دې ریفلو لامل څه دی. موږ وموندله چې ظاهراً، په جاواسکریپټ کې ډېر عام شیان کولی شي براوزر ریفلو رامنځته کولو ته وهڅوي.
تقریبا هر هغه فنکشن چې تاسو یې د DOM عنصر د بر، لوړوالي یا موقعیت د ترلاسه کولو لپاره کارولی شئ کولی شي ریفلو پیل کړي. پاول آیرش د ټولو هغو ځانګړتیاوو او فنکشنونو یو پراخ لست ولیکه په جاواسکریپټ کې چې کولی شي دا کار وکړي. بد خبر دا دی چې Page Builder Sandwich له دې ځانګړتیاوو او فنکشنونو څخه ډېر کار اخلي، چې دا ټول د ریفلو لامل کیږي:
- elem.getBoundingClientRect()
- window.getComputedStyle()
- window.scrollY
- او نور ډېر څه…
۱ حل: د درندو Reflow پروسو کیش کول
تر ټولو ښکاره حل دا دی چې دا ځانګړتیاوې او فنکشنونه ونه کارول شي. خو بیا هم، PBS په دوی خورا ډېر تکیه کوي او موږ له هغوی پرته نشو کولی.
هغه حل چې موږ ته پاتې دی دا دی چې دغو فنکشنونو ته غوښتنې تر ممکنه حده کمې کړو. دلته سخته برخه دا وه چې موږ دا ځانګړتیاوې او فنکشنونه د PBS په مختلفو برخو کې ډېر ځله کارولي وو، او ډېری وخت، موږ دوی په ورته DOM عنصر کې څو ځله کارولي وو. د دې د حل لپاره، موږ د هرې ستونزمنې ځانګړتیا/فنکشن لپاره خپل د کیش کولو میکانیزم جوړ کړ.
د بېلګې په توګه، د getBoundingClientRect فنکشن موږ ته د DOM عنصر اوسني پورتني، کیڼ، بر، لوړوالي، ښي، او لاندې پکسل اندازه راکوي. موږ دا فنکشن هر وخت په PBS کې د عنصر د باندنیو کرښو د رسمولو ځای محاسبه کولو لپاره کاروو. دلته د کیش کولو فنکشن دی چې موږ د دې لپاره جوړ کړی:
// کیش: زموږ کلائنټ رېکټونه دلته ساتل کېږي، موږ کولی شو دا وروسته د هغوی د پاکولو لپاره وکاروو.
var elemsWithBoundingRects = [];
window.pbsGetBoundingClientRect = function( element ) {
// وګورئ چې ایا موږ مخکې له مخکې کلائنټ رېکټ ترلاسه کړی که نه.
if ( ! element._boundingClientRect ) {
// که نه، هغه ترلاسه کړئ او د راتلونکي کارونې لپاره یې وساتئ.
element._boundingClientRect = element.getBoundingClientRect();
elemsWithBoundingRects.push( element );
}
return element._boundingClientRect;
};
د getBoundingClientRect د غوښتلو پر ځای، موږ اوس pbsGetBoundingClientRect وکاراوه. اوس هرکله چې د کلائنټ رېکټ پوښتنه کیږي، موږ دا ارزښت د راتلونکي مرجع لپاره ساتو، پدې توګه د ریفلو محرکاتو شمېر محدودوو.
موږ یوې لارې ته هم اړتیا درلوده چې کیش پاک کړو کله چې ساتل شوي کلائنټ رېکټونه باطل شي. د ساتل شوي کلائنټ رېکټ ارزښتونه هغه وخت بدلیږي کله چې کاروونکی پاڼه سکرول کوي یا په سکرین کې عناصر اضافه کوي/بدلوي/لرې کوي. نو موږ د کیش پاکولو یو فنکشن جوړ کړ چې موږ کولی شو هرکله چې د کلائنټ رېکټ نویو ارزښتونو ته اړتیا لرو ورته غږ وکړو:
var clearClientRects = function() {
var i;
for ( i = 0; i < elemsWithBoundingRects.length; i++ ) {
if ( elemsWithBoundingRects[ i ] ) {
elemsWithBoundingRects[ i ]._boundingClientRect = null;
}
}
elemsWithBoundingRects = [];
};
موږ د نورو هغو ګرانو فنکشنونو د غوښتنو لپاره هم دا ورته کیشینګ میکانیزم وکاراوه چې موږ معمولا کاروو.
۲ حل: د FastDom په کارولو سره د لوستلو او لیکلو یوځای ګروپ کول
د ۱ حل پلي کولو د PBS کارکردګي زیاته کړه، مګر دا کافي نه وه.
په ګوګل کې د یو څه نور لټون وروسته، موږ د ویلسن پېج د ‘layout thrashing’ مخنیوي په اړه یوې مقالې سره مخ شو. ویلسن وايي:
د لېآوټ ټکر یا ترشینګ (ریفلو) هغه وخت رامنځته کیږي کله چې جاواسکریپټ په پرله پسې او چټک ډول له DOM څخه ولیکي، او بیا ولولي، چې دا څو ځله د سند د ریفلو لامل کیږي.
ظاهراً، دا کافي نده چې ځانګړو ریفلو-محرک کوونکو ځانګړتیاوو او فنکشنونو ته خپلې غوښتنې محدودې کړئ. کله چې تاسو په DOM باندې څو پرله پسې “لوستل” او “لیکل” ترسره کوئ، دا د براوزر ریفلو هم محرک کوي. دلته یو عادي حالت دی، مستقیماً د ویلسن له سایټ څخه:
// لوستل var h1 = element1.clientHeight; // لیکل (لېآوټ باطلوي) element1.style.height = (h1 * 2) + 'px'; // لوستل (ریفلو هڅوي) var h2 = element2.clientHeight; // لیکل (لېآوټ باطلوي) element2.style.height = (h2 * 2) + 'px'; // لوستل (ریفلو هڅوي) var h3 = element3.clientHeight; // لیکل (لېآوټ باطلوي) element3.style.height = (h3 * 2) + 'px'; // د فریم په پای کې د سند ریفلو ترسره کیږي
پورتنۍ بېلګه ۳ ریفلوګانې هڅوي ځکه چې د ټولې پاڼې ابعاد د لیکلو وروسته باطل کیږي. د دې لپاره وړاندیز شوی حل دا دی چې کوډ له سره تنظیم شي ترڅو ټول لوستل او لیکل سره یوځای راټول شي ترڅو ټوله پروسه یوازې ۱ د براوزر ریفلو رامنځته کړي:
// لوستل var h1 = element1.clientHeight; var h2 = element2.clientHeight; var h3 = element3.clientHeight; // لیکل (لېآوټ باطلوي) element1.style.height = (h1 * 2) + 'px'; element2.style.height = (h2 * 2) + 'px'; element3.style.height = (h3 * 2) + 'px'; // د فریم په پای کې د سند ریفلو ترسره کیږي
پورتنۍ ټوټه کوډ د ستونزې حل کول اسانه ښیي. مګر په حقیقت کې، په PBS کې، د ریفلو-محرک کوونکو شیانو لوستل او لیکل د PBS د ژوند په دوران کې په ډېرو مختلفو ځایونو او بېلابېلو وختونو کې پیښیږي. د زرګونو کرښو جاواسکریپټ کوډ بیا تنظیم کول امکان نلري.
زموږ په نېکمرغۍ، ویلسن په خپله مقاله کې یو حل هم وړاندې کړ. هغه د دې لوستلو او لیکلو د یوځای راټولولو کې د مرستې لپاره یو کوچنی ګټور سکریپټ جوړ کړ، چې ورته FastDom ویل کیږي.
دلته د Page Builder Sandwich څخه ځینې کوډونه دي چې FastDom کاروي او زموږ پورتنی ۱ حل هم پکې شامل دی:
// د نورو تارونو څخه لوستل سره یوځای کړئ.
fastdom.measure( function() {
// زموږ کیش شوی کلائنټ رېکټ وکاروئ.
var rect = window.pbsGetBoundingClientRect( elem );
// د نورو تارونو څخه لیکل سره یوځای کړئ.
fastdom.mutate( function() {
elem.style.top = ( rect.top + window.pbsScrollY() ) + 'px';
elem.style.height = rect.height + 'px';
elem.style.left = rect.left + 'px';
elem.style.width = rect.width + 'px';
}.bind( this ) );
}.bind( this ) );
هغه څه چې FastDom یې کوي دا دي چې دا ټولې د fastdom.measure غوښتنې او ټولې د fastdom.mutate غوښتنې سره ګروپ کوي او په اسینکرونس ډول یې پلي کوي، چې په مؤثره توګه ټول لوستل او لیکل سره یوځای کوي ترڅو په براوزر کې ټول ریفلوګانې کمې کړي.
۳ حل: د سټایل توکو ته لاسرسی دروند او لګښتمن دی
موږ د jsPerf په مرسته دا هم وموندله چې د سټایل ترلاسه کولو ځینې فنکشنونه د نورو په پرتله ګړندي وو.
په PBS کې، موږ معمولا اړتیا لرو چې د یو عنصر د ځانګړي سټایل اوسنی ارزښت ترلاسه کړو. د بېلګې په توګه، موږ په نورمال ډول د پورتنۍ حاشیې ترلاسه کولو لپاره دا کاروو:
var styles = window.getComputedStyle( elem ); var marginTop = styles.marginTop;
مګر، موږ وموندله چې د دې کار کول خورا ګړندي دي:
var marginTop = elem.style.marginTop;
په هرصورت، elem.style.marginTop او getComputedStyle ډېر توپیر لري. لومړنی یوازې موږ ته د عنصر انلاین سټایل راکوي، او د سټایل شیټونو حساب نه کوي؛ او دوهم یې دواړه انلاین سټایلونه او سټایل شیټونه په پام کې نیسي.
نور څه دا چې حتی کله چې د getComputedStyle پایله کیش شوې هم وه، دا بیا هم واقعیا سسته وه. لکه څنګه چې معلومه شوه، پخپله سټایل آبجیکټ ته لاسرسی سسته پروسه ده.
زموږ په نېکمرغۍ، PBS عناصرو ته انلاین سټایلونه ورزیاتوي، او له هغه ځایه چې انلاین سټایلونه د سټایل شیټونو په پرتله (ډېری وخت) لومړیتوب لري، داسې حالتونه به وي چې د انلاین سټایل ارزښت ترلاسه کول به پکې کافي وي. نو که موږ پورته دوه میتودونه سره یوځای کړو، موږ کولی شو ډېر ګړندی چلېدونکی کوډ رامنځته کړو:
var marginTop = elem.style.marginTop;
if ( ! marginTop ) {
var styles = window.getComputedStyle( elem );
marginTop = styles.marginTop;
}
د کوډ د ښه والي پایلې
زموږ پورته ۳ حلونو ډېرې څېړنې، ازموینې او عملي تطبیق ته اړتیا درلوده (او زموږ د فونټونو د ځانګړتیا خپرېدل یې وځنډول)، مګر په پای کې دا ټول ارزښت درلود.
بېرته زموږ لومړنۍ ازموینې ته لاړ شو چې د ۲ ثانیو لپاره په سکرین د خپل ماوس خوځول و. دلته پخوانی بدرنګه/بېثباته مهالوېش دی:
او دلته هغه څه دي چې زموږ نوی مهالوېش د کارکردګۍ له ښه والي وروسته ورته ښکاري:
لکه څنګه چې تاسو لیدلی شئ، په ګراف کې لږ ارغواني شیان شتون لري. او د براوزر لخوا د ترسره کیدونکو پروسو په مقدار کې د پام وړ توپیر شتون لري. لاندې مستطیل ډوله شیان هم نري دي، چې پدې مانا ده چې پروسې د پخوا په پرتله ګړندۍ پرمخ وړل کیږي.
که تاسو په پخوانیو او نویو ګرافونو کې د لوړو/پراخو ارغواني سیمو مقدار پرتله کړئ، موږ د کارکردګۍ په برخه کې د پام وړ ۲۰۰٪ زیاتوالی وینو! موږ په ټوله کچه د کارکردګۍ زیاتوالی هم وینو. هیڅ بد ندی!
پایلې او زده کړې
رښتیا ووایم، موږ فکر نه کاوه چې PBS د دې مسلې تر راپورته کولو مخکې د کارکردګۍ ستونزې لرلې. په ځانګړي توګه له دې امله چې موږ د پراختیا لپاره ځانګړي قوي کمپیوټرونه کارول او د کارکردګۍ خنډونه دومره ښکاره نه وو. شاته په کتلو سره، د کارکردګۍ چک کول باید یو له مهمو لومړیتوبونو څخه وای. مګر لږترلږه اوس، د 4.3 نسخې پورې، د دې پاملرنه شوې ده.
د هغو کسانو لپاره چې غواړي د خپل ورډپریس پلگ ان کارکردګي ښه کړي، په ځانګړي توګه که تاسو دروند جاواسکریپټ هم کاروئ، له دې تجربې څخه زما ترلاسه شوي درسونه دلته دي:
- هغو ملکیتونو/فنکشنونو ته خپلې غوښتنې محدودې/کیش کړئ چې ریفلو رامنځته کوي. دا د لارښود په توګه وکاروئ: څه شی layout/reflow ته اړ کوي. بشپړ لیست.
- د DOM سټایلونو لپاره “لوستل” او “لیکل” سره یوځای کړئ. د دې لپاره چې دا ستاسو لپاره ترسره کړي FastDom وکاروئ.
- د کروم د مهالوېش پروفایلر وکاروئ، او ډاډ ترلاسه کړئ چې تر ممکنه حده لږ ریفلوګانې (ارغواني توکي) لرئ.