ગત ૨ ફેબ્રુઆરી, ૨૦૧૭ ના રોજ, એન ટેલરે 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 અનુભવ, બધું સરળતાથી ડ્રેગ કરી શકાય છે. જો કે, જ્યારે પેજ પર આશરે ૧૦ મોડ્યુલ્સ આવ્યા, ત્યારે એડિટિંગની ઓછી સ્પીડને કારણે તેની સાથે કામ ચાલુ રાખવું મુશ્કેલ બની ગયું…
તેથી તેના જણાવ્યા મુજબ, Page Builder Sandwich માં પર્ફોર્મન્સ સંબંધિત સમસ્યાઓ છે. અને અમે હંમેશાં પ્રતિસાદને ગંભીરતાથી લઈએ છીએ, તેથી અમે તેની તપાસ કરી.
પર્ફોર્મન્સનું પરીક્ષણ કરવું
PBS ના પર્ફોર્મન્સને ચકાસવા માટે અમને એક રીતની જરૂર હતી; PBS મોટે ભાગે જાવાસ્ક્રિપ્ટ દ્વારા બ્રાઉઝર પર ચાલતું હોવાથી, Chrome નું ટાઈમલાઈન પ્રોફાઇલર આ કામ માટે શ્રેષ્ઠ ટૂલ હતું. ટાઈમલાઈન પ્રોફાઇલર રનટાઇમ દરમિયાન વેબપેજમાં કઈ પ્રક્રિયાઓ થઈ રહી છે તે ઓળખી અને માપી શકે છે, જે સ્પીડ બોટલનેક્સ (અવરોધો) શોધવા માટે ઉત્તમ છે.
અમે વિચાર્યું કે અમારે પહેલા સૌથી સરળ પગલાંનું પરીક્ષણ કરવું જોઈએ – બહુવિધ એલિમેન્ટ્સ અને પંક્તિઓ પર અમારું માઉસ ફેરવવું. એકદમ સરળ, ખરું ને? અમને ખાતરી હતી કે આટલી સરળ બાબતમાં અમને પર્ફોર્મન્સની સમસ્યાઓનો સામનો કરવો નહીં પડે. કમનસીબે, અમે ખોટા હતા.
જેવું અમે રેકોર્ડ બટન દબાવ્યું, અમે સ્ક્રીન પર લગભગ ૨ સેકન્ડ માટે માઉસ ફેરવ્યું, પછી સ્ટોપ બટન દબાવ્યું. પ્રોફાઇલરમાંથી મળેલું ટાઈમલાઈન પરિણામ આ મુજબ છે:
અને જુઓ તો ખરા. આ પર્ફોર્મન્સ બોટલનેક્સથી ભરેલું છે!
ગ્રાફમાં ઘણી બધી વસ્તુઓ થઈ રહી છે, પરંતુ સૌથી સ્પષ્ટ સમસ્યા એ છે કે તેમાં ઘણા બધા જાંબુડિયા વિસ્તારો છે (જે ન હોવા જોઈએ). તેના ઉપર, આ જાંબુડિયા વિસ્તારો દેખીતી રીતે ખૂબ પહોળા છે અને બધા ગ્રાફના શિખરને સ્પર્શતા લાગે છે. તમે એ પણ જોશો કે ગ્રાફ હંમેશાં ભરેલો રહે છે અને જાંબુડિયા વિસ્તારો લગભગ ક્યારેય શૂન્ય સુધી નીચે આવતા નથી. એવું લાગે છે કે બ્રાઉઝર હંમેશાં કંઈક કરવામાં વ્યસ્ત રહે છે અને લગભગ ક્યારેય આરામ કરતું નથી.
પરંતુ તે બધા જાંબુડિયા વિસ્તારોનો ખરેખર અર્થ શું છે?
પ્રોફાઇલરે કૃપા કરીને અમને જણાવ્યું કે તેમને reflows કહેવામાં આવે છે. Google ડેવલપર સાઇટ:
રિફ્લો એ દસ્તાવેજમાંના એલિમેન્ટ્સની સ્થિતિ અને ભૂમિતિની પુનઃગણતરી કરવા માટેની વેબ બ્રાઉઝર પ્રક્રિયાનું નામ છે.. રિફ્લો એ બ્રાઉઝરમાં યુઝર-બ્લોકિંગ કામગીરી છે.
તેથી આનો અર્થ એ છે કે PBS માં તમારા માઉસને આસપાસ ફેરવવાથી અસંખ્ય રિફ્લો ટ્રિગર થાય છે. તેનાથી પણ ખરાબ બાબત એ છે કે દરેક રિફ્લો બ્રાઉઝરને ક્ષણભર માટે થોભાવી દે છે જેથી તે તેની ગણતરીઓ પૂર્ણ કરી શકે. વધુ રિફ્લો એટલે વધુ બ્રાઉઝર પોઝ, અને અનુભવ વધુ જેન્કી (અટકતો-અટકતો) બની જાય છે. સરળ શબ્દોમાં કહીએ તો, ઘણા બધા જાંબુડિયા વિસ્તારો = ખરાબ.
તેથી બહાર આવ્યું કે એન સાચી હતી: અમારી પાસે ખરેખર એક મોટો પર્ફોર્મન્સ બોટલનેક છે, તેથી અમારી ટીમે તેને તાત્કાલિક સુધારવા માટે કામ શરૂ કરી દીધું.
અમારી રિફ્લો / જેન્ક સમસ્યાને સુધારવી
બીજું કંઈપણ કરતાં પહેલાં, અમને રિફ્લોનું કારણ શું છે તે શોધવા માટે થોડું સંશોધન કરવાની જરૂર હતી. અમને જાણવા મળ્યું કે દેખીતી રીતે, જાવાસ્ક્રિપ્ટમાં ઘણી સામાન્ય બાબતો બ્રાઉઝરમાં રિફ્લોનું કારણ બની શકે છે.
DOM એલિમેન્ટની પહોળાઈ, ઊંચાઈ અથવા સ્થિતિ મેળવવા માટે તમે જે પણ ફંક્શનનો ઉપયોગ કરો છો તે લગભગ દરેક ફંક્શન રિફ્લો ટ્રિગર કરી શકે છે. પોલ આઇરિશે જાવાસ્ક્રિપ્ટમાં આવી તમામ પ્રોપર્ટીઝ અને ફંક્શન્સની વિસ્તૃત સૂચિ લખી છે જે આવું કરી શકે છે. ખરાબ સમાચાર એ છે કે Page Builder Sandwich આમાંની ઘણી બધી પ્રોપર્ટીઝ અને ફંક્શન્સનો ઉપયોગ કરે છે, જે તમામ રિફ્લોનું કારણ બને છે:
- elem.getBoundingClientRect()
- window.getComputedStyle()
- window.scrollY
- અને ઘણું બધું…
ઉકેલ #૧: ભારે રિફ્લો પ્રક્રિયાઓને કેશ (Cache) કરવી
સૌથી સ્પષ્ટ ઉકેલ એ છે કે તે પ્રોપર્ટીઝ અને ફંક્શન્સનો ઉપયોગ ન કરવો. જો કે, PBS તેમના પર ખૂબ આધાર રાખે છે અને અમે તેમના વિના કામ ચલાવી શકીએ તેમ નથી.
અમારી પાસે બાકી રહેલો ઉકેલ એ હતો કે તે ફંક્શન્સના કૉલ્સને શક્ય તેટલા ઓછા કરવા. અહીં મુશ્કેલ બાબત એ હતી કે અમે PBS ના વિવિધ ભાગોમાં આ પ્રોપર્ટીઝ અને ફંક્શન્સનો ઘણી વખત ઉપયોગ કર્યો હતો, અને મોટાભાગે, અમે સમાન DOM એલિમેન્ટ પર ઘણી વખત તેનો ઉપયોગ કર્યો હતો. આને સુધારવા માટે, અમે દરેક સમસ્યારૂપ પ્રોપર્ટી/ફંક્શન માટે અમારી પોતાની કેશિંગ સિસ્ટમ બનાવી.
ઉદાહરણ તરીકે, 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 નો ઉપયોગ કર્યો. હવે જ્યારે પણ ક્લાયંટ રેક્ટ ક્વેરી થાય છે, ત્યારે અમે તે મૂલ્ય ભવિષ્યના સંદર્ભ માટે સંગ્રહિત કરીએ છીએ, જેથી રિફ્લો ટ્રિગર્સની સંખ્યા મર્યાદિત થાય છે.
જ્યારે સંગ્રહિત ક્લાયંટ રેક્ટ અમાન્ય બને ત્યારે અમને કેશ સાફ કરવાની રીતની પણ જરૂર હતી. જ્યારે યુઝર પેજને સ્ક્રોલ કરે છે અથવા સ્ક્રીન પર એલિમેન્ટ્સ ઉમેરે/બદલે/દૂર કરે છે ત્યારે સંગ્રહિત ક્લાયંટ રેક્ટના મૂલ્યો બદલાય છે. તેથી અમે એક કેશ ક્લિયરિંગ ફંક્શન બનાવ્યું જેને જ્યારે પણ અમને નવા ક્લાયંટ રેક્ટ મૂલ્યોની જરૂર હોય ત્યારે અમે કૉલ કરી શકીએ છીએ:
var clearClientRects = function() {
var i;
for ( i = 0; i < elemsWithBoundingRects.length; i++ ) {
if ( elemsWithBoundingRects[ i ] ) {
elemsWithBoundingRects[ i ]._boundingClientRect = null;
}
}
elemsWithBoundingRects = [];
};
અમે સામાન્ય રીતે ઉપયોગમાં લેવાતા અન્ય ભારે ફંક્શન કૉલ્સ માટે પણ આ જ કેશિંગ સિસ્ટમ અપનાવી.
ઉકેલ #૨: FastDom નો ઉપયોગ કરીને રીડ્સ (Reads) અને રાઇટ્સ (Writes) નું જૂથ બનાવવું
ઉકેલ #૧ લાગુ કરવાથી PBS નું પર્ફોર્મન્સ વધ્યું, પરંતુ તે પૂરતું ન હતું.
વધુ ગૂગલિંગ કરતાં, અમે વિલ્સન પેજનો ‘લેઆઉટ થ્રેશિંગ’ અટકાવવા પરનો એક લેખ જોયો. વિલ્સન કહે છે:
લેઆઉટ થ્રેશિંગ (રિફ્લો) ત્યારે થાય છે જ્યારે જાવાસ્ક્રિપ્ટ DOM માંથી વારંવાર ઝડપથી લખે છે અને પછી વાંચે છે, જેના કારણે દસ્તાવેજમાં રિફ્લો થાય છે.
દેખીતી રીતે, ચોક્કસ રિફ્લો-ટ્રિગરિંગ પ્રોપર્ટીઝ અને ફંક્શન્સ પરના તમારા કૉલ્સને મર્યાદિત કરવા પૂરતું નથી. જ્યારે તમે DOM પર એક પછી એક બહુવિધ “રીડ્સ” અને “રાઇટ્સ” કરો છો, ત્યારે તે બ્રાઉઝર રિફ્લો પણ ટ્રિગર કરે છે. વિલ્સનની સાઇટ પરથી સીધું લીધેલું એક સામાન્ય દૃશ્ય અહીં છે:
// 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
ઉપરોક્ત ઉદાહરણ ૩ રિફ્લો ટ્રિગર કરે છે કારણ કે એક રાઇટ પછી સમગ્ર પેજના પરિમાણો અમાન્ય થઈ જાય છે. આ માટે સૂચવેલ ઉકેલ એ છે કે કોડને ફરીથી ગોઠવીને બધા રીડ્સ અને રાઇટ્સને એકસાથે જૂથબદ્ધ કરવા જેથી આખી બાબત ફક્ત ૧ બ્રાઉઝર રિફ્લો ટ્રિગર કરે:
// 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 કહેવામાં આવે છે.
Page Builder Sandwich નો કેટલોક કોડ અહીં છે જે FastDom નો ઉપયોગ કરે છે અને તેમાં અમારા ઉપરોક્ત ઉકેલ #૧ નો પણ સમાવેશ થાય છે:
// 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 કૉલ્સને એકસાથે જૂથબદ્ધ કરે છે અને તેમને અસિંક્રોનસ રીતે એક્ઝિક્યુટ કરે છે, બ્રાઉઝરમાં તમામ રિફ્લો ઘટાડવા માટે તમામ રીડ્સ અને રાઇટ્સને અસરકારક રીતે એકસાથે ગોઠવે છે.
ઉકેલ #૩: સ્ટાઇલ ઑબ્જેક્ટ્સને એક્સેસ કરવું ખર્ચાળ છે
અમને 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 માં પર્ફોર્મન્સની સમસ્યાઓ છે. મુખ્યત્વે કારણ કે અમે ડેવલપમેન્ટ-કેન્દ્રિત મશીનોનો ઉપયોગ કરી રહ્યા હતા અને પર્ફોર્મન્સ બોટલનેક્સ એટલા સ્પષ્ટ નહોતા. પાછળ વળીને જોતાં, પર્ફોર્મન્સની ચકાસણી એ સર્વોચ્ચ પ્રાથમિકતાઓમાંની એક હોવી જોઈતી હતી. પરંતુ ઓછામાં ઓછું હવે, વર્ઝન ૪.૩ મુજબ તેની કાળજી લેવામાં આવી છે. 
જેઓ તેમના પોતાના WordPress પ્લગઇન પર્ફોર્મન્સને સુધારવા માગે છે, ખાસ કરીને જો તમે પણ ભારે જાવાસ્ક્રિપ્ટનો ઉપયોગ કરી રહ્યાં છો, તો આ અનુભવમાંથી મારા મુખ્ય તારણો અહીં છે:
- રિફ્લો ટ્રિગર કરતી પ્રોપર્ટીઝ/ફંક્શન્સના તમારા કૉલ્સને મર્યાદિત/કેશ કરો. માર્ગદર્શિકા તરીકે આનો ઉપયોગ કરો: લેઆઉટ/રિફ્લો શું દબાણ કરે છે. વ્યાપક સૂચિ.
- DOM સ્ટાઇલ્સમાં “રીડ્સ” અને “રાઇટ્સ” ને એકસાથે જૂથબદ્ધ કરો. તમારા માટે આ કરવા માટે FastDom નો ઉપયોગ કરો.
- Chrome ના ટાઈમલાઈન પ્રોફાઇલરનો ઉપયોગ કરો, અને ખાતરી કરો કે તમારી પાસે શક્ય તેટલા ઓછા રિફ્લો (જાંબુડિયા વિસ્તારો) હોય.