ባለፈው የካቲት 2 ቀን 2017 አን ቴይለር በCodeInWP ላይ 12 Things We Need to See From WordPress Page Builders in 2017 + Who Already Gets It Right የተሰኘውን ጽሁፍ ጽፋ ነበር። Page Builder Sandwichን ከአንድ አመት በላይ ያለማቋረጥ እያሻሻልን ቆይተናል፡ ጥናት እናደርጋለን፣ ደንበኞቻችንን እናዳምጣለን፣ ስለዚህ Page Builder Sandwich በCodeInWP “Who Got it Right” ጽሁፍ ውስጥ ይካተታል ብለን አስበን ነበር። ይሁን እንጂ በአፈፃፀም ችግር ምክንያት አልተካተትንም።
ስለዚህ አንን ስለዚህ ጉዳይ ጠየቅናት፣ እሷም እንዲህ ስትል መለሰች፡-
…የነጻውን እትም ትንሽ ሞክሬዋለሁ። ብዙ ተስፋዎችን ያሳያል፡ ብዙ ሞጁሎች፣ በጣም ግልጽ የሆነ UI፣ ምርጥ የWYSIWYG ተሞክሮ፣ ሁሉም ነገር በቀላሉ ይጎተታል። ሆኖም በገጹ ላይ ወደ 10 የሚጠጉ ሞጁሎች ሲኖሩኝ፣ በአነስተኛ የአርትዖት ፍጥነት ምክንያት መስራቱን መቀጠል ከባድ ሆነ…
እንደ እርሷ አባባል Page Builder Sandwich የአፈጻጸም ችግሮች አሉበት። እኛ ደግሞ ሁልጊዜ ግብረመልስን ስለምናዳምጥ፣ ጉዳዩን መርምረነዋል።
አፈጻጸሙን መሞከር
የPBSን አፈጻጸም የምንፈትሽበት መንገድ ያስፈልገን ነበር፤ PBS በአብዛኛው በጃቫስክሪፕት በኩል በአሳሽ ላይ ስለሚሰራ፣ የChrome የTimeline ፕሮፋይለር ለስራው ትክክለኛው መሳሪያ ነበር። የTimeline ፕሮፋይለር በስራ ወቅት በድረ-ገጽ ውስጥ የትኞቹ ሂደቶች እየተከናወኑ እንዳሉ መለየት እና መለካት ይችላል፣ ይህም የፍጥነት እንቅፋቶችን ለማግኘት ፍጹም ነው።
በመጀመሪያ በጣም ቀላል የሆኑትን እርምጃዎች መሞከር አለብን ብለን አሰብን – ማውሳችንን በበርካታ አካላት እና ረድፎች ላይ ማንቀሳቀስ። ቀላል ነው አይደል? እንደዚህ ባለ ቀላል ነገር ላይ የአፈጻጸም ችግሮች እንደማያጋጥሙን እርግጠኞች ነበርን። በሚያሳዝን ሁኔታ፣ ተሳስተን ነበር።
የመቅረጫ ቁልፉን ከተጫንን በኋላ ማውሱን በማያ ገጹ ላይ ለ2 ሰከንድ ያህል አንቀሳቅሰን የማቆሚያ ቁልፉን ተጫንን። ከፕሮፋይለሩ የተገኘው የጊዜ መስመር ይኸውና፡
እዩት እንግዲህ። በአፈጻጸም እክሎች የተሞላ ነው!
በግራፉ ውስጥ ብዙ ነገሮች እየተከሰቱ ነው፣ ነገር ግን በጣም ግልጽ የሆነው ችግር ብዙ የወይን ጠጅ (purple) ቦታዎች በውስጡ መኖራቸው ነው (ይህ መሆን የለበትም)። በዛ ላይ እነዚህ የወይን ጠጅ ቦታዎች በሚታይ ሁኔታ በጣም ሰፊ ናቸው፣ እና ሁሉም የግራፉን ጫፍ የነኩ ይመስላሉ። እንዲሁም ግራፉ ሁል ጊዜ ሙሉ እንደሆነ እና የወይን ጠጅ ቦታዎች ፈጽሞ ወደ ዜሮ እንደማይወርዱ ያስተውላሉ። አሳሹ ሁል ጊዜ የሆነ ነገር በመስራት የተጠመደ ይመስላል፣ እና ፈጽሞ አያርፍም።
ግን እነዚህ ሁሉ የወይን ጠጅ ቦታዎች በእርግጥ ምን ማለት ናቸው?
ፕሮፋይለሩ እነሱ reflows እንደሚባሉ ደግነቱ ነግሮናል። reflow ምን እንደሆነ ከየGoogle Developer ድረ-ገጽ:
Reflow በሰነዱ ውስጥ ያሉትን ንጥረ ነገሮች አቀማመጥ እና ጂኦሜትሪ እንደገና ለማስላት የሚደረግ የድር አሳሽ ሂደት ስም ነው.. reflow በአሳሹ ውስጥ የተጠቃሚን እንቅስቃሴ የሚያግድ ተግባር ነው።
ስለዚህ ይህ ማለት በPBS ውስጥ ማውስዎን ማንቀሳቀስ በርካታ reflowsን ያስነሳል ማለት ነው። የከፋው ደግሞ እያንዳንዱ reflow ስሌቱን ማጠናቀቅ እንዲችል አሳሹን ለጊዜው ያቆመዋል። ተጨማሪ reflows ማለት ተጨማሪ የአሳሽ መቆራረጥ ማለት ነው፣ እና ልምዱ ይበልጥ የተቆራረጠ (janky) ይሆናል። በቀላል አነጋገር፣ ብዙ የወይን ጠጅ ቦታዎች = መጥፎ።
ስለዚህ አን ትክክል ሆና ተገኘች፡ ትልቅ የአፈጻጸም ማነቆ አለብን፣ ስለዚህ ቡድናችን ወዲያውኑ ለማስተካከል ወደ ስራ ገባ።
የእኛን የReflow / Jank ችግር ማስተካከል
ከምንም ነገር በፊት ይህንን reflow በመጀመሪያ ደረጃ ምን እንደሚያመጣው ለማወቅ የተወሰነ ምርምር ማድረግ አስፈልጎን ነበር። እንዳገኘነው ከሆነ፣ በጃቫስክሪፕት ውስጥ ያሉ ብዙ የተለመዱ ነገሮች አሳሹ reflow እንዲፈጥር ሊያነሳሱት ይችላሉ።
የDOM አካልን ስፋት፣ ቁመት ወይም አቀማመጥ ለማግኘት ሊጠቀሙበት የሚችሉት ማንኛውም ተግባር ማለት ይቻላል reflow ሊያስነሳ ይችላል። ፖል አይሪሽ ይህንን ሊያደርጉ የሚችሉትን ሁሉንም ንብረቶች እና ተግባራት በጃቫስክሪፕት ውስጥ ዝርዝር ዝርዝር ጽፏል። መጥፎው ዜና Page Builder Sandwich እነዚህን በርካታ ንብረቶች እና ተግባራት ይጠቀማል፣ ሁሉም reflow ያስከትላሉ፡
- elem.getBoundingClientRect()
- window.getComputedStyle()
- window.scrollY
- እና ሌሎች ብዙ…
ማስተካከያ #1፡ አድካሚ የሆኑ የReflow ሂደቶችን መሸጎጥ (Caching)
በጣም ግልጽ የሆነው መፍትሄ እነዚያን ንብረቶች እና ተግባራት አለመጠቀም ነው። ነገር ግን፣ PBS በእነሱ ላይ በእጅጉ ይተማመናል እና ያለነሱ መስራት አንችልም።
የቀረን መፍትሄ ወደ እነዚያ ተግባራት የሚደረጉ ጥሪዎችን በተቻለ መጠን መቀነስ ነው። እዚህ ላይ አስቸጋሪው ነገር እነዚያን ንብረቶች እና ተግባራት በተለያዩ የPBS ክፍሎች ውስጥ ብዙ ጊዜ መጠቀማችን ነው፣ እና አብዛኛውን ጊዜ ደግሞ በተመሳሳይ የDOM አካል ላይ ብዙ ጊዜ እንጠቀምባቸዋለን። ይህንን ለማስተካከል ለእያንዳንዱ ችግር ፈጣሪ ንብረት/ተግባር የራሳችንን የመሸጎጫ (caching) ዘዴ ፈጠርን።
ለምሳሌ፣ የgetBoundingClientRect ተግባር የDOM አካል የአሁኑን የላይኛው፣ የግራ፣ የስፋት፣ የቁመት፣ የቀኝ እና የታችኛውን የፒክሰል መለኪያዎች ይሰጠናል። በPBS ውስጥ የንጥረ ነገር ገጽታዎችን የት መሳል እንዳለብን ለማስላት ሁልጊዜ ይህንን ተግባር እንጠቀማለን። ለዚህ የፈጠርነው የመሸጎጫ ተግባር ይኸውና፡
// Cache: Our client rects are kept here, we can use this to clear them later.
var elemsWithBoundingRects = [];
window.pbsGetBoundingClientRect = function( element ) {
// Check if we already got the client rect before.
if ( ! element._boundingClientRect ) {
// If not, get it then store it for future use.
element._boundingClientRect = element.getBoundingClientRect();
elemsWithBoundingRects.push( element );
}
return element._boundingClientRect;
};
getBoundingClientRectን ከመጥራት ይልቅ አሁን pbsGetBoundingClientRectን ተጠቀምን። አሁን client rect በተጠየቀ ቁጥር ያንን እሴት ለወደፊት ማጣቀሻ እናከማቻለን፣ በዚህም የreflow ቀስቅሴዎችን ቁጥር እንገድባለን።
እንዲሁም የተከማቹት client rects ዋጋ ሲያጡ መሸጎጫውን የምናጸዳበት መንገድ ያስፈልገን ነበር። ተጠቃሚው ገጹን ሲያንሸራትት ወይም በስክሪኑ ላይ ያሉ ንጥረ ነገሮችን ሲጨምር/ሲቀይር/ሲያስወግድ የተከማቸው client rect እሴቶች ይቀየራሉ። ስለዚህ አዲስ የclient rect እሴቶች በሚያስፈልጉን ጊዜ ሁሉ ልንጠራው የምንችለውን የመሸጎጫ ማጽጃ ተግባር ፈጠርን፡
var clearClientRects = function() {
var i;
for ( i = 0; i < elemsWithBoundingRects.length; i++ ) {
if ( elemsWithBoundingRects[ i ] ) {
elemsWithBoundingRects[ i ]._boundingClientRect = null;
}
}
elemsWithBoundingRects = [];
};
ይህንኑ የመሸጎጫ ዘዴ በብዛት ለምንጠቀምባቸው ሌሎች አድካሚ የተግባር ጥሪዎችም አድርገናል።
ማስተካከያ #2፡ FastDomን በመጠቀም ንባቦችን እና ጽሁፎችን በአንድ ላይ ማቧደን
ማስተካከያ #1ን መተግበር የPBSን አፈጻጸም ጨምሯል፣ ግን በቂ አልነበረም።
ትንሽ ተጨማሪ ጉግል ስናደርግ፣ በዊልሰን ፔጅ የተጻፈውን Preventing ‘layout thrashing’ የሚለውን ጽሁፍ አገኘን። ዊልሰን እንዲህ ይላል፡-
Layout Thrashing (reflow) የሚከሰተው ጃቫስክሪፕት በDOM ላይ በተደጋጋሚ ሲጽፍ እና ሲያነብ ሲሆን ይህም የሰነድ reflows ያስከትላል።
እንደሚታየው፣ ወደ ተወሰኑ reflow-ቀስቃሽ ንብረቶች እና ተግባራት ጥሪዎችዎን መገደብ በቂ አይደለም። በDOM ላይ ተከታታይ የሆኑ በርካታ “ንባቦችን” እና “ጽሁፎችን” ሲያከናውኑ፣ እሱም እንዲሁ የአሳሽ reflowን ያስነሳል። ከዊልሰን ድረ-ገጽ በቀጥታ የተወሰደ የተለመደ ሁኔታ ይኸውና፡
// Read var h1 = element1.clientHeight; // Write (invalidates layout) element1.style.height = (h1 * 2) + 'px'; // Read (triggers reflow) var h2 = element2.clientHeight; // Write (invalidates layout) element2.style.height = (h2 * 2) + 'px'; // Read (triggers reflow) var h3 = element3.clientHeight; // Write (invalidates layout) element3.style.height = (h3 * 2) + 'px'; // Document reflows at end of frame
ከላይ ያለው ምሳሌ 3 reflowsን ያስነሳል ምክንያቱም ከጽሁፍ በኋላ የሙሉ ገጹ ልኬቶች ዋጋ ስለሚያጡ ነው። ለዚህ የተጠቆመው መፍትሄ ሙሉው ነገር 1 የአሳሽ reflow ብቻ እንዲያስነሳ ኮዱን በድጋሚ በማስተካከል ሁሉንም ንባቦች እና ጽሁፎች በአንድ ላይ ማሰባሰብ ነው፡
// Read var h1 = element1.clientHeight; var h2 = element2.clientHeight; var h3 = element3.clientHeight; // Write (invalidates layout) element1.style.height = (h1 * 2) + 'px'; element2.style.height = (h2 * 2) + 'px'; element3.style.height = (h3 * 2) + 'px'; // Document reflows at end of frame
ከላይ ያለው አጭር ኮድ ችግሩን ማስተካከል ቀላል ያስመስለዋል። ነገር ግን በተጨባጭ፣ በPBS ውስጥ፣ reflow-ቀስቃሽ ነገሮችን ማንበብ እና መጻፍ በPBS የህይወት ዑደት ውስጥ በተለያዩ ጊዜያት በብዙ የተለያዩ ቦታዎች ይከሰታል። በሺዎች የሚቆጠሩ የጃቫስክሪፕት ኮድ መስመሮችን እንደገና ማደራጀት የሚቻል አይደለም።
ለእኛ እድል ሆኖ፣ ዊልሰን በጽሁፉ ውስጥ መፍትሄም ሰጥቷል። እነዚያን ንባቦች እና ጽሁፎች አንድ ላይ ለማሰባሰብ የሚረዳ FastDom የሚባል አነስተኛ የፍጆታ ስክሪፕት ፈጠረ።
FastDomን የሚጠቀም እና ከላይ ያለውን ማስተካከያ #1ንም የሚያካትት ከPage Builder Sandwich የተወሰደ አንዳንድ ኮድ ይኸውና፡
// Bunch together the reads from other threads.
fastdom.measure( function() {
// Use our cached client rect.
var rect = window.pbsGetBoundingClientRect( elem );
// Bunch together the writes from other threads.
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 ጥሪዎች በአንድ ላይ ማቧደን እና ባልተመሳሰለ መልኩ (asynchronously) ማስኬድ ነው፣ ይህም በአሳሹ ውስጥ ያሉትን ሁሉንም reflows ለመቀነስ ሁሉንም ንባቦች እና ጽሁፎች በብቃት በአንድ ላይ ያሰባስባል።
ማስተካከያ #3፡ የስታይል ነገሮችን (Style Objects) መድረስ አድካሚ ነው
በjsPerf እገዛ አንዳንድ ስታይል-አግኚ ተግባራት ከሌሎቹ ፈጣን መሆናቸውን አውቀናል።
በPBS ውስጥ፣ አብዛኛውን ጊዜ የአንድን አካል የተወሰነ ስታይል የአሁኑን ዋጋ ማግኘት አለብን። ለምሳሌ፣ የላይኛውን ህዳግ (top margin) ለማግኘት በተለምዶ ይህንን እንጠቀማለን፡
var styles = window.getComputedStyle( elem ); var marginTop = styles.marginTop;
ነገር ግን፣ ይህንን ማድረግ በጣም ፈጣን መሆኑን ደርሰንበታል፡
var marginTop = elem.style.marginTop;
ሆኖም ግን፣ elem.style.marginTop እና getComputedStyle በጣም የተለያዩ ናቸው። የመጀመሪያው የንጥረ ነገሩን ውስጠ-መስመር ስታይል (inline styling) ብቻ ይሰጠናል፣ እና ማንኛውንም የስታይል ሉሆችን (stylesheets) ከግምት ውስጥ አያስገባም፤ ሁለተኛው ደግሞ ውስጠ-መስመር ስታይሎችንም ሆነ የስታይል ሉሆችን ግምት ውስጥ ያስገባል።
ከዚህም በላይ የgetComputedStyle ውጤት በተሸጎጠ ጊዜ እንኳን አሁንም በጣም ቀርፋፋ ነበር። እንዳየነው ከሆነ፣ የስታይል እቃውን ራሱ መድረስ ቀርፋፋው ሂደት ነው።
ለእኛ እድል ሆኖ፣ PBS ውስጠ-መስመር ስታይሎችን ወደ አካላት ያክላል፣ እና ውስጠ-መስመር ስታይሎች ከስታይል ሉሆች ይልቅ (ብዙውን ጊዜ) ቅድሚያ ስለሚወስዱ፣ የውስጠ-መስመር ስታይል እሴትን ማግኘት በቂ የሚሆንባቸው አጋጣሚዎች ይኖራሉ። ስለዚህ ከላይ ያሉትን ሁለት ዘዴዎች ካጣመርን በጣም ፈጣን የሆነ የስራ ማስኬጃ ኮድ ይዘን መምጣት እንችላለን፡
var marginTop = elem.style.marginTop;
if ( ! marginTop ) {
var styles = window.getComputedStyle( elem );
marginTop = styles.marginTop;
}
የኮድ ማሻሻያ ውጤቶች
ከላይ ያሉት 3 ማስተካከያዎቻችን ብዙ ምርምር፣ ሙከራ እና ትክክለኛ አተገባበርን ወስደዋል (እና የFonts ባህሪያችን እንዳይለቀቅ አዘግይተውታል)፣ በመጨረሻ ግን ሙሉ በሙሉ ዋጋ ነበረው።
ማውስዎን በማያ ገጹ ላይ ለ2 ሰከንድ ወደ ማንቀሳቀስ የመጀመሪያ ሙከራችን ስንመለስ። የድሮው አስቀያሚ/የተቆራረጠ የጊዜ መስመር ይኸውና፡
እና ከአፈጻጸም ማሻሻያዎች በኋላ አዲሱ የጊዜ መስመራችን ምን እንደሚመስል ይኸውና፡
እንደሚመለከቱት፣ በግራፉ ውስጥ አነስተኛ የወይን ጠጅ ነገሮች አሉ። እና በአሳሹ በሚከናወኑ ሂደቶች መጠን ላይ የሚታይ ልዩነት አለ። ከታች ያሉት አራት ማዕዘን ቅርጽ ያላቸው ነገሮችም ቀጭን ናቸው፣ ይህ ማለት ሂደቶች ከበፊቱ በበለጠ ፍጥነት እየተከናወኑ ነው።
በድሮው እና በአዲሱ ግራፎች ውስጥ ያለውን የረጃጅም/ሰፋፊ የወይን ጠጅ ቦታዎች መጠን ካነጻጸሩ፣ አስደናቂ የሆነ የ200% የአፈጻጸም ጭማሪ እያየን ነው! በሁሉም መስክ የአፈጻጸም ጭማሪዎችን እያየን ነው። በጭራሽ መጥፎ አይደለም!
ዋና ዋና ነጥቦች እና ትምህርቶች
እውነቱን ለመናገር፣ አን እስክታነሳው ድረስ PBS የአፈጻጸም ችግሮች እንዳሉበት አላሰብንም ነበር። በዋናነት እኛ ለልማት ያተኮሩ ማሽኖችን ስንጠቀም ስለነበር እና የአፈጻጸም እንቅፋቶቹ ያን ያህል ግልጽ ስላልነበሩ ነው። ወደ ኋላ መለስ ብለን ስናስበው፣ አፈጻጸሙን መፈተሽ ከቀዳሚዎቹ ተግባራት አንዱ መሆን ነበረበት። አሁን ግን ቢያንስ፣ ከስሪት 4.3 ጀምሮ ትኩረት ተሰጥቶታል።
የራሳቸውን የWordPress ፕለጊን አፈጻጸም ለማሻሻል ለሚፈልጉ፣ በተለይም ከባድ ጃቫስክሪፕት እየተጠቀሙ ከሆነ፣ ከዚህ ተሞክሮ ያገኘኋቸው ዋና ዋና ትምህርቶች እነሆ፡
- Reflow የሚያስነሱትን የንብረቶች/ተግባራት ጥሪዎችዎን ይገድቡ/ይሸጉጡ። ይህንን እንደ መመሪያ ይጠቀሙ፡ What forces layout/reflow. The comprehensive list.
- ወደ DOM ስታይሎች የሚደረጉ “ንባቦችን” እና “ጽሁፎችን” በአንድ ላይ ያቧድኑ። ይህን ለእርስዎ እንዲያደርግ FastDomን ይጠቀሙ።
- የChrome የTimeline ፕሮፋይለርን ይጠቀሙ፣ እና በተቻለ መጠን ጥቂት reflows (የወይን ጠጅ ነገሮች) እንዲኖሩዎት ያረጋግጡ።