గత ఫిబ్రవరి 2, 2017న, ఆన్ టేలర్ CodeInWP లో 12 Things We Need to See From WordPress Page Builders in 2017 + Who Already Gets It Right అనే కథనాన్ని రాశారు. మేము పేజ్ బిల్డర్ శాండ్విచ్ను ఒక సంవత్సరానికి పైగా నిరంతరం మెరుగుపరుస్తూ వస్తున్నాము: మేము పరిశోధన చేస్తాము, మా కస్టమర్ల మాట వింటాము, కాబట్టి పేజ్ బిల్డర్ శాండ్విచ్ CodeInWP యొక్క “Who Got it Right” కథనంలో స్థానం సంపాదిస్తుందని మేము భావించాము. కానీ, పనితీరు సమస్యల కారణంగా మాకు స్థానం లభించలేదు.
కాబట్టి మేము దాని గురించి ఆన్ను అడిగాము, ఆమె ఇలా సమాధానమిచ్చారు:
…నేను కాసేపు ఉచిత వెర్షన్ని ఉపయోగించి చూశాను. ఇది చాలా ఆశాజనకంగా కనిపిస్తోంది: చాలా మాడ్యూల్స్, స్పష్టమైన UI, అద్భుతమైన WYSIWYG అనుభవం, ప్రతిదీ సులభంగా డ్రాగ్ చేయవచ్చు. అయితే, పేజీలో సుమారు 10 మాడ్యూల్స్ ఉన్నప్పుడు, తక్కువ ఎడిటింగ్ వేగం కారణంగా దానితో పనిచేయడం కష్టంగా మారింది…
కాబట్టి ఆమె ప్రకారం, పేజ్ బిల్డర్ శాండ్విచ్లో పనితీరు సమస్యలు ఉన్నాయి. మరియు మేము ఎల్లప్పుడూ ఫీడ్బ్యాక్ను పరిగణనలోకి తీసుకుంటాము కాబట్టి, మేము దానిని పరిశీలించాము.
పనితీరును పరీక్షించడం
PBS పనితీరును పరిశీలించడానికి మాకు ఒక మార్గం అవసరమైంది; PBS ఎక్కువగా జావాస్క్రిప్ట్ ద్వారా బ్రౌజర్లో రన్ అవుతుంది కాబట్టి, ఈ పనికి Chrome’s Timeline profiler సరైన సాధనం. టైమ్లైన్ ప్రొఫైలర్ రన్టైమ్లో వెబ్పేజీలో ఏయే ప్రక్రియలు జరుగుతున్నాయో గుర్తించగలదు మరియు కొలవగలదు, ఇది వేగంలో ఉన్న అడ్డంకులను (బాటిల్నెక్స్) కనుగొనడానికి అనువైనది.
మేము ముందుగా అత్యంత సాధారణమైన దశలను పరీక్షించాలని అనుకున్నాము – మా మౌస్ను బహుళ అంశాలు మరియు అడ్డువరుసల మీదుగా కదపడం. చాలా సులభం కదా? ఇంత సాధారణమైన దానితో మాకు పనితీరు సమస్యలు ఎదురుకావని మేము విశ్వసించాము. దురదృష్టవశాత్తూ, మేము తప్పుగా అంచనా వేశాము.
మేము రికార్డ్ బటన్ను క్లిక్ చేసి, స్క్రీన్పై దాదాపు 2 సెకన్ల పాటు మౌస్ను కదిపి, ఆపై స్టాప్ బటన్ను నొక్కాము. ప్రొఫైలర్ నుండి వచ్చిన ఫలిత టైమ్లైన్ ఇక్కడ ఉంది:
చూడండి, ఇది పనితీరు అడ్డంకులతో నిండిపోయింది!
గ్రాఫ్లో చాలా విషయాలు జరుగుతున్నాయి, కానీ స్పష్టంగా కనిపించే సమస్య ఏమిటంటే అందులో చాలా ఊదా రంగు (పర్పుల్) భాగాలు ఉన్నాయి (అలా ఉండకూడదు). అంతేకాకుండా, ఈ ఊదా భాగాలు చాలా వెడల్పుగా కనిపిస్తున్నాయి, మరియు అన్నీ గ్రాఫ్ యొక్క గరిష్ట స్థాయిని తాకుతున్నట్లు ఉన్నాయి. గ్రాఫ్ కూడా ఎల్లప్పుడూ నిండుగా ఉండటం మరియు ఊదా భాగాలు దాదాపుగా సున్నాకి తగ్గకపోవడాన్ని కూడా మీరు గమనించవచ్చు. బ్రౌజర్ ఎల్లప్పుడూ ఏదో ఒక పని చేయడంలో బిజీగా ఉందని, దాదాపు ఎప్పుడూ విశ్రాంతి తీసుకోవడం లేదని అనిపిస్తోంది.
అయితే ఆ ఊదా రంగ భాగాల అసలు అర్థం ఏమిటి?
వాటిని reflows అని పిలుస్తారని ప్రొఫైలర్ మాకు తెలియజేసింది. రీఫ్లో అంటే ఏమిటో Google డెవలపర్ సైట్:
డాక్యుమెంట్లోని ఎలిమెంట్ల స్థానాలను మరియు జ్యామితిని (geometries) తిరిగి లెక్కించే వెబ్ బ్రౌజర్ ప్రక్రియ పేరు రీఫ్లో.. రీఫ్లో అనేది బ్రౌజర్లో యూజర్-బ్లాకింగ్ ఆపరేషన్.
కాబట్టి దీని అర్థం PBS లో మీ మౌస్ను తిప్పడం వలన భారీ సంఖ్యలో రీఫ్లోలు ప్రేరేపించబడతాయి. ఇంకా ఘోరమైన విషయం ఏమిటంటే, ప్రతి రీఫ్లో బ్రౌజర్ను క్షణకాలం నిలిపివేస్తుంది, తద్వారా అది తన లెక్కలను పూర్తి చేయగలదు. ఎక్కువ రీఫ్లోలు అంటే ఎక్కువ బ్రౌజర్ అంతరాయాలు, మరియు అనుభవం మరింత జాంకీగా (janky) మారుతుంది. సరళంగా చెప్పాలంటే, ఎక్కువ ఊదా భాగాలు = చెడ్డ పనితీరు.
కాబట్టి ఆన్ చెప్పింది నిజమేనని తేలింది: మా వద్ద ఖచ్చితంగా పెద్ద పనితీరు సమస్య ఉంది, కాబట్టి మా బృందం వెంటనే దాన్ని సరిదిద్దడానికి రంగంలోకి దిగింది.
మా రీఫ్లో / జాంక్ సమస్యను పరిష్కరించడం
అన్నింటికంటే ముందుగా, అసలు ఈ రీఫ్లో రావడానికి గల కారణాన్ని తెలుసుకోవడానికి మేము కొంత పరిశోధన చేయాల్సి వచ్చింది. స్పష్టంగా చెప్పాలంటే, జావాస్క్రిప్ట్లోని అనేక సాధారణ విషయాలు బ్రౌజర్లో రీఫ్లోను ప్రేరేపించగలవని మేము కనుగొన్నాము.
DOM ఎలిమెంట్ యొక్క వెడల్పు, ఎత్తు లేదా స్థానాన్ని పొందడానికి మీరు ఉపయోగించే దాదాపు ఏదైనా ఫంక్షన్ రీఫ్లోను ప్రేరేపిస్తుంది. దీన్ని చేయగల జావాస్క్రిప్ట్లోని అన్ని ప్రాపర్టీలు మరియు ఫంక్షన్ల సమగ్ర జాబితాను పాల్ ఐరిష్ రాశారు. చేదు వార్త ఏమిటంటే, పేజ్ బిల్డర్ శాండ్విచ్ వీటిలో చాలా ప్రాపర్టీలు మరియు ఫంక్షన్లను ఉపయోగిస్తుంది, ఇవన్నీ రీఫ్లోకు కారణమవుతాయి:
- elem.getBoundingClientRect()
- window.getComputedStyle()
- window.scrollY
- మరియు ఇంకా ఎన్నో…
పరిష్కారం #1: ఖరీదైన రీఫ్లో ప్రాసెస్లను కాష్ చేయడం
అత్యంత స్పష్టమైన పరిష్కారం ఏమిటంటే ఆ ప్రాపర్టీలు మరియు ఫంక్షన్లను ఉపయోగించకపోవడం. అయితే, PBS వాటిపై ఎక్కువగా ఆధారపడుతుంది మరియు అవి లేకుండా మేము ఏమీ చేయలేము.
మా ముందున్న ఏకైక పరిష్కారం ఆ ఫంక్షన్ల కాల్లను వీలైనంత వరకు తగ్గించడం. ఇక్కడ కష్టమైన విషయం ఏమిటంటే, మేము PBS లోని వివిధ భాగాలలో ఆ ప్రాపర్టీలు మరియు ఫంక్షన్లను చాలా సార్లు ఉపయోగించాము, మరియు ఎక్కువ సమయం, మేము వాటిని ఒకే DOM ఎలిమెంట్పై బహుళ సార్లు ఉపయోగించాము. దీన్ని పరిష్కరించడానికి, ప్రతి సమస్యాత్మక ప్రాపర్టీ/ఫంక్షన్ కోసం మేము మా స్వంత క్యాషింగ్ విధానాన్ని సృష్టించాము.
ఉదాహరణకు, getBoundingClientRect ఫంక్షన్ ఒక DOM ఎలిమెంట్ యొక్క ప్రస్తుత top, left, width, height, right, మరియు bottom పిక్సెల్ కొలతలను అందిస్తుంది. 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 ప్రశ్నార్థకమైనప్పుడు, భవిష్యత్ సూచన కోసం మేము ఆ విలువను నిల్వ చేస్తాము, తద్వారా రీఫ్లో ట్రిగ్గర్ల సంఖ్య పరిమితం అవుతుంది.
నిల్వ చేయబడిన క్లయింట్ రెక్ట్లు చెల్లుబాటు కాకుండా పోయినప్పుడు కాష్ను క్లియర్ చేయడానికి కూడా మాకు ఒక మార్గం అవసరమైంది. వినియోగదారు పేజీని స్క్రోల్ చేసినప్పుడు లేదా స్క్రీన్లోని ఎలిమెంట్లను జోడించినప్పుడు/మార్చినప్పుడు/తీసివేసినప్పుడు నిల్వ చేయబడిన క్లయింట్ రెక్ట్ విలువలు మారతాయి. కాబట్టి మాకు తాజా క్లయింట్ రెక్ట్ విలువలు అవసరమైనప్పుడల్లా పిలవడానికి వీలుగా మేము కాష్ క్లియరింగ్ ఫంక్షన్ను రూపొందించాము:
var clearClientRects = function() {
var i;
for ( i = 0; i < elemsWithBoundingRects.length; i++ ) {
if ( elemsWithBoundingRects[ i ] ) {
elemsWithBoundingRects[ i ]._boundingClientRect = null;
}
}
elemsWithBoundingRects = [];
};
మేము సాధారణంగా ఉపయోగించే ఇతర ఖరీదైన ఫంక్షన్ కాల్ల కోసం కూడా ఇదే క్యాషింగ్ విధానాన్ని అమలు చేసాము.
పరిష్కారం #2: FastDom ఉపయోగించి రీడ్స్ & రైట్స్ను సమూహపరచడం
పరిష్కారం #1 ను అమలు చేయడం వల్ల PBS పనితీరు పెరిగింది, కానీ అది సరిపోలేదు.
మరింత గూగుల్ చేయగా, ‘లేఅవుట్ థ్రాషింగ్’ను నివారించడం గురించి విల్సన్ పేజ్ రాసిన ఒక కథనం మా కంటపడింది. విల్సన్ ఇలా చెప్పారు:
జావాస్క్రిప్ట్ DOM నుండి పలుమార్లు వేగంగా వ్రాయడం (write), ఆపై చదవడం (read) చేసినప్పుడు డాక్యుమెంట్ రీఫ్లోలకు కారణమవుతూ లేఅవుట్ థ్రాషింగ్ (రీఫ్లో) జరుగుతుంది.
నిర్దిష్ట రీఫ్లో-ట్రిగ్గరింగ్ ప్రాపర్టీలు మరియు ఫంక్షన్లకు మీ కాల్లను పరిమితం చేస్తే సరిపోదు. మీరు DOM పై ఒకదాని తర్వాత ఒకటి బహుళ “reads” మరియు “writes” నిర్వహించినప్పుడు, అది కూడా బ్రౌజర్ రీఫ్లోను ప్రేరేపిస్తుంది. విల్సన్ సైట్ నుండి నేరుగా తీసుకున్న ఒక సాధారణ దృశ్యం ఇక్కడ ఉంది:
// 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 రీఫ్లోలను ప్రేరేపిస్తుంది ఎందుకంటే రైట్ తర్వాత మొత్తం పేజీ యొక్క కొలతలు చెల్లనివిగా మారతాయి. మొత్తం ప్రక్రియ కేవలం 1 బ్రౌజర్ రీఫ్లోను మాత్రమే ప్రేరేపించేలా అన్ని రీడ్స్ మరియు రైట్స్ను కలిపి ఒకే సమూహంగా మార్చడానికి కోడ్ను క్రమబద్ధీకరించడం దీనికి సూచించబడిన పరిష్కారం:
// 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 లో, రీఫ్లో-ప్రేరేపించే రీడింగ్ మరియు రైటింగ్ ప్రక్రియలు PBS జీవిత చక్రంలో వివిధ సమయాల్లో చాలా విభిన్న ప్రదేశాలలో జరుగుతాయి. వేలాది జావాస్క్రిప్ట్ కోడ్ లైన్లను పునర్వ్యవస్థీకరించడం సాధ్యం కాదు.
మా అదృష్టవశాత్తూ, విల్సన్ తన కథనంలో ఒక పరిష్కారాన్ని కూడా అందించారు. ఆ రీడ్స్ మరియు రైట్స్ను సమూహపరచడంలో సహాయపడటానికి ఆయన FastDom అనే చిన్న యుటిలిటీ స్క్రిప్ట్ను రూపొందించారు.
FastDom ని ఉపయోగిస్తూ మరియు పైన పేర్కొన్న మా పరిష్కారం #1 ని కలిగి ఉన్న పేజ్ బిల్డర్ శాండ్విచ్ నుండి కొంత కోడ్ ఇక్కడ ఉంది:
// 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) అమలు చేస్తుంది, బ్రౌజర్లోని అన్ని రీఫ్లోలను తగ్గించడానికి అన్ని రీడ్స్ మరియు రైట్స్ను సమర్థవంతంగా సమూహపరుస్తుంది.
పరిష్కారం #3: స్టైల్ ఆబ్జెక్ట్లను యాక్సెస్ చేయడం ఖరీదైనది
కొన్ని స్టైల్-పొందే ఫంక్షన్లు ఇతరులకన్నా వేగంగా ఉన్నాయని jsPerf సహాయంతో మేము కనుగొన్నాము.
PBS లో, మేము సాధారణంగా ఒక ఎలిమెంట్ యొక్క నిర్దిష్ట శైలి యొక్క ప్రస్తుత విలువను పొందవలసి ఉంటుంది. ఉదాహరణకు, ఎగువ మార్జిన్ (top margin) పొందడానికి మేము సాధారణంగా దీన్ని ఉపయోగిస్తాము:
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;
}
కోడ్ మెరుగుదలల ఫలితాలు
పై మా 3 పరిష్కారాలు చాలా పరిశోధన, పరీక్షలు మరియు వాస్తవ అమలును తీసుకున్నాయి (మరియు మా ఫాంట్ల ఫీచర్ విడుదల కావడాన్ని ఆలస్యం చేశాయి), కానీ చివరికి ఇదంతా సార్థకమైంది.
స్క్రీన్పై 2 సెకన్ల పాటు మౌస్ను కదిలించే మా ప్రారంభ పరీక్షను మళ్లీ పరిశీలిస్తే. పాత గజిబిజి/జాంకీ టైమ్లైన్ ఇక్కడ ఉంది:
మరియు పనితీరు మెరుగుదలల తర్వాత మా కొత్త టైమ్లైన్ ఇలా కనిపిస్తుంది:
మీరు గమనిస్తే, గ్రాఫ్లో ఊదా రంగు భాగాలు చాలా తక్కువగా ఉన్నాయి. మరియు బ్రౌజర్ ద్వారా నిర్వహించబడుతున్న ప్రక్రియల పరిమాణంలో గణనీయమైన వ్యత్యాసం ఉంది. దిగువన ఉన్న దీర్ఘచతురస్రాకార భాగాలు కూడా సన్నగా ఉన్నాయి, అంటే ప్రక్రియలు మునుపటి కంటే వేగంగా నడుస్తున్నాయని అర్థం.
మీరు పాత మరియు కొత్త గ్రాఫ్లలోని పొడవైన/వెడల్పాటి ఊదా ప్రాంతాల పరిమాణాన్ని పోల్చి చూస్తే, మేము ఏకంగా 200% పనితీరు పెరుగుదలను చూస్తున్నాము! మేము అన్ని విభాగాలలోనూ పనితీరు పెరుగుదలను చూస్తున్నాము. ఇది ఎంతమాత్రం తక్కువ కాదు!
ముఖ్యాంశాలు & నేర్చుకున్న విషయాలు
నిజం చెప్పాలంటే, ఆన్ ప్రస్తావించే వరకు PBS లో పనితీరు సమస్యలు ఉన్నాయని మేము అనుకోలేదు. ప్రధానంగా మేము డెవలప్మెంట్-కేంద్రీకృత యంత్రాలను ఉపయోగిస్తున్నందున పనితీరు అడ్డంకులు అంత స్పష్టంగా కనిపించలేదు. వెనక్కి తిరిగి చూసుకుంటే, పనితీరును తనిఖీ చేయడం అత్యంత ప్రాధాన్యతలలో ఒకటిగా ఉండాల్సింది. కానీ కనీసం ఇప్పుడు, వెర్షన్ 4.3 నాటికి ఇది పరిష్కరించబడింది.
తమ స్వంత వర్డ్ప్రెస్ ప్లగిన్ పనితీరును మెరుగుపరచాలనుకునే వారికి, ముఖ్యంగా మీరు కూడా హెవీ జావాస్క్రిప్ట్ని ఉపయోగిస్తుంటే, ఈ అనుభవం నుండి నా ముఖ్యాంశాలు ఇక్కడ ఉన్నాయి:
- రీఫ్లోను ప్రేరేపించే ప్రాపర్టీలు/ఫంక్షన్లకు మీ కాల్లను పరిమితం చేయండి/కాష్ చేయండి. దీనిని గైడ్గా ఉపయోగించండి: What forces layout/reflow. The comprehensive list.
- DOM శైలులకు “reads” మరియు “writes”ను సమూహపరచండి. మీ కోసం దీన్ని చేయడానికి FastDom ని ఉపయోగించండి.
- Chrome యొక్క టైమ్లైన్ ప్రొఫైలర్ను ఉపయోగించండి మరియు మీకు వీలైనంత తక్కువ రీఫ్లోలు (ఊదా భాగాలు) ఉండేలా చూసుకోండి.
మీరు పూర్తి నిడివి గల వ్యాసాలను రాయడం మరియు అప్పుడప్పుడు ఒక చిత్రాన్ని జోడించడం చుట్టూనే మీ కంటెంట్ సృష్టి అంతా తిరిగే తీవ్రమైన బ్లాగర్ అయితే, బహుశా ప్రస్తుతం ఉన్న TinyMCE కంటెంట్ ఎడిటర్ మీ అవసరాలకు సరిపోవచ్చు. ప్రస్తుత సాధనాల సమితిలో వ్యాసాలు రాయడానికి అవసరమైన సాధనాలు ఇప్పటికే ఉన్నాయి; బోల్డ్, ఇటాలిక్, శీర్షికలు మొదలైన ప్రాథమిక టెక్స్ట్ ఫార్మాటింగ్ సాధనాలు మీకు లభిస్తాయి. కానీ అంతే.


