प्रॉम्प्ट और लागू होने वाले परिदृश्य
एक उत्पाद गतिविधि फ़ीड 100,000 लॉजिकल आइटम तक बढ़ सकती है। इसका कर्सर API प्रति अनुरोध 50 आइटम लौटाता है। टेक्स्ट रैप होने, इमेज लोड होने या विवरण विस्तृत होने के बाद एक कार्ड 48 से 240 पिक्सेल ऊँचा हो सकता है। उपयोगकर्ता फ़ीड को फ़िल्टर कर सकते हैं, कार्ड विस्तृत कर सकते हैं और इनलाइन उत्तर ड्राफ़्ट कर सकते हैं। कीबोर्ड और स्क्रीन-रीडर उपयोगकर्ताओं को फ़ोकस या स्थिति की जानकारी खोए बिना फ़ीड में आगे बढ़ने में सक्षम होना चाहिए।
रेंडरिंग रेंज, परिवर्तनीय-ऊँचाई मापन, वृद्धिशील लोडिंग, स्टेट ओनरशिप, स्क्रॉल एंकरिंग, फ़ोकस व्यवहार, एक्सेसिबिलिटी सेमांटिक्स और वैलिडेशन योजना डिज़ाइन करें। स्पष्ट करें कि एक सरल पेजिनेटेड या गैर-वर्चुअलाइज़्ड लिस्ट कब बेहतर विकल्प होती है।
आइटम की संख्या, पेज का आकार और ऊँचाई की सीमा इंटरव्यू की धारणाएँ हैं, सार्वभौमिक उत्पाद लक्ष्य नहीं। यह प्रश्न वरिष्ठ फ़्रंटएंड, UI इन्फ्रास्ट्रक्चर और वेब प्रदर्शन भूमिकाओं के लिए उपयुक्त है। इसका मुख्य कौशल ब्राउज़र रेंडरिंग और इंटरैक्शन डिज़ाइन है, इसलिए श्रेणी frontend है।
इंटरव्यूअर क्या मूल्यांकन करता है
पहला, क्या उम्मीदवार उन चार चिंताओं को अलग कर सकता है जो अक्सर एक साथ मिला दी जाती हैं? पेजिनेशन नियंत्रित करता है कि क्लाइंट ने कौन से रिकॉर्ड लोड किए हैं। वर्चुअलाइज़ेशन नियंत्रित करता है कि किन लोड किए गए रिकॉर्ड में DOM नोड्स हैं। स्थिर पहचान (Stable identity) नियंत्रित करती है कि किस व्यावसायिक रिकॉर्ड के पास स्टेट है। एक्सेसिबिलिटी नियंत्रित करती है कि आंशिक DOM लॉजिकल संग्रह का प्रतिनिधित्व कैसे करता है। एक तंत्र अन्य तीन को हल नहीं करता है।
दूसरा, क्या उम्मीदवार पंक्ति-आकार की धारणाओं से रेंज गणित निकाल सकता है? समान-ऊँचाई वाली पंक्तियाँ सीधे ऑफ़सेट अंकगणित की अनुमति देती हैं। परिवर्तनीय-ऊँचाई वाली पंक्तियों के लिए अनुमान, मापे गए आकार, संचयी ऑफ़सेट (cumulative offsets) और अनुमान बदलने पर एक सुधार नीति की आवश्यकता होती है। एक मजबूत उत्तर व्यूपोर्ट के ऊपर बदलते कंटेंट के कारण होने वाले स्क्रॉल जंप का नाम लेता है और एक लॉजिकल एंकर को सुरक्षित रखता है।
तीसरा, क्या उम्मीदवार स्टेट के दूषित होने से बच सकता है? एक पुनर्चक्रित (recycled) विज़ुअल स्लॉट कोई व्यावसायिक रिकॉर्ड नहीं है। ड्राफ़्ट, चयन, विस्तार और लंबित म्यूटेशन को स्थिर रिकॉर्ड ID और ऐसी स्थिति की आवश्यकता होती है जो पंक्ति के अनमाउंट होने पर भी बची रहे। सॉर्टिंग, फ़िल्टरिंग और पुराने पेज प्रतिक्रियाओं को गलत इंडेक्स में डेटा या स्थिति संलग्न नहीं करनी चाहिए।
चौथा, क्या उम्मीदवार एक्सेसिबिलिटी को अक्षुण्ण रख सकता है? केवल दृश्यमान कार्ड माउंट करने से DOM से अधिकांश लॉजिकल सेट हट जाता है। एक मजबूत उत्तर मूल या फ़ीड सेमांटिक्स को सुरक्षित रखता है, लॉजिकल स्थिति और सेट आकार को उजागर करता है, व्यस्त स्थिति की सही घोषणा करता है, केंद्रित कार्ड को माउंट रखता है और एक संचालन योग्य लोडिंग पथ प्रदान करता है।
पाँचवाँ, क्या उम्मीदवार "स्मूद स्क्रॉलिंग" का वादा करने के बजाय व्यवहार को सत्यापित कर सकता है? उत्तर को लक्षित उपकरणों और परिदृश्यों को परिभाषित करना चाहिए, फिर माउंट किए गए नोड की संख्या, फ़्रेम और लंबे-कार्य (long-task) व्यवहार, लेआउट शिफ्ट या एंकर त्रुटि, अनुरोध दोहराव, मेमोरी, फ़ोकस प्रतिधारण और स्क्रीन-रीडर आउटपुट को मापना चाहिए।
पहले स्पष्ट करने योग्य प्रश्न
- क्या लिस्ट वर्चुअलाइज़ेशन के बिना वास्तव में धीमी है? यदि उत्पाद अधिक से अधिक कुछ दर्जन सरल पंक्तियाँ दिखाता है, तो सामान्य रेंडरिंग या पेजिनेशन को बनाए रखना आसान है और अधिक सुलभ है। विंडोइंग जोड़ने से पहले मापें।
- क्या पंक्ति की ऊँचाइयाँ निश्चित, सीमित या मनमानी हैं? निश्चित ऊँचाइयाँ स्थिर-समय रेंज गणित की अनुमति देती हैं। परिवर्तनीय ऊँचाइयों के लिए अनुमान और मापन की आवश्यकता होती है। असीमित एम्बेड या देर से आने वाला मीडिया स्क्रॉल सुधार को कठिन बनाते हैं और विवश कार्ड लेआउट को उचित ठहरा सकते हैं।
- क्या API कुल संख्या को उजागर करता है या केवल एक अगला कर्सर देता है? एक ज्ञात कुल एक पूर्ण लॉजिकल सेट आकार का समर्थन कर सकता है। एक अज्ञात कुल स्क्रॉलबार अपेक्षाओं और एक्सेसिबिलिटी मेटाडेटा को बदल देता है। कर्सर पेजिनेशन का अर्थ यह भी है कि अनलोड किए गए इंडेक्स सीधे एड्रेस करने योग्य नहीं हैं।
- क्या उपयोगकर्ताओं को किसी मनमाने आइटम पर कूदना होगा? परिवर्तनीय, अधिकतर अनमापी पंक्तियों के साथ इंडेक्स द्वारा कूदना तब तक अनुमानित है जब तक कि आस-पास की पंक्तियों को मापा न जाए। रिकॉर्ड ID द्वारा कूदने के लिए सर्वर लुकअप या भिन्न API की आवश्यकता हो सकती है।
- अनमाउंट होने के बाद कौन सी पंक्ति स्थिति बची रहनी चाहिए? अस्थायी होवर गायब हो सकता है। ड्राफ़्ट उत्तर, चयन, विस्तार, सत्यापन त्रुटियाँ और आशावादी म्यूटेशन आमतौर पर पंक्ति घटक के बाहर रिकॉर्ड ID द्वारा कीड स्थिति में होते हैं।
- कौन सा कीबोर्ड मॉडल और सेमांटिक्स लागू होते हैं? एक रीडिंग फ़ीड, चयन योग्य लिस्टबॉक्स और संपादन योग्य ग्रिड की अलग-अलग भूमिकाएँ और कीबोर्ड अनुबंध होते हैं। सेमांटिक पैटर्न को इंटरैक्शन से चुनें, विज़ुअल लेआउट से नहीं।
- डेटा बदलने पर स्क्रॉल अनुबंध क्या है? फ़िल्टर करने के बाद, उत्पाद शीर्ष पर रीसेट हो सकता है। जब पुराने आइटम पहले जोड़े जाते हैं (prepended), तो यह आमतौर पर वर्तमान पहले दृश्यमान आइटम को सुरक्षित रखता है। जब लाइव आइटम जोड़े जाते हैं, तो यह केवल तभी अनुसरण करता है जब उपयोगकर्ता पहले से ही अंत में था।
- प्रदर्शन स्वीकृति लक्ष्य क्या हैं? लक्षित उपकरणों, डेटा आकार, स्क्रॉल क्रियाओं और बजटों का नाम दें। छोटी प्लेसहोल्डर पंक्तियों पर एक डेस्कटॉप ट्रेस इमेज और नियंत्रणों वाले मोबाइल फ़ीड को मान्य नहीं करता है।
30-सेकंड का उत्तर ढाँचा
"मैं डेटा लोडिंग, वर्चुअलाइज़ेशन और पंक्ति स्थिति को अलग रखूँगा। कर्सर लोडर 50-आइटम वाले पेजों को फ़ेच और डुप्लिकेट-मुक्त करता है। वर्चुअलाइज़र केवल दृश्यमान रेंज और एक छोटे ओवरस्कैन को रेंडर करता है और उन पंक्तियों को एक स्पेसर के अंदर रखता है जिसकी ऊँचाई लोड किए गए डेटा का प्रतिनिधित्व करती है। निश्चित पंक्तियाँ ऑफ़सेट अंकगणित का उपयोग करती हैं; परिवर्तनीय पंक्तियाँ अनुमानों से शुरू होती हैं, लेआउट के बाद मापी जाती हैं और संचयी ऑफ़सेट को अपडेट करती हैं। जब व्यूपोर्ट से पहले की ऊँचाई बदलती है, तो मैं पहले दृश्यमान रिकॉर्ड और उसके इंट्रा-रो ऑफ़सेट को सुरक्षित रखता हूँ ताकि स्क्रीन जंप न करे। प्रत्येक पंक्ति रिकॉर्ड ID का उपयोग करती है, जबकि ड्राफ़्ट और चयन पंक्ति के बाहर रहते हैं। एक गतिविधि फ़ीड के लिए, मैं फ़ीड और आर्टिकल सेमांटिक्स, लॉजिकल स्थिति और सेट आकार, व्यस्त स्थिति को उजागर करूँगा और फ़ोकस वाले कार्ड को कभी भी अनमाउंट नहीं करूँगा। मैं तेज़ स्क्रॉल, इमेज और विस्तार परिवर्तन, फ़िल्टर रेस, प्रीपेंड और अपेंड व्यवहार, कीबोर्ड और स्क्रीन-रीडर नेविगेशन, नोड संख्या, लंबे कार्य, मेमोरी और एंकर त्रुटि का परीक्षण करूँगा। यदि साधारण रेंडरिंग पहले से ही बजट को पूरा करती है, तो मैं सरल लिस्ट रखूँगा।"
चरण-दर-चरण गहन विश्लेषण
चरण 1: लोड किए गए रिकॉर्ड को माउंट की गई पंक्तियों से अलग करें
डेटा परत के लिए स्पष्ट स्थिति बनाए रखें: क्रमित रिकॉर्ड ID, ID से रिकॉर्ड का मैप, अगला कर्सर, अनुरोध स्थिति और क्या अधिक डेटा मौजूद है। वर्चुअलाइज़र क्रमित लोड की गई ID और एक स्क्रॉल कंटेनर प्राप्त करता है। यह कर्सर, पुनः प्रयास (retries), ड्राफ़्ट या सर्वर म्यूटेशन का स्वामी नहीं है।
कर्सर API के साथ, प्रारंभ में केवल 50 रिकॉर्ड एड्रेस करने योग्य होते हैं। लोड किए गए उपसर्ग को वर्चुअलाइज़ करें और पेज आने पर इसकी लॉजिकल ऊँचाई बढ़ाएँ। यह दिखावा न करें कि अनलोड किया गया इंडेक्स 73,421 स्थानीय रूप से उपलब्ध है जब तक कि API अनुक्रमित पहुँच का समर्थन नहीं करता है या स्थिर स्थितियों वाले प्लेसहोल्डर नहीं लौटाता है। दृश्यमान रेंज एक फ़ेच को ट्रिगर कर सकती है जब इसका अंत लोड की गई संख्या के करीब पहुँचता है, लेकिन लोडर अनुरोधों को संयोजित करने और अंत में रुकने के लिए जिम्मेदार रहता है।
यह अलगाव दो सामान्य बगों को रोकता है: अनंत लोडिंग जो हजारों पुराने DOM नोड्स को माउंट छोड़ देती है, और एक वर्चुअलाइज़र जो हर बार अपनी छोटी रेंज की पुनर्गणना होने पर डुप्लिकेट अनुरोध फ़ायर करता है।
चरण 2: परिवर्तनीय ऊँचाइयों को जोड़ने से पहले निश्चित-ऊँचाई रेंज प्राप्त करें
समान-ऊँचाई वाली पंक्तियों के लिए, scrollTop, व्यूपोर्ट ऊँचाई और पंक्ति ऊँचाई से पहले और अंतिम दृश्यमान इंडेक्स प्राप्त करें। ओवरस्कैन सीमा का विस्तार करता है लेकिन लोड की गई संख्या तक सीमित रहता है। एक पूर्ण-ऊँचाई वाला आंतरिक कैनवास स्क्रॉलबार बनाता है; माउंट की गई पंक्तियों को उनके लॉजिकल ऑफ़सेट पर स्थित किया जाता है।
function getFixedRange({
scrollTop,
viewportHeight,
rowHeight,
loadedCount,
overscanRows,
}) {
const visibleStart = Math.floor(scrollTop / rowHeight);
const visibleEnd = Math.ceil(
(scrollTop + viewportHeight) / rowHeight,
);
return {
start: Math.max(0, visibleStart - overscanRows),
end: Math.min(loadedCount, visibleEnd + overscanRows),
totalHeight: loadedCount * rowHeight,
};
}start से end तक आधे-खुले अंतराल को रेंडर करें, जिसमें end शामिल नहीं है। इंडेक्स i पर एक पंक्ति i * rowHeight पर शुरू होती है। स्क्रॉल कंटेनर से रेंज अपडेट करें, फ़्रेमवर्क के साथ बैच रेंडरिंग करें और एक स्क्रॉल कॉलबैक के अंदर लेआउट को बार-बार पढ़ने और शैलियों को लिखने से बचें।
यह समाधान तब बेहतर होता है जब डिज़ाइन एक पंक्ति ऊँचाई या ज्ञात वेरिएंट की एक छोटी संख्या को लागू कर सकता है। यह पूर्वानुमेय, सस्ता और पुनर्स्थापित करने में आसान है। केवल इसलिए गतिशील मापन न अपनाएँ क्योंकि लाइब्रेरी इसकी पेशकश करती है।
चरण 3: परिवर्तनीय पंक्तियों को मापें और संचयी ऑफ़सेट बनाए रखें
परिवर्तनीय पंक्तियाँ गुणन को एक आकार मॉडल से बदल देती हैं। प्रत्येक अनमापी पंक्ति को वास्तविक कार्ड डिज़ाइन के आधार पर एक उचित अनुमान के साथ शुरू करें। मापे गए आकारों को रिकॉर्ड ID द्वारा रखें, न कि पुनर्चक्रित DOM स्लॉट द्वारा। किसी आइटम का प्रारंभिक ऑफ़सेट पूर्ववर्ती आकारों का योग होता है, इसलिए पहले दृश्यमान आइटम को ढूँढना संचयी ऑफ़सेट पर एक खोज बन जाता है।
एक साधारण प्रीफ़िक्स ऐरे की व्याख्या करना आसान है, लेकिन एक ऊँचाई बदलने पर कई बाद के ऑफ़सेट को अपडेट करने की आवश्यकता हो सकती है। एक वर्चुअलाइज़र लाइब्रेरी या एक अनुक्रमित प्रीफ़िक्स-सम संरचना खोज और अपडेट कार्य को कम कर सकती है। महत्वपूर्ण इंटरव्यू निर्णय इनवेरिएंट है: प्रत्येक रेंडर की गई पंक्ति का एक ही आकार स्टोर से प्राप्त लॉजिकल स्टार्ट ऑफ़सेट होता है, और कुल कैनवास ऊँचाई वर्तमान मापे गए या अनुमानित आकारों के योग के बराबर होती है।
पंक्ति लेआउट के बाद ResizeObserver या लाइब्रेरी के माप हुक का उपयोग करें। संभव होने पर ज्ञात आयामों से इमेज स्पेस आरक्षित करें; अन्यथा इमेज लोड होने से एक नया माप उत्पन्न होता है। अपरिवर्तित आकारों पर ध्यान न दें, सुधारों को बैच करें और अनमाउंट होने वाली पंक्तियों के लिए ऑब्ज़र्वर को डिस्कनेक्ट करें। जब चौड़ाई, फ़ॉन्ट मेट्रिक्स, विस्तार या कंटेंट परिवर्तन ऊँचाई बदल सकते हैं, तो फिर से मापें।
अनुमानों के गलत होने की अनुमति है। सिस्टम तब विफल हो जाता है जब वह इस नीति के बिना ऑफ़सेट बदलता है कि उपयोगकर्ता को क्या देखते रहना चाहिए।
चरण 4: एक लॉजिकल स्क्रॉल एंकर को सुरक्षित रखें
आकार परिवर्तन लागू करने से पहले, पहले दृश्यमान रिकॉर्ड की ID और उसके शीर्ष किनारे से व्यूपोर्ट के शीर्ष किनारे तक की दूरी को कैप्चर करें। मापों और संचयी ऑफ़सेट को अपडेट करने के बाद, उस रिकॉर्ड की नई शुरुआत का पता लगाएँ और स्क्रॉल ऑफ़सेट सेट करें ताकि वही इंट्रा-रो बिंदु उसी दृश्य स्थान पर रहे।
यदि एंकर से पूरी तरह से ऊपर की कोई पंक्ति 30 पिक्सेल बढ़ती है, तो स्क्रॉल ऑफ़सेट को सामान्य रूप से उसी 30-पिक्सेल सुधार की आवश्यकता होती है। एंकर के नीचे एक परिवर्तन नहीं करता है। यदि उपयोगकर्ता स्क्रॉलबार खींच रहा है या उत्पाद जानबूझकर किसी नए आइटम पर नेविगेट करता है, तो उस इंटरैक्शन अनुबंध के अनुसार सुधार को टालें या छोड़ें।
ब्राउज़र सामान्य लेआउट परिवर्तनों के लिए स्क्रॉल एंकरिंग भी लागू करते हैं। एक वर्चुअलाइज़र अक्सर एक सिंथेटिक कैनवास और पूर्ण रूप से स्थित पंक्तियों का उपयोग करता है, इसलिए नेटिव व्यवहार इच्छित लॉजिकल आइटम को संरक्षित नहीं कर सकता है। संयोजन का परीक्षण करें। या तो ब्राउज़र या वर्चुअलाइज़र को किसी दिए गए कंटेनर के लिए मुआवजे का स्वामित्व लेने दें; यदि मैन्युअल एंकरिंग आधिकारिक है, तो दोहरे सुधार से बचने के लिए वहाँ नेटिव एंकरिंग से ऑप्ट आउट करें।
पुराने रिकॉर्ड को पहले जोड़ना (prepending) उसी नियम का उपयोग करता है। वर्तमान एंकर को कैप्चर करें, नए रिकॉर्ड डालें और मापें, फिर एंकर को पुनर्स्थापित करें। लाइव रिकॉर्ड जोड़ना केवल तभी अंत का अनुसरण करता है जब उपयोगकर्ता पहले से ही उत्पाद के "नवीनतम" थ्रेशोल्ड के भीतर था; अन्यथा व्यूपोर्ट को स्थानांतरित करने के बजाय "नई गतिविधि" क्रिया दिखाएँ।
चरण 5: प्रति पंक्ति कार्य और स्क्रॉल व्यवहार से ओवरस्कैन ट्यून करें
ओवरस्कैन व्यूपोर्ट के ठीक बाहर आइटम माउंट करके रेंडरिंग विलंबता को छुपाता है। बहुत कम होने पर तेज़ स्क्रॉल के दौरान खाली जगह दिखाई दे सकती है; बहुत अधिक होने पर DOM, लेआउट, मेमोरी और इफ़ेक्ट लागत फिर से बन जाती है जिसे वर्चुअलाइज़ेशन से बचना था। परिवर्तनीय ऊँचाइयों के साथ, पिक्सेल-आधारित ओवरस्कैन अक्सर एक निश्चित पंक्ति संख्या की तुलना में अधिक स्थिर होता है क्योंकि पाँच कॉम्पैक्ट पंक्तियाँ और पाँच विस्तृत पंक्तियाँ अलग-अलग कार्य और दूरी का प्रतिनिधित्व करती हैं।
रूढ़िवादी रूप से शुरू करें, लक्षित उपकरणों पर ट्रेस रिकॉर्ड करें और साक्ष्य से ट्यून करें। स्क्रॉल दिशा, वेग, पंक्ति रेंडरिंग लागत, इमेज डिकोडिंग और फ़्रेमवर्क की अपडेट विलंबता पर विचार करें। ओवरस्कैन महंगे पंक्ति कार्य को मेमोइज़ करने, मीडिया आयामों को आरक्षित करने, अप्रचलित प्रभावों को रद्द करने या सिंक्रोनस लेआउट रीड्स को कम करने का विकल्प नहीं है।
एक सख्त नोड-गणना इनवेरिएंट रखें: माउंट की गई पंक्तियाँ दृश्यमान सीमा, ओवरस्कैन और केंद्रित आइटम जैसी स्पष्ट रूप से पिन की गई पंक्तियों की एक छोटी संख्या के बराबर होती हैं। एक मेमोरी प्रोफ़ाइल को दिखाना चाहिए कि पुराने पंक्ति घटक, ऑब्ज़र्वर और इवेंट लिसनर उस सेट को छोड़ने के बाद कलेक्टिबल हो जाते हैं।
चरण 6: बिना किसी रेस या डुप्लिकेट रिकॉर्ड के पेज लोड करें
एक संतरी (sentinel) पर भरोसा करने के बजाय लॉजिकल रेंज के अंत से लोडिंग ट्रिगर करें जिसे रीसायकल किया जा सकता है। प्रति कर्सर अधिक से अधिक एक अनुरोध की अनुमति दें। प्रत्येक अनुरोध से जुड़े कर्सर को स्टोर करें, स्थिर ID द्वारा लौटाए गए रिकॉर्ड को डुप्लिकेट-मुक्त करें और सर्वर द्वारा यह कहने पर रुकें कि कोई अगला कर्सर नहीं है।
फ़िल्टरिंग या सॉर्टिंग एक नया क्वेरी जनरेशन बनाती है। संभव होने पर पिछले अनुरोध को निरस्त करें और किसी भी देर से आई प्रतिक्रिया को अस्वीकार करें जिसका जनरेशन अब मेल नहीं खाता है। ऑर्डर की गई ID, कर्सर, लेआउट या कंटेंट पर निर्भर मापों और उत्पाद अनुबंध के अनुसार स्क्रॉल स्थिति को रीसेट करें। एक नए क्रम के लिए पुराने ऑफ़सेट का पुन: उपयोग करने से सही ऊँचाइयाँ गलत स्थितियों से जुड़ जाती हैं।
लोडिंग प्लेसहोल्डर को स्थिर लॉजिकल उपचार की आवश्यकता होती है। यदि एक प्लेसहोल्डर अगले पेज के लिए खड़ा है, तो यह 50 सुलभ रिकॉर्ड नहीं है। यदि API एक ज्ञात अनुक्रमित कुल प्रदान करता है और उत्पाद प्रति-पंक्ति प्लेसहोल्डर चुनता है, तो उन्हें स्थिर स्थिति दें और पहचान बदले बिना उन्हें बदलें। हमेशा पुनः प्रयास और लिस्ट-का-अंत स्थितियों को उजागर करें; एक असफल फ़ेच को एक स्थायी खाली टेल नहीं छोड़ना चाहिए जो अंत जैसा दिखता हो।
चरण 7: रिकॉर्ड पहचान और महत्वपूर्ण स्थिति को पुनर्चक्रित पंक्तियों के बाहर रखें
प्रत्येक रिकॉर्ड की स्थिर ID को फ़्रेमवर्क कुंजी और वर्चुअलाइज़र की आइटम कुंजी के रूप में उपयोग करें। ऐरे इंडेक्स तब असुरक्षित होता है जब पेज प्रीपेंड होते हैं, फ़िल्टर रिकॉर्ड को पुनर्व्यवस्थित करते हैं या डुप्लिकेट हटा दिए जाते हैं। एक पुनर्चक्रित स्लॉट अब रिकॉर्ड A और बाद में रिकॉर्ड B प्रदर्शित कर सकता है; स्लॉट से जुड़ी स्थिति उपयोगकर्ताओं के रिकॉर्ड के बीच एक ड्राफ़्ट, चेकबॉक्स या आशावादी परिणाम लीक कर सकती है।
टिकाऊ UI स्थिति को रिकॉर्ड ID द्वारा कीड मैप के रूप में संग्रहीत करें: ड्राफ़्ट टेक्स्ट, विस्तार, चयन, सत्यापन स्थिति और लंबित म्यूटेशन। एक पंक्ति माउंट होने पर अपने हिस्से को पढ़ती है और एक स्वामी के माध्यम से लिखती है जो अनमाउंट होने पर भी जीवित रहता है। स्थानीय स्थिति डिस्पोजेबल प्रस्तुति विवरणों के लिए स्वीकार्य है जिनका नुकसान जानबूझकर किया गया है।
प्रत्येक क्षणिक मान को हमेशा के लिए बनाए न रखें। जब उत्पाद किसी क्वेरी को छोड़ देता है, तो स्थिति को हटा दें, ड्राफ़्ट प्रतिधारण को सीमित करें और सर्वर परिणामों के साथ आशावादी स्थिति का मिलान करें। लक्ष्य व्यावसायिक पहचान द्वारा स्वामित्व है, न कि एक असीमित क्लाइंट कैश।
चरण 8: रेंज एल्गोरिदम के भाग के रूप में एक्सेसिबिलिटी डिज़ाइन करें
इंटरैक्शन से सेमांटिक्स चुनें। एक रीडिंग फ़ीड के लिए, कंटेनर फ़ीड सेमांटिक्स का उपयोग कर सकता है और प्रत्येक कार्ड एक सुलभ नाम के साथ आर्टिकल सेमांटिक्स का उपयोग कर सकता है। प्रत्येक माउंट किया गया आर्टिकल अपनी एक-आधारित लॉजिकल स्थिति को उजागर करता है। यदि कुल ज्ञात है, तो लॉजिकल कुल को उजागर करें; यदि यह अज्ञात है, तो पैटर्न के अज्ञात-आकार प्रतिनिधित्व का उपयोग करें। बहु-ऑपरेशन अपडेट के दौरान फ़ीड को व्यस्त चिह्नित करें और अपडेट समाप्त होने पर हमेशा उस स्थिति को साफ़ करें।
उस तत्व को अनमाउंट न करें जिसमें DOM फ़ोकस है। फ़ोकस किए गए रिकॉर्ड को माउंट की गई रेंज में जोड़ें, भले ही वह सामान्य ओवरस्कैन से बाहर हो, या निष्कासन से पहले एक जानबूझकर नेविगेशन क्रिया के माध्यम से फ़ोकस को स्थानांतरित करें। जब कीबोर्ड कमांड अगले लॉजिकल आर्टिकल पर जाते हैं, तो सुनिश्चित करें कि यह लोड और माउंट है, इसे दृश्य में स्क्रॉल करें, फिर इसे फ़ोकस करें। किसी भी कस्टम कुंजी का दस्तावेजीकरण करें और फ़ीड से पहले और बाद में जाने के लिए एक विश्वसनीय तरीका सुरक्षित रखें।
वर्चुअलाइज़ेशन फाइंड-इन-पेज, ब्राउज़र टेक्स्ट चयन, प्रिंटिंग और स्क्रीन-रीडर ब्राउज़ व्यवहार को भी तोड़ सकता है क्योंकि स्क्रीन से बाहर की सामग्री DOM से अनुपस्थित होती है। तय करें कि क्या वे सुविधाएँ आवश्यकताएँ हैं। खोज को सर्वर-समर्थित नियंत्रण की आवश्यकता हो सकती है, प्रिंटिंग एक अलग पेजिनेटेड दृश्य प्रस्तुत कर सकती है और एक स्पष्ट "और लोड करें" नियंत्रण स्वचालित लोडिंग का एक संचालन योग्य विकल्प प्रदान कर सकता है।
अंत में, केवल-कीबोर्ड ऑपरेशन और वास्तविक स्क्रीन पाठकों के साथ परीक्षण करें। विशेषताओं का निरीक्षण करने से मार्कअप की पुष्टि होती है लेकिन यह साबित नहीं हो सकता कि फ़ोकस, घोषणाएँ, लोडिंग और नेविगेशन एक साथ काम करते हैं।
चरण 9: विफलता मैट्रिक्स को मान्य करें, न कि केवल एक स्मूद स्क्रॉल को
एक नियतात्मक (deterministic) डेटा सेट बनाएँ जिसमें छोटा और लंबा टेक्स्ट, आयामों के साथ विलंबित इमेज, विस्तार, गायब मीडिया और डुप्लिकेट ID शामिल हों। धीमी और तेज़ व्हील स्क्रॉल, टच-जैसे मोमेंटम, स्क्रॉलबार ड्रैगिंग, रीसाइज़, ज़ूम, फ़ॉन्ट लोड, अनुरोध के दौरान फ़िल्टर परिवर्तन, प्रीपेंड, अपेंड, फ़ेच विफलता, पुनः प्रयास और डेटा-के-अंत का अभ्यास करें।
पूरे रन के दौरान माउंट की गई पंक्ति और DOM नोड की संख्या रिकॉर्ड करें। फ़्रेम, लंबे कार्यों, स्क्रिप्टिंग, लेआउट, पेंट और अप्रत्याशित दोहराए गए मापों का निरीक्षण करने के लिए प्रदर्शन ट्रेस का उपयोग करें। कई पेजों पर स्क्रॉल करने के बाद पीक और रिटेन्ड मेमोरी को ट्रैक करें। ऊँचाई परिवर्तन से पहले और बाद में शीर्ष लॉजिकल एंकर की तुलना करें, और पुष्टि करें कि डुप्लिकेट कर्सर और ID दिखाई नहीं देते हैं।
इंटरैक्शन के लिए, एक पंक्ति में फ़ोकस रखें, पॉइंटर और कीबोर्ड के साथ स्क्रॉल करें, इसके ऊपर की पंक्तियों को विस्तृत करें, अगला पेज लोड करें और फ़िल्टर बदलें। सत्यापित करें कि फ़ोकस कहाँ आता है और क्या ड्राफ़्ट सही ID से जुड़े रहते हैं। स्क्रीन रीडर के साथ, आर्टिकल के नाम, लॉजिकल स्थिति और सेट आकार, व्यस्त ट्रांज़िशन, अगला और पिछला नेविगेशन, पुनः प्रयास और अंतिम स्थिति सत्यापित करें।
स्वीकृति लक्ष्य उत्पाद और लक्षित उपकरणों का है। यह दावा करने के बजाय कि वर्चुअलाइज़ेशन एक विशेष फ़्रेम दर की गारंटी देता है, मापे गए ट्रेस और इनवेरिएंट उल्लंघनों की रिपोर्ट करें।
उच्च गुणवत्ता वाला नमूना उत्तर
"मैं फ़ीड को तीन परतों के रूप में मॉडल करूँगा। डेटा परत ऑर्डर की गई ID, रिकॉर्ड, अगले कर्सर, अनुरोध जनरेशन और डिडुप्लीकेशन का स्वामित्व रखती है। वर्चुअलाइज़र केवल लोड की गई ID प्राप्त करता है और दृश्यमान रेंज, मापों और स्थिति का स्वामित्व रखता है। ड्राफ़्ट, विस्तार, चयन और म्यूटेशन रिकॉर्ड ID द्वारा कीड मैप में रहते हैं ताकि किसी पंक्ति को अनमाउंट करने से वे हटें या स्थानांतरित न हों।
निश्चित पंक्तियों के लिए, रेंज प्रत्यक्ष ऑफ़सेट अंकगणित है और कैनवास की ऊँचाई लोड की गई संख्या गुणा पंक्ति ऊँचाई है। ये कार्ड 48 से 240 पिक्सेल तक भिन्न होते हैं, इसलिए मैं अनुमानों से शुरू करूँगा, माउंट किए गए कार्डों को मापूँगा और संचयी ऑफ़सेट बनाए रखूँगा। पहला दृश्यमान रिकॉर्ड और उसका इंट्रा-रो ऑफ़सेट स्क्रॉल एंकर बनाते हैं। जब उस रिकॉर्ड के ऊपर कोई माप बदलता है, तो मैं परिणामी डेल्टा द्वारा स्क्रॉल ऑफ़सेट को अपडेट करता हूँ। मैं कंटेनर के लिए एक मुआवज़ा स्वामी चुनूँगा ताकि नेटिव और मैन्युअल स्क्रॉल एंकरिंग दोनों इसे समायोजित न करें।
रेंज में एक छोटा मापा गया ओवरस्कैन और कोई भी फ़ोकस किया गया कार्ड शामिल होता है। जब इसका अंत लोड की गई संख्या के करीब पहुँचता है, तो लोडर अगले कर्सर का एक बार अनुरोध करता है। एक फ़िल्टर परिवर्तन एक नया जनरेशन शुरू करता है, जहाँ संभव हो पुराने अनुरोध को रद्द करता है, देर से आए परिणामों को अस्वीकार करता है और ऑर्डर और माप को रीसेट करता है। रिकॉर्ड ID आइटम कुंजियों के रूप में कार्य करती हैं; इंडेक्स कभी भी स्थिति के स्वामी नहीं होते हैं।
एक्सेसिबिलिटी के लिए, यह गतिविधि स्ट्रीम फ़ीड और आर्टिकल सेमांटिक्स का उपयोग करती है। माउंट किए गए आर्टिकल अपनी लॉजिकल स्थिति और ज्ञात कुल को उजागर करते हैं, पेज डालते समय फ़ीड व्यस्त स्थिति को उजागर करती है, और उस स्थिति को बाद में साफ़ किया जाता है। मैं उस आर्टिकल को अनमाउंट नहीं करता जिसमें फ़ोकस है। कीबोर्ड नेविगेशन फ़ोकस करने से पहले अगले लॉजिकल आर्टिकल को लोड और माउंट करता है, और मैं स्पष्ट पुनः प्रयास, अंत और लोड-अधिक पथ रखता हूँ।
मैं पहले पुष्टि करूँगा कि क्या साधारण रेंडरिंग लक्षित बजट को पूरा करने में विफल रहती है। फिर मैं पंक्ति ऊँचाइयों, विलंबित मीडिया, विस्तार, तेज़ स्क्रॉलिंग, रीसाइज़िंग, फ़िल्टर रेस, प्रीपेंड और अपेंड और नेटवर्क विफलताओं के एक नियतात्मक मिश्रण का परीक्षण करूँगा। मैं माउंटेड-नोड गणना, लंबे कार्यों, लेआउट और पेंट कार्य, रिटेन्ड मेमोरी, एंकर त्रुटि, डुप्लिकेट अनुरोध और ID, ड्राफ़्ट पहचान, कीबोर्ड फ़ोकस और स्क्रीन-रीडर आउटपुट को रिकॉर्ड करूँगा। यदि कोई पेजिनेटेड सामान्य लिस्ट समान आवश्यकताओं को पूरा करती है, तो मैं उसे चुनूँगा क्योंकि इसमें कम शुद्धता और एक्सेसिबिलिटी विफलता मोड होते हैं।"
सामान्य गलतियाँ
- अनंत लोडिंग को वर्चुअलाइज़ेशन मानना → पुराने पेज DOM नोड्स जोड़ते रहते हैं और स्क्रॉल की गई दूरी के साथ प्रदर्शन ख़राब होता है → लोड किए गए डेटा से स्वतंत्र रूप से माउंट की गई रेंज को सीमित करें।
- आइटम कुंजियों के रूप में ऐरे इंडेक्स का उपयोग करना → प्रीपेंड, फ़िल्टरिंग और डिडुप्लीकेशन ड्राफ़्ट और चयन को अलग-अलग रिकॉर्ड में ले जाते हैं → पंक्तियों और बाहरी स्थिति को स्थिर रिकॉर्ड ID द्वारा कीड करें।
- यह मानना कि एक औसत ऊँचाई सटीक है → ऑफ़सेट त्रुटि जमा होती है और खाली रेंज या जंप का कारण बनती है → परिवर्तनीय पंक्तियों को मापें और एक संचयी आकार मॉडल को अपडेट करें।
- एंकर के बिना मापन परिवर्तन लागू करना → व्यूपोर्ट के ऊपर की सामग्री उपयोगकर्ता जो पढ़ रहा है उसे स्थानांतरित कर देती है → पहले दृश्यमान रिकॉर्ड और उसके इंट्रा-रो ऑफ़सेट को सुरक्षित रखें।
- नेटिव और मैन्युअल एंकरिंग दोनों को क्षतिपूर्ति करने देना → व्यूपोर्ट दो बार स्थानांतरित हो सकता है → कंटेनर का परीक्षण करें और एक स्वामी को मुआवज़ा सौंपें।
- एक निश्चित बड़ी पंक्ति संख्या को ओवरस्कैन करना → विस्तृत कार्ड भारी DOM और लेआउट कार्य को फिर से बनाते हैं → लक्षित उपकरणों पर पिक्सेल दूरी और रेंडरिंग लागत को ट्यून करें।
- प्रत्येक रेंज अपडेट से एक फ़ेच फ़ायर करना → बार-बार रेंडर समान कर्सर का अनुरोध करते हैं और परिणाम इंटरलीव होते हैं → कर्सर द्वारा संयोजित करें और पुराने क्वेरी जनरेशन को अस्वीकार करें।
- पंक्ति घटकों के अंदर ड्राफ़्ट रखना → अनमाउंट करने से वे हट जाते हैं या स्लॉट पुनर्चक्रण उन्हें लीक कर देता है → महत्वपूर्ण स्थिति को एक ID-कीड स्वामी में उठाएँ।
- फ़ोकस की गई पंक्ति को अनमाउंट करना → कीबोर्ड और सहायक-तकनीक संदर्भ गायब हो जाता है → फ़ोकस किए गए आइटम को पिन करें या निष्कासन से पहले जानबूझकर फ़ोकस ले जाएँ।
- केवल माउंट किए गए सबसेट की स्थिति की रिपोर्ट करना → एक स्क्रीन रीडर भ्रामक संग्रह आकार और क्रम सुनता है → लॉजिकल स्थिति और ज्ञात या अज्ञात लॉजिकल सेट आकार को उजागर करें।
- व्यस्त स्थिति सेट करना और इसे कभी साफ़ न करना → सहायक तकनीक पूर्ण किए गए अपडेट को उजागर नहीं कर सकती है → प्रत्येक सफलता और विफलता पथ में व्यस्त स्थिति को साफ़ करें।
- केवल फ़्रेम दर को ऑप्टिमाइज़ करना → फ़ोकस, ड्राफ़्ट, रेस, मेमोरी और स्क्रॉल स्थिति अभी भी गलत हो सकती है → प्रदर्शन और इंटरैक्शन इनवेरिएंट को एक साथ सत्यापित करें।
फ़ॉलो-अप प्रश्न और प्रतिक्रियाएँ
फ़ॉलो-अप 1: यदि प्रत्येक पंक्ति की ऊँचाई ठीक 56 पिक्सेल हो तो क्या बदलता है?
गतिशील मापन और इसके सुधार पथ हटाएँ। 56 पिक्सेल से सीधे रेंज और ऑफ़सेट की गणना करें, गुणन द्वारा कुल लोड की गई ऊँचाई प्राप्त करें, और इंडेक्स प्लस इंट्रा-रो ऑफ़सेट द्वारा स्थितियों को पुनर्स्थापित करें। स्थिर ID, लोडिंग रेस, फ़ोकस और एक्सेसिबिलिटी हैंडलिंग रखें; निश्चित ऊँचाई ज्यामिति को सरल बनाती है लेकिन पहचान या इंटरैक्शन को हल नहीं करती है। प्रीफ़िक्स-सम संरचना जोड़ने से पहले बेंचमार्क करें जिसकी अब बाधा को आवश्यकता नहीं है।
फ़ॉलो-अप 2: आप केवल-कर्सर API से अज्ञात कुल का समर्थन कैसे करते हैं?
लोड किए गए उपसर्ग को वर्चुअलाइज़ करें और पेज आने पर कैनवास बढ़ाएँ। अनलोड किए गए इंडेक्स या नकली अंतिम स्क्रॉलबार आकार का आविष्कार न करें। फ़ीड पैटर्न के अज्ञात सेट आकार को उजागर करें, लोडिंग और अंतिम स्थितियों की घोषणा करें, और एक स्पष्ट लोड-अधिक या पुनः प्रयास नियंत्रण रखें। मनमाना जंप-टू-इंडेक्स अनुपलब्ध है जब तक कि सर्वर अनुक्रमित लुकअप, एक रिकॉर्ड लोकेटर या एक स्थिर अनुमान अनुबंध न जोड़े।
फ़ॉलो-अप 3: पुराने आइटम तब प्रीपेंड किए जाते हैं जब उपयोगकर्ता बीच में पढ़ रहा होता है। आप जंप को कैसे रोकते हैं?
सम्मिलन से पहले पहले दृश्यमान रिकॉर्ड की ID और इसके व्यूपोर्ट-सापेक्ष ऑफ़सेट को कैप्चर करें। पुरानी ID डालें, उनका अनुमान लगाएँ या मापें, संचयी ऑफ़सेट की पुनर्गणना करें और स्क्रॉल ऑफ़सेट सेट करें ताकि कैप्चर किया गया रिकॉर्ड उसी दृश्य बिंदु पर वापस आ जाए। पेज सीमा पर ID को डिडुप्लिकेट करें। यदि मीडिया लोड होने के बाद मापन जारी रहता है, तो उसी नियम का उपयोग करके एंकर के ऊपर बाद के डेल्टा लागू करें।
फ़ॉलो-अप 4: उपयोगकर्ता द्वारा स्क्रॉलबार खींचने के बाद फ़ोकस किया गया कार्ड 5,000 आइटम दूर है। क्या आप इसे हमेशा माउंट रखते हैं?
इंटरैक्शन अनुबंध को परिभाषित करें। एक केंद्रित कार्ड को पिन रखना एक सीमित DOM लागत है, लेकिन व्यूपोर्ट से दूर एक छिपा हुआ फ़ोकस लक्ष्य उपयोगकर्ताओं को भ्रमित कर सकता है। एक जानबूझकर स्क्रॉलबार जंप के दौरान, घोषणा के साथ फ़ीड कंटेनर या नए नेविगेट किए गए दृश्यमान आर्टिकल पर फ़ोकस ले जाएँ, फिर पुराने कार्ड को अनपिन करें। प्रासंगिक माप या पॉइंटर स्क्रॉल के दौरान, चुपचाप फ़ोकस नष्ट न करें। कीबोर्ड और स्क्रीन-रीडर उपयोगकर्ताओं के साथ चुने गए व्यवहार का परीक्षण करें।
फ़ॉलो-अप 5: उत्पाद ब्राउज़र फाइंड-इन-पेज और सभी 100,000 आइटम प्रिंट करने के लिए कहता है। क्या एक वर्चुअलाइज़्ड DOM इसे संतुष्ट कर सकता है?
कोई भी विश्वसनीय आंशिक DOM उस टेक्स्ट को उजागर नहीं कर सकता है जो ब्राउज़र खोज के लिए माउंट नहीं है या इसे साधारण पेज सामग्री के रूप में प्रिंट नहीं कर सकता है। इन्हें अलग-अलग आवश्यकताओं के रूप में मानें। सर्वर-समर्थित खोज प्रदान करें जो मिलान करने वाले रिकॉर्ड पर जाती है और उसे माउंट करती है। अस्थायी रूप से 100,000 इंटरैक्टिव कार्ड माउंट करने और पेज को फ़्रीज़ करने के बजाय स्पष्ट सीमाओं के साथ एक पेजिनेटेड निर्यात या प्रिंट-विशिष्ट डेटा दृश्य उत्पन्न करें।
फ़ॉलो-अप 6: आप केवल स्क्रीनशॉट पर भरोसा किए बिना वर्चुअलाइज़र का परीक्षण कैसे करेंगे?
नियतात्मक इनपुट के साथ शुद्ध निश्चित-रेंज और संचयी-ऑफ़सेट इनवेरिएंट का परीक्षण करें, फिर एक वास्तविक ब्राउज़र में एकीकरण परिदृश्यों को चलाएँ। सुनिश्चित करें कि माउंट की गई ID दृश्यमान रेंज और ओवरस्कैन को कवर करती हैं, कुल आकार आकार मॉडल से मेल खाता है, लॉजिकल एंकर माप के बाद सहमत सहनशीलता के भीतर रहता है, प्रत्येक कर्सर का एक बार अनुरोध किया जाता है, और ड्राफ़्ट पुनर्व्यवस्था के माध्यम से ID का पालन करते हैं। कीबोर्ड और स्क्रीन-रीडर जाँच जोड़ें क्योंकि DOM ज्यामिति दावे फ़ोकस और घोषणाओं को मान्य नहीं कर सकते हैं।