રિએક્ટના પર્ફોર્મન્સ પાછળના જાદુને અનલૉક કરો. આ વ્યાપક માર્ગદર્શિકા રિકન્સિલિએશન એલ્ગોરિધમ, વર્ચ્યુઅલ DOM ડિફિંગ અને મુખ્ય ઓપ્ટિમાઇઝેશન વ્યૂહરચનાઓ સમજાવે છે.
રિએક્ટનો સિક્રેટ સોસ: રિકન્સિલિએશન એલ્ગોરિધમ અને વર્ચ્યુઅલ DOM ડિફિંગમાં ઊંડાણપૂર્વકનો અભ્યાસ
આધુનિક વેબ ડેવલપમેન્ટની દુનિયામાં, રિએક્ટે ડાયનેમિક અને ઇન્ટરેક્ટિવ યુઝર ઇન્ટરફેસ બનાવવા માટે એક પ્રબળ શક્તિ તરીકે પોતાને સ્થાપિત કર્યું છે. તેની લોકપ્રિયતા ફક્ત તેના કમ્પોનન્ટ-આધારિત આર્કિટેક્ચરને કારણે જ નહીં, પરંતુ તેના અસાધારણ પ્રદર્શનને કારણે પણ છે. પણ રિએક્ટને આટલું ઝડપી શું બનાવે છે? જવાબ કોઈ જાદુ નથી; તે એન્જિનિયરિંગનો એક ઉત્કૃષ્ટ નમૂનો છે જેને રિકન્સિલિએશન એલ્ગોરિધમ તરીકે ઓળખવામાં આવે છે.
ઘણા ડેવલપર્સ માટે, રિએક્ટની આંતરિક કામગીરી એક બ્લેક બોક્સ જેવી છે. આપણે કમ્પોનન્ટ્સ લખીએ છીએ, સ્ટેટ મેનેજ કરીએ છીએ અને UI ને દોષરહિત રીતે અપડેટ થતું જોઈએ છીએ. જોકે, આ સીમલેસ પ્રક્રિયા પાછળની પદ્ધતિઓ, ખાસ કરીને વર્ચ્યુઅલ DOM અને તેના ડિફિંગ એલ્ગોરિધમને સમજવું એ જ એક સારા રિએક્ટ ડેવલપરને એક મહાન ડેવલપરથી અલગ પાડે છે. આ ઊંડું જ્ઞાન તમને અત્યંત ઓપ્ટિમાઇઝ્ડ એપ્લિકેશન્સ લખવા, પર્ફોર્મન્સની સમસ્યાઓનું નિવારણ કરવા અને લાઇબ્રેરી પર સાચી રીતે નિપુણતા મેળવવા માટે સશક્ત બનાવે છે.
આ વ્યાપક માર્ગદર્શિકા રિએક્ટની મુખ્ય રેન્ડરિંગ પ્રક્રિયાને સ્પષ્ટ કરશે. આપણે અન્વેષણ કરીશું કે સીધું DOM મેનીપ્યુલેશન શા માટે ખર્ચાળ છે, વર્ચ્યુઅલ DOM કેવી રીતે એક ઉત્તમ ઉકેલ પૂરો પાડે છે, અને રિકન્સિલિએશન એલ્ગોરિધમ તમારા UI ને અસરકારક રીતે કેવી રીતે અપડેટ કરે છે. આપણે મૂળ સ્ટેક રિકન્સાઇલરથી આધુનિક ફાઈબર આર્કિટેક્ચર સુધીની ઉત્ક્રાંતિમાં પણ ઊંડા ઉતરીશું અને તમારી પોતાની એપ્લિકેશન્સને ઓપ્ટિમાઇઝ કરવા માટે તમે આજે અમલમાં મૂકી શકો તેવી કાર્યક્ષમ વ્યૂહરચનાઓ સાથે સમાપન કરીશું.
મુખ્ય સમસ્યા: શા માટે સીધું DOM મેનીપ્યુલેશન બિનકાર્યક્ષમ છે
રિએક્ટના ઉકેલની પ્રશંસા કરવા માટે, આપણે પહેલા તે જે સમસ્યાનું નિરાકરણ લાવે છે તેને સમજવી જોઈએ. ડોક્યુમેન્ટ ઓબ્જેક્ટ મોડેલ (DOM) એ HTML દસ્તાવેજોનું પ્રતિનિધિત્વ કરવા અને તેની સાથે ક્રિયાપ્રતિક્રિયા કરવા માટે બ્રાઉઝર API છે. તે ઓબ્જેક્ટ્સના ટ્રી તરીકે રચાયેલ છે, જ્યાં દરેક નોડ દસ્તાવેજના એક ભાગનું પ્રતિનિધિત્વ કરે છે (જેમ કે એલિમેન્ટ, ટેક્સ્ટ અથવા એટ્રિબ્યુટ).
જ્યારે તમે સ્ક્રીન પર શું છે તે બદલવા માંગો છો, ત્યારે તમે આ DOM ટ્રીમાં ફેરફાર કરો છો. ઉદાહરણ તરીકે, નવી લિસ્ટ આઇટમ ઉમેરવા માટે, તમે એક નવું `
- ` નોડ સાથે જોડો છો. જ્યારે આ સીધું લાગે છે, DOM ઓપરેશન્સ કમ્પ્યુટેશનલી ખર્ચાળ હોય છે. અહીં શા માટે તે છે:
- લેઆઉટ અને રિફ્લો: જ્યારે પણ તમે કોઈ એલિમેન્ટની ભૂમિતિ (જેમ કે તેની પહોળાઈ, ઊંચાઈ અથવા સ્થિતિ) બદલો છો, ત્યારે બ્રાઉઝરને તમામ અસરગ્રસ્ત એલિમેન્ટ્સની સ્થિતિ અને પરિમાણોની ફરીથી ગણતરી કરવી પડે છે. આ પ્રક્રિયાને "રિફ્લો" અથવા "લેઆઉટ" કહેવામાં આવે છે અને તે સમગ્ર દસ્તાવેજમાં ફેલાઈ શકે છે, જે નોંધપાત્ર પ્રોસેસિંગ પાવરનો વપરાશ કરે છે.
- રિપેઈન્ટિંગ: રિફ્લો પછી, બ્રાઉઝરને અપડેટ થયેલા એલિમેન્ટ્સ માટે સ્ક્રીન પર પિક્સેલ્સ ફરીથી દોરવાની જરૂર છે. આને "રિપેઈન્ટિંગ" અથવા "રાસ્ટરાઇઝિંગ" કહેવાય છે. બેકગ્રાઉન્ડ રંગ જેવી સરળ વસ્તુ બદલવાથી કદાચ ફક્ત રિપેઈન્ટ ટ્રિગર થાય, પરંતુ લેઆઉટમાં ફેરફાર હંમેશા રિપેઈન્ટ ટ્રિગર કરશે.
- સિંક્રોનસ અને બ્લોકિંગ: DOM ઓપરેશન્સ સિંક્રોનસ હોય છે. જ્યારે તમારો જાવાસ્ક્રિપ્ટ કોડ DOM માં ફેરફાર કરે છે, ત્યારે બ્રાઉઝરને રિફ્લો અને રિપેઈન્ટ કરવા માટે અન્ય કાર્યો, જેમાં વપરાશકર્તાના ઇનપુટનો પ્રતિસાદ આપવાનો સમાવેશ થાય છે, તેને ઘણીવાર રોકવા પડે છે, જે સુસ્ત અથવા થીજી ગયેલા યુઝર ઇન્ટરફેસ તરફ દોરી શકે છે.
- પ્રારંભિક રેન્ડર: જ્યારે તમારી એપ્લિકેશન પ્રથમ વખત લોડ થાય છે, ત્યારે રિએક્ટ તમારા UI માટે સંપૂર્ણ વર્ચ્યુઅલ DOM ટ્રી બનાવે છે અને તેનો ઉપયોગ પ્રારંભિક વાસ્તવિક DOM બનાવવા માટે કરે છે.
- સ્ટેટ અપડેટ: જ્યારે એપ્લિકેશનનું સ્ટેટ બદલાય છે (દા.ત., વપરાશકર્તા બટન પર ક્લિક કરે છે), ત્યારે રિએક્ટ એક નવું વર્ચ્યુઅલ DOM ટ્રી બનાવે છે જે નવા સ્ટેટને પ્રતિબિંબિત કરે છે.
- ડિફિંગ: હવે રિએક્ટ પાસે મેમરીમાં બે વર્ચ્યુઅલ DOM ટ્રી છે: જૂનું (સ્ટેટ બદલાતા પહેલાનું) અને નવું. તે પછી આ બે ટ્રીની તુલના કરવા અને ચોક્કસ તફાવતો ઓળખવા માટે તેનું "ડિફિંગ" એલ્ગોરિધમ ચલાવે છે.
- બેચિંગ અને અપડેટિંગ: રિએક્ટ વાસ્તવિક DOM ને નવા વર્ચ્યુઅલ DOM સાથે મેચ કરવા માટે જરૂરી સૌથી કાર્યક્ષમ અને ન્યૂનતમ ઓપરેશન્સના સેટની ગણતરી કરે છે. આ ઓપરેશન્સને એકસાથે બેચ કરવામાં આવે છે અને એક જ, ઓપ્ટિમાઇઝ્ડ ક્રમમાં વાસ્તવિક DOM પર લાગુ કરવામાં આવે છે.
- તે સંપૂર્ણ જૂના ટ્રીને તોડી પાડે છે, બધા જૂના કમ્પોનન્ટ્સને અનમાઉન્ટ કરે છે અને તેમના સ્ટેટનો નાશ કરે છે.
- તે નવા એલિમેન્ટ પ્રકારના આધારે શરૂઆતથી સંપૂર્ણપણે નવું ટ્રી બનાવે છે.
- આઇટમ B
- આઇટમ C
- આઇટમ A
- આઇટમ B
- આઇટમ C
- તે જૂની આઇટમ ઇન્ડેક્સ 0 ('આઇટમ B') ને નવી આઇટમ ઇન્ડેક્સ 0 ('આઇટમ A') સાથે સરખાવે છે. તે અલગ છે, તેથી તે પ્રથમ આઇટમમાં ફેરફાર કરે છે.
- તે જૂની આઇટમ ઇન્ડેક્સ 1 ('આઇટમ C') ને નવી આઇટમ ઇન્ડેક્સ 1 ('આઇટમ B') સાથે સરખાવે છે. તે અલગ છે, તેથી તે બીજી આઇટમમાં ફેરફાર કરે છે.
- તે જુએ છે કે ઇન્ડેક્સ 2 પર એક નવી આઇટમ ('આઇટમ C') છે અને તેને દાખલ કરે છે.
- આઇટમ B
- આઇટમ C
- આઇટમ A
- આઇટમ B
- આઇટમ C
- રિએક્ટ નવી લિસ્ટના ચિલ્ડ્રનને જુએ છે અને 'b' અને 'c' કીવાળા એલિમેન્ટ્સ શોધે છે.
- તે જાણે છે કે 'b' અને 'c' કીવાળા એલિમેન્ટ્સ જૂની લિસ્ટમાં પહેલેથી જ અસ્તિત્વમાં છે, તેથી તે ફક્ત તેમને ખસેડે છે.
- તે જુએ છે કે 'a' કી સાથે એક નવો એલિમેન્ટ છે જે પહેલાં અસ્તિત્વમાં ન હતો, તેથી તે તેને બનાવે છે અને દાખલ કરે છે.
- ... )`) એ એક એન્ટી-પેટર્ન છે, કારણ કે તે કોઈ કી ન હોવા જેવી જ સમસ્યાઓ તરફ દોરી જાય છે. શ્રેષ્ઠ કી તમારા ડેટામાંથી અનન્ય ઓળખકર્તા છે, જેમ કે ડેટાબેઝ ID.
- વધતું રેન્ડરિંગ (Incremental Rendering): તે રેન્ડરિંગના કામને નાના ટુકડાઓમાં વિભાજીત કરી શકે છે અને તેને બહુવિધ ફ્રેમ્સમાં ફેલાવી શકે છે.
- પ્રાથમિકતા (Prioritization): તે વિવિધ પ્રકારના અપડેટ્સને અલગ-અલગ પ્રાથમિકતા સ્તર સોંપી શકે છે. ઉદાહરણ તરીકે, ઇનપુટ ફિલ્ડમાં ટાઇપ કરતા વપરાશકર્તાની પ્રાથમિકતા બેકગ્રાઉન્ડમાં ફેચ થતા ડેટા કરતાં વધુ હોય છે.
- રોકવાની અને રદ કરવાની ક્ષમતા (Pausability and Abortability): તે ઉચ્ચ-પ્રાથમિકતાવાળા અપડેટને હેન્ડલ કરવા માટે ઓછી-પ્રાથમિકતાવાળા કામને રોકી શકે છે, અને જે કામની હવે જરૂર નથી તેને રદ અથવા ફરીથી ઉપયોગ પણ કરી શકે છે.
- રેન્ડર/રિકન્સિલિએશન તબક્કો (એસિંક્રોનસ): આ તબક્કામાં, રિએક્ટ "વર્ક-ઇન-પ્રોગ્રેસ" ટ્રી બનાવવા માટે ફાઈબર નોડ્સ પર પ્રક્રિયા કરે છે. તે કમ્પોનન્ટ `render` મેથડ્સને કૉલ કરે છે અને DOM માં શું ફેરફાર કરવાની જરૂર છે તે નક્કી કરવા માટે ડિફિંગ એલ્ગોરિધમ ચલાવે છે. નિર્ણાયક રીતે, આ તબક્કો અટકાવી શકાય તેવો છે. રિએક્ટ વધુ મહત્વની કોઈ વસ્તુને હેન્ડલ કરવા માટે આ કામને રોકી શકે છે, અને પછીથી તેને ફરી શરૂ કરી શકે છે. કારણ કે તેને અટકાવી શકાય છે, રિએક્ટ અસંગત UI સ્થિતિને ટાળવા માટે આ તબક્કા દરમિયાન કોઈ વાસ્તવિક DOM ફેરફારો લાગુ કરતું નથી.
- કમિટ તબક્કો (સિંક્રોનસ): એકવાર વર્ક-ઇન-પ્રોગ્રેસ ટ્રી પૂર્ણ થઈ જાય, રિએક્ટ કમિટ તબક્કામાં પ્રવેશે છે. તે ગણતરી કરેલા ફેરફારો લે છે અને તેમને વાસ્તવિક DOM પર લાગુ કરે છે. આ તબક્કો સિંક્રોનસ છે અને તેને અટકાવી શકાતો નથી. આ સુનિશ્ચિત કરે છે કે વપરાશકર્તા હંમેશા એક સુસંગત UI જુએ છે. `componentDidMount` અને `componentDidUpdate` જેવી લાઇફસાયકલ મેથડ્સ, તેમજ `useLayoutEffect` અને `useEffect` હુક્સ, આ તબક્કા દરમિયાન ચલાવવામાં આવે છે.
- `React.memo()`: ફંક્શન કમ્પોનન્ટ્સ માટે એક હાયર-ઓર્ડર કમ્પોનન્ટ. તે કમ્પોનન્ટના પ્રોપ્સની શેલો કમ્પેરિઝન કરે છે. જો પ્રોપ્સ બદલાયા ન હોય, તો રિએક્ટ કમ્પોનન્ટને રી-રેન્ડર કરવાનું છોડી દેશે અને છેલ્લા રેન્ડર થયેલા પરિણામનો ફરીથી ઉપયોગ કરશે.
- `useCallback()`: કમ્પોનન્ટની અંદર વ્યાખ્યાયિત કરાયેલા ફંક્શન્સ દરેક રેન્ડર પર ફરીથી બનાવવામાં આવે છે. જો તમે આ ફંક્શન્સને `React.memo` માં લપેટાયેલા ચાઈલ્ડ કમ્પોનન્ટને પ્રોપ્સ તરીકે પાસ કરો છો, તો ચાઈલ્ડ રી-રેન્ડર થશે કારણ કે ફંક્શન પ્રોપ તકનીકી રીતે દરેક વખતે એક નવું ફંક્શન છે. `useCallback` ફંક્શનને જ મેમોઇઝ કરે છે, સુનિશ્ચિત કરે છે કે તે ફક્ત ત્યારે જ ફરીથી બનાવવામાં આવે છે જો તેની ડિપેન્ડન્સીઝ બદલાય.
- `useMemo()`: `useCallback` જેવું જ છે, પરંતુ વેલ્યુઝ માટે. તે ખર્ચાળ ગણતરીના પરિણામને મેમોઇઝ કરે છે. ગણતરી ફક્ત ત્યારે જ ફરીથી ચલાવવામાં આવે છે જો તેની કોઈ ડિપેન્ડન્સી બદલાઈ હોય. આ દરેક રેન્ડર પર ખર્ચાળ ગણતરીઓને રોકવા અને પ્રોપ્સ તરીકે પાસ કરાયેલા સ્થિર ઓબ્જેક્ટ/એરે રેફરન્સને જાળવવા માટે ઉપયોગી છે.
હજારો નોડ્સવાળી એક જટિલ એપ્લિકેશનની કલ્પના કરો. જો તમે સ્ટેટ અપડેટ કરો અને સીધા DOM માં ફેરફાર કરીને સમગ્ર UI ને ફરીથી રેન્ડર કરો, તો તમે બ્રાઉઝરને ખર્ચાળ રિફ્લો અને રિપેઈન્ટ્સના કાસ્કેડમાં ધકેલી રહ્યા હશો, જે એક ભયંકર વપરાશકર્તા અનુભવમાં પરિણમશે.
ઉકેલ: વર્ચ્યુઅલ DOM (VDOM)
રિએક્ટના સર્જકોએ સીધા DOM મેનીપ્યુલેશનની પર્ફોર્મન્સની મર્યાદાને ઓળખી. તેમનો ઉકેલ એક એબ્સ્ટ્રેક્શન લેયર દાખલ કરવાનો હતો: વર્ચ્યુઅલ DOM.
વર્ચ્યુઅલ DOM શું છે?
વર્ચ્યુઅલ DOM એ વાસ્તવિક DOM નું એક હલકું, ઇન-મેમરી પ્રતિનિધિત્વ છે. તે અનિવાર્યપણે એક સાદો જાવાસ્ક્રિપ્ટ ઓબ્જેક્ટ છે જે UI નું વર્ણન કરે છે. VDOM ઓબ્જેક્ટમાં એવી પ્રોપર્ટીઝ હોય છે જે વાસ્તવિક DOM એલિમેન્ટના એટ્રિબ્યુટ્સને પ્રતિબિંબિત કરે છે. ઉદાહરણ તરીકે, એક સરળ `
{ type: 'div', props: { className: 'container', children: 'Hello World' } }
કારણ કે આ ફક્ત જાવાસ્ક્રિપ્ટ ઓબ્જેક્ટ્સ છે, તેમને બનાવવા અને તેમાં ફેરફાર કરવાનું અત્યંત ઝડપી છે. તેમાં બ્રાઉઝર API સાથે કોઈ ક્રિયાપ્રતિક્રિયા શામેલ નથી, તેથી કોઈ રિફ્લો કે રિપેઈન્ટ થતા નથી.
વર્ચ્યુઅલ DOM કેવી રીતે કામ કરે છે?
VDOM UI ડેવલપમેન્ટ માટે એક ઘોષણાત્મક (declarative) અભિગમ સક્ષમ કરે છે. બ્રાઉઝરને કેવી રીતે DOM બદલવું તે સ્ટેપ-બાય-સ્ટેપ કહેવાને બદલે (આજ્ઞાત્મક - imperative), તમે ફક્ત જાહેર કરો છો કે આપેલ સ્ટેટ માટે UI કેવું દેખાવું જોઈએ (ઘોષણાત્મક - declarative). બાકીનું કામ રિએક્ટ સંભાળે છે.
પ્રક્રિયા આના જેવી દેખાય છે:
અપડેટ્સને બેચ કરીને, રિએક્ટ ધીમા DOM સાથે સીધી ક્રિયાપ્રતિક્રિયા ઘટાડે છે, જે પર્ફોર્મન્સમાં નોંધપાત્ર સુધારો કરે છે. આ કાર્યક્ષમતાનો મુખ્ય ભાગ "ડિફિંગ" સ્ટેપમાં રહેલો છે, જેને ઔપચારિક રીતે રિકન્સિલિએશન એલ્ગોરિધમ તરીકે ઓળખવામાં આવે છે.
રિએક્ટનું હૃદય: રિકન્સિલિએશન એલ્ગોરિધમ
રિકન્સિલિએશન એ એવી પ્રક્રિયા છે જેના દ્વારા રિએક્ટ નવીનતમ કમ્પોનન્ટ ટ્રી સાથે મેચ કરવા માટે DOM ને અપડેટ કરે છે. આ સરખામણી કરનાર એલ્ગોરિધમને આપણે "ડિફિંગ એલ્ગોરિધમ" કહીએ છીએ.
સૈદ્ધાંતિક રીતે, એક ટ્રીને બીજામાં રૂપાંતરિત કરવા માટે ન્યૂનતમ સંખ્યામાં રૂપાંતરણો શોધવી એ એક ખૂબ જ જટિલ સમસ્યા છે, જેની એલ્ગોરિધમ જટિલતા O(n³) ના ક્રમમાં છે, જ્યાં n એ ટ્રીમાં નોડ્સની સંખ્યા છે. આ વાસ્તવિક દુનિયાની એપ્લિકેશન્સ માટે ખૂબ ધીમું હશે. આને ઉકેલવા માટે, રિએક્ટની ટીમે વેબ એપ્લિકેશન્સ સામાન્ય રીતે કેવી રીતે વર્તે છે તે વિશે કેટલાક ઉત્તમ અવલોકનો કર્યા અને એક હિઉરિસ્ટિક એલ્ગોરિધમ અમલમાં મૂક્યો જે ઘણો ઝડપી છે—O(n) સમયમાં કાર્ય કરે છે.
હિઉરિસ્ટિક્સ: ડિફિંગને ઝડપી અને અનુમાનિત બનાવવું
રિએક્ટનું ડિફિંગ એલ્ગોરિધમ બે પ્રાથમિક ધારણાઓ અથવા હિઉરિસ્ટિક્સ પર બનેલું છે:
હિઉરિસ્ટિક 1: અલગ પ્રકારના એલિમેન્ટ્સ અલગ ટ્રી ઉત્પન્ન કરે છે
આ પહેલો અને સૌથી સીધો નિયમ છે. બે VDOM નોડ્સની તુલના કરતી વખતે, રિએક્ટ પ્રથમ તેમના પ્રકારને જુએ છે. જો રૂટ એલિમેન્ટ્સનો પ્રકાર અલગ હોય, તો રિએક્ટ ધારે છે કે ડેવલપર એકને બીજામાં રૂપાંતરિત કરવાનો પ્રયાસ કરવા માંગતો નથી. તેના બદલે, તે વધુ કઠોર પરંતુ અનુમાનિત અભિગમ અપનાવે છે:
ઉદાહરણ તરીકે, આ ફેરફારને ધ્યાનમાં લો:
પહેલાં: <div><Counter /></div>
પછી: <span><Counter /></span>
ભલે ચાઈલ્ડ `Counter` કમ્પોનન્ટ સમાન હોય, રિએક્ટ જુએ છે કે રૂટ `div` થી `span` માં બદલાઈ ગયું છે. તે જૂના `div` અને તેની અંદરના `Counter` ઇન્સ્ટન્સને સંપૂર્ણપણે અનમાઉન્ટ કરશે (તેનું સ્ટેટ ગુમાવશે) અને પછી એક નવું `span` અને `Counter` નું એકદમ નવું ઇન્સ્ટન્સ માઉન્ટ કરશે.
મુખ્ય શીખ: જો તમે કમ્પોનન્ટ સબટ્રીનું સ્ટેટ સાચવવા માંગતા હો અથવા તે સબટ્રીનું સંપૂર્ણ રી-રેન્ડર ટાળવા માંગતા હો, તો તેના રૂટ એલિમેન્ટનો પ્રકાર બદલવાનું ટાળો.
હિઉરિસ્ટિક 2: ડેવલપર્સ `key` પ્રોપ વડે સ્થિર એલિમેન્ટ્સનો સંકેત આપી શકે છે
આ દલીલપૂર્વક ડેવલપર્સ માટે સમજવા અને યોગ્ય રીતે લાગુ કરવા માટે સૌથી નિર્ણાયક હિઉરિસ્ટિક છે. જ્યારે રિએક્ટ ચાઈલ્ડ એલિમેન્ટ્સની લિસ્ટની તુલના કરે છે, ત્યારે તેનું ડિફોલ્ટ વર્તન એ છે કે બંને લિસ્ટના ચિલ્ડ્રન પર એક જ સમયે પુનરાવર્તન કરવું અને જ્યાં પણ તફાવત હોય ત્યાં મ્યુટેશન જનરેટ કરવું.
ઇન્ડેક્સ-આધારિત ડિફિંગ સાથેની સમસ્યા
ચાલો કલ્પના કરીએ કે આપણી પાસે આઇટમ્સની લિસ્ટ છે અને આપણે કીનો ઉપયોગ કર્યા વિના લિસ્ટની શરૂઆતમાં એક નવી આઇટમ ઉમેરીએ છીએ.
પ્રારંભિક લિસ્ટ:
અપડેટ થયેલ લિસ્ટ (શરૂઆતમાં 'આઇટમ A' ઉમેરો):
કી વિના, રિએક્ટ એક સરળ, ઇન્ડેક્સ-આધારિત સરખામણી કરે છે:
આ અત્યંત બિનકાર્યક્ષમ છે. રિએક્ટે બે બિનજરૂરી મ્યુટેશન્સ અને એક ઇન્સર્શન કર્યું છે, જ્યારે જરૂર માત્ર શરૂઆતમાં એક જ ઇન્સર્શનની હતી. જો આ લિસ્ટ આઇટમ્સ તેમના પોતાના સ્ટેટ સાથે જટિલ કમ્પોનન્ટ્સ હોત, તો આ ગંભીર પર્ફોર્મન્સ સમસ્યાઓ અને બગ્સ તરફ દોરી શકે છે, કારણ કે સ્ટેટ કમ્પોનન્ટ્સ વચ્ચે ભળી શકે છે.
`key` પ્રોપની શક્તિ
`key` પ્રોપ એક ઉકેલ પૂરો પાડે છે. તે એક વિશેષ સ્ટ્રિંગ એટ્રિબ્યુટ છે જે તમારે એલિમેન્ટ્સની લિસ્ટ બનાવતી વખતે શામેલ કરવાની જરૂર છે. કી રિએક્ટને દરેક એલિમેન્ટ માટે સ્થિર ઓળખ આપે છે.
ચાલો એ જ ઉદાહરણ પર પાછા ફરીએ, પરંતુ આ વખતે સ્થિર, અનન્ય કી સાથે:
પ્રારંભિક લિસ્ટ:
અપડેટ થયેલ લિસ્ટ:
હવે, રિએક્ટની ડિફિંગ પ્રક્રિયા ઘણી વધુ સ્માર્ટ છે:
આ ઘણું વધારે કાર્યક્ષમ છે. રિએક્ટ યોગ્ય રીતે ઓળખે છે કે તેને ફક્ત એક જ ઇન્સર્શન કરવાની જરૂર છે. 'b' અને 'c' કી સાથે સંકળાયેલા કમ્પોનન્ટ્સ સચવાય છે, તેમના આંતરિક સ્ટેટને જાળવી રાખે છે.
કી માટે નિર્ણાયક નિયમ: કી તેની સિબલિંગ્સ (એક જ સ્તરના એલિમેન્ટ્સ) વચ્ચે સ્થિર, અનુમાનિત અને અનન્ય હોવી જોઈએ. જો લિસ્ટને ક્યારેય ફરીથી ગોઠવવામાં, ફિલ્ટર કરવામાં અથવા વચ્ચેથી આઇટમ્સ ઉમેરવામાં/દૂર કરવામાં આવે, તો એરે ઇન્ડેક્સનો કી તરીકે ઉપયોગ કરવો (`items.map((item, index) =>
ઉત્ક્રાંતિ: સ્ટેકથી ફાઈબર આર્કિટેક્ચર સુધી
ઉપર વર્ણવેલ રિકન્સિલિએશન એલ્ગોરિધમ ઘણા વર્ષોથી રિએક્ટનો પાયો હતો. જોકે, તેની એક મોટી મર્યાદા હતી: તે સિંક્રોનસ અને બ્લોકિંગ હતું. આ મૂળ અમલીકરણને હવે સ્ટેક રિકન્સાઇલર તરીકે ઓળખવામાં આવે છે.
જૂની રીત: ધ સ્ટેક રિકન્સાઇલર
સ્ટેક રિકન્સાઇલરમાં, જ્યારે સ્ટેટ અપડેટ રી-રેન્ડરને ટ્રિગર કરતું, ત્યારે રિએક્ટ સંપૂર્ણ કમ્પોનન્ટ ટ્રીને રિકર્સિવલી ટ્રાવર્સ કરતું, ફેરફારોની ગણતરી કરતું, અને તેમને DOM પર લાગુ કરતું—આ બધું એક જ, અવિરત ક્રમમાં. નાના અપડેટ્સ માટે, આ ઠીક હતું. પરંતુ મોટા કમ્પોનન્ટ ટ્રી માટે, આ પ્રક્રિયા નોંધપાત્ર સમય લઈ શકતી (દા.ત., 16ms થી વધુ), બ્રાઉઝરની મુખ્ય થ્રેડને બ્લોક કરી દેતી. આનાથી UI બિનપ્રતિભાવશીલ બની જતું, જેના કારણે ફ્રેમ્સ ડ્રોપ થતી, એનિમેશનમાં ઝટકા આવતા અને ખરાબ વપરાશકર્તા અનુભવ થતો.
રિએક્ટ ફાઈબરનો પરિચય (રિએક્ટ 16+)
આ સમસ્યાને ઉકેલવા માટે, રિએક્ટ ટીમે મુખ્ય રિકન્સિલિએશન એલ્ગોરિધમને સંપૂર્ણપણે ફરીથી લખવા માટે એક બહુ-વર્ષીય પ્રોજેક્ટ હાથ ધર્યો. તેનું પરિણામ, રિએક્ટ 16 માં રિલીઝ થયું, તેને રિએક્ટ ફાઈબર કહેવામાં આવે છે.
ફાઈબર આર્કિટેક્ચરને શરૂઆતથી જ કન્કરન્સીને સક્ષમ કરવા માટે ડિઝાઇન કરવામાં આવ્યું હતું—એટલે કે રિએક્ટની એક સાથે અનેક કાર્યો પર કામ કરવાની અને પ્રાથમિકતાના આધારે તેમની વચ્ચે સ્વિચ કરવાની ક્ષમતા.
"ફાઈબર" એ એક સાદો જાવાસ્ક્રિપ્ટ ઓબ્જેક્ટ છે જે કામના એકમનું પ્રતિનિધિત્વ કરે છે. તે એક કમ્પોનન્ટ, તેના ઇનપુટ (props), અને તેના આઉટપુટ (children) વિશેની માહિતી ધરાવે છે. રિકર્સિવ ટ્રાવર્સલ જેને અટકાવી શકાતું ન હતું તેને બદલે, રિએક્ટ હવે એક સમયે એક, ફાઈબર નોડ્સની લિંક્ડ લિસ્ટ પર પ્રક્રિયા કરે છે.
આ નવા આર્કિટેક્ચરે ઘણી મુખ્ય ક્ષમતાઓને અનલૉક કરી છે:
ફાઈબરના બે તબક્કા
ફાઈબર હેઠળ, રેન્ડરિંગ પ્રક્રિયા બે અલગ-અલગ તબક્કામાં વહેંચાયેલી છે:
ફાઈબર આર્કિટેક્ચર રિએક્ટની ઘણી આધુનિક સુવિધાઓનો પાયો છે, જેમાં `Suspense`, કન્કરન્ટ રેન્ડરિંગ, `useTransition`, અને `useDeferredValue` નો સમાવેશ થાય છે, જે બધા ડેવલપર્સને વધુ પ્રતિભાવશીલ અને સરળ યુઝર ઇન્ટરફેસ બનાવવામાં મદદ કરે છે.
ડેવલપર્સ માટે વ્યવહારુ ઓપ્ટિમાઇઝેશન વ્યૂહરચનાઓ
રિએક્ટની રિકન્સિલિએશન પ્રક્રિયાને સમજવું તમને વધુ પર્ફોર્મન્ટ કોડ લખવાની શક્તિ આપે છે. અહીં કેટલીક કાર્યક્ષમ વ્યૂહરચનાઓ છે:
૧. લિસ્ટ માટે હંમેશા સ્થિર અને અનન્ય કીનો ઉપયોગ કરો
આના પર પૂરતો ભાર મૂકી શકાતો નથી. લિસ્ટ માટે આ સૌથી મહત્વપૂર્ણ ઓપ્ટિમાઇઝેશન છે. તમારા ડેટામાંથી એક અનન્ય ID નો ઉપયોગ કરો (દા.ત., `product.id`). જ્યાં સુધી લિસ્ટ સંપૂર્ણપણે સ્થિર ન હોય અને ક્યારેય બદલાશે નહીં ત્યાં સુધી એરે ઇન્ડેક્સનો ઉપયોગ કરવાનું ટાળો.
૨. બિનજરૂરી રી-રેન્ડર્સ ટાળો
એક કમ્પોનન્ટ ત્યારે રી-રેન્ડર થાય છે જો તેનું સ્ટેટ બદલાય અથવા તેનું પેરેન્ટ રી-રેન્ડર થાય. કેટલીકવાર, એક કમ્પોનન્ટ ત્યારે પણ રી-રેન્ડર થાય છે જ્યારે તેનું આઉટપુટ સમાન જ હોત. તમે આને રોકવા માટે આનો ઉપયોગ કરી શકો છો:
૩. સ્માર્ટ કમ્પોનન્ટ કમ્પોઝિશન
તમે તમારા કમ્પોનન્ટ્સની રચના કેવી રીતે કરો છો તેની પર્ફોર્મન્સ પર નોંધપાત્ર અસર થઈ શકે છે. જો તમારા કમ્પોનન્ટના સ્ટેટનો કોઈ ભાગ વારંવાર અપડેટ થાય છે, તો તેને જે ભાગો નથી થતા તેનાથી અલગ કરવાનો પ્રયાસ કરો.
ઉદાહરણ તરીકે, એક જ મોટા કમ્પોનન્ટમાં જ્યાં વારંવાર બદલાતું ઇનપુટ ફિલ્ડ સમગ્ર કમ્પોનન્ટને રી-રેન્ડર કરાવે છે, તેના બદલે તે સ્ટેટને તેના પોતાના નાના કમ્પોનન્ટમાં ઉઠાવો. આ રીતે, જ્યારે વપરાશકર્તા ટાઇપ કરે છે ત્યારે ફક્ત નાનો કમ્પોનન્ટ જ રી-રેન્ડર થાય છે.
૪. લાંબી લિસ્ટને વર્ચ્યુઅલાઈઝ કરો
જો તમારે સેંકડો કે હજારો આઇટમ્સવાળી લિસ્ટ રેન્ડર કરવાની જરૂર હોય, તો પણ યોગ્ય કી સાથે, તે બધાને એક જ સમયે રેન્ડર કરવું ધીમું હોઈ શકે છે અને ઘણી બધી મેમરીનો વપરાશ કરી શકે છે. તેનો ઉકેલ વર્ચ્યુઅલાઈઝેશન અથવા વિન્ડોઇંગ છે. આ તકનીકમાં ફક્ત તે નાનો સબસેટ રેન્ડર કરવાનો સમાવેશ થાય છે જે હાલમાં વ્યુપોર્ટમાં દૃશ્યમાન છે. જેમ જેમ વપરાશકર્તા સ્ક્રોલ કરે છે, જૂની આઇટમ્સ અનમાઉન્ટ થાય છે, અને નવી આઇટમ્સ માઉન્ટ થાય છે. `react-window` અને `react-virtualized` જેવી લાઇબ્રેરીઓ આ પેટર્નને અમલમાં મૂકવા માટે શક્તિશાળી અને ઉપયોગમાં સરળ કમ્પોનન્ટ્સ પ્રદાન કરે છે.
નિષ્કર્ષ
રિએક્ટનું પર્ફોર્મન્સ કોઈ અકસ્માત નથી; તે વર્ચ્યુઅલ DOM અને એક કાર્યક્ષમ રિકન્સિલિએશન એલ્ગોરિધમ પર કેન્દ્રિત એક ઇરાદાપૂર્વક અને અત્યાધુનિક આર્કિટેક્ચરનું પરિણામ છે. સીધા DOM મેનીપ્યુલેશનને એબ્સ્ટ્રેક્ટ કરીને, રિએક્ટ અપડેટ્સને એવી રીતે બેચ અને ઓપ્ટિમાઇઝ કરી શકે છે જે મેન્યુઅલી મેનેજ કરવું અત્યંત જટિલ હશે.
ડેવલપર્સ તરીકે, આપણે આ પ્રક્રિયાનો એક નિર્ણાયક ભાગ છીએ. ડિફિંગ એલ્ગોરિધમના હિઉરિસ્ટિક્સને સમજીને—યોગ્ય રીતે કીનો ઉપયોગ કરીને, કમ્પોનન્ટ્સ અને વેલ્યુઝને મેમોઇઝ કરીને, અને આપણી એપ્લિકેશન્સને વિચારપૂર્વક ગોઠવીને—આપણે રિએક્ટના રિકન્સાઇલર સાથે કામ કરી શકીએ છીએ, તેની વિરુદ્ધ નહીં. ફાઈબર આર્કિટેક્ચરની ઉત્ક્રાંતિએ જે શક્ય છે તેની સીમાઓને વધુ આગળ ધપાવી છે, જે ફ્લુઇડ અને પ્રતિભાવશીલ UI ની નવી પેઢીને સક્ષમ બનાવે છે.
આગલી વખતે જ્યારે તમે સ્ટેટ ફેરફાર પછી તમારા UI ને તરત જ અપડેટ થતું જુઓ, ત્યારે પડદા પાછળ થતા વર્ચ્યુઅલ DOM, ડિફિંગ એલ્ગોરિધમ અને કમિટ તબક્કાના સુંદર નૃત્યની પ્રશંસા કરવા માટે એક ક્ષણ લો. આ સમજણ વૈશ્વિક પ્રેક્ષકો માટે ઝડપી, વધુ કાર્યક્ષમ અને વધુ મજબૂત રિએક્ટ એપ્લિકેશન્સ બનાવવા માટે તમારી ચાવી છે.