ब्लर करने की सुविधा, किसी व्यक्ति का ध्यान हटाने का एक बेहतरीन तरीका है. कुछ विज़ुअल एलिमेंट को धुंधला करके और अन्य एलिमेंट को फ़ोकस में रखकर, उपयोगकर्ता का ध्यान स्वाभाविक रूप से खींचा जा सकता है. उपयोगकर्ता, धुंधले किए गए कॉन्टेंट को अनदेखा करते हैं और इसके बजाय, उस कॉन्टेंट पर फ़ोकस करते हैं जिसे वे पढ़ सकते हैं. इसका एक उदाहरण, आइकॉन की ऐसी सूची है जिस पर कर्सर घुमाने पर, अलग-अलग आइटम के बारे में जानकारी दिखती है. इस दौरान, बाकी विकल्पों को धुंधला किया जा सकता है, ताकि उपयोगकर्ता को नई जानकारी पर रीडायरेक्ट किया जा सके.
कम शब्दों में कहा जाए तो
ब्लर को ऐनिमेट करने का विकल्प उपलब्ध नहीं है, क्योंकि यह बहुत धीमा है. इसके बजाय, ज़्यादा से ज़्यादा धुंधले वर्शन की एक सीरीज़ पहले से ही तैयार कर लें और उनके बीच क्रॉस-फ़ेड करें. मेरे सहकर्मी यी गु ने आपके लिए एक लाइब्रेरी बनाई है, ताकि आपको किसी भी तरह की समस्या न हो! हमारा डेमो देखें.
हालांकि, ट्रांज़िशन पीरियड के बिना इसे लागू करने पर, यह तकनीक काफ़ी परेशान करने वाली हो सकती है. धुंधला करने की सुविधा को ऐनिमेट करना — साफ़ से धुंधला करना — एक सही विकल्प लगता है. हालांकि, अगर आपने कभी वेब पर ऐसा करने की कोशिश की है, तो शायद आपने पाया होगा कि ऐनिमेशन बिलकुल भी स्मूद नहीं हैं. अगर आपके पास पावरफ़ुल मशीन नहीं है, तो यह डेमो दिखाता है. क्या हम इसे और बेहतर बना सकते हैं?
समस्या

फ़िलहाल, हम ब्लर करने की सुविधा को बेहतर तरीके से ऐनिमेट नहीं कर सकते. हालांकि, हम एक ऐसा तरीका ढूंढ सकते हैं जो काफ़ी हद तक धुंधला दिखने वाला इफ़ेक्ट देता है. हालांकि, तकनीकी तौर पर यह ऐनिमेटेड ब्लर नहीं होता. शुरू करने से पहले, आइए सबसे पहले यह समझते हैं कि ऐनिमेशन वाला ब्लर क्यों धीरे-धीरे होता है. वेब पर मौजूद एलिमेंट को धुंधला करने के लिए, दो तकनीकों का इस्तेमाल किया जा सकता है: सीएसएस filter
प्रॉपर्टी और एसवीजी फ़िल्टर. ज़्यादा सपोर्ट और इस्तेमाल में आसानी की वजह से, आम तौर पर सीएसएस फ़िल्टर का इस्तेमाल किया जाता है. अगर आपको Internet Explorer के साथ काम करने वाले फ़िल्टर इस्तेमाल करने हैं, तो आपके पास SVG फ़िल्टर इस्तेमाल करने के अलावा कोई और विकल्प नहीं है. ऐसा इसलिए, क्योंकि IE 10 और 11 में SVG फ़िल्टर काम करते हैं, लेकिन CSS फ़िल्टर नहीं. अच्छी बात यह है कि धुंधला करने की सुविधा को ऐनिमेट करने का हमारा तरीका, दोनों तकनीकों के साथ काम करता है. इसलिए, DevTools की मदद से परफ़ॉर्मेंस में आने वाली रुकावटों का पता लगाते हैं.
DevTools में "Paint Flashing" सुविधा चालू करने पर, आपको कोई भी फ़्लैश नहीं दिखेगा. ऐसा लगता है कि कोई भी रीपेंट नहीं हो रहा है. तकनीकी तौर पर यह सही है, क्योंकि "रीपेंट" का मतलब है कि सीपीयू को प्रमोट किए गए एलिमेंट के टेक्सचर को फिर से पेंट करना होगा. जब भी किसी एलिमेंट का प्रमोशन किया जाता है और उसे धुंधला किया जाता है, तब जीपीयू, शेडर का इस्तेमाल करके उसे धुंधला करता है.
एसवीजी फ़िल्टर और सीएसएस फ़िल्टर, दोनों ही धुंधला करने के लिए कनवोल्यूशन फ़िल्टर का इस्तेमाल करते हैं. कनवोल्यूशन फ़िल्टर का इस्तेमाल करना महंगा होता है, क्योंकि हर आउटपुट पिक्सल के लिए कई इनपुट पिक्सल पर विचार करना पड़ता है. इमेज जितनी बड़ी होगी या ब्लर करने का दायरा जितना बड़ा होगा, इफ़ेक्ट उतना ही महंगा होगा.
समस्या यहीं है. हम हर फ़्रेम में महंगा जीपीयू ऑपरेशन चला रहे हैं. इससे हमारा फ़्रेम बजट 16 मि॰से॰ से ज़्यादा हो जाता है. इसलिए, हमें 60 एफ़पीएस से कम फ़्रेम मिलते हैं.
रैबिट होल
इसलिए, हम इसे आसानी से चलाने के लिए क्या कर सकते हैं? हम हाथ की सफ़ाई का इस्तेमाल कर सकते हैं! ब्लर की असल वैल्यू (ब्लर का दायरा) को ऐनिमेट करने के बजाय, हम ब्लर की कुछ ऐसी कॉपी पहले से ही तैयार कर लेते हैं जिनमें ब्लर की वैल्यू तेज़ी से बढ़ती है. इसके बाद, opacity
का इस्तेमाल करके, उनके बीच क्रॉस-फ़ेड किया जाता है.
क्रॉस-फ़ेड, ओपैसिटी के फ़ेड-इन और फ़ेड-आउट होने की एक ऐसी सीरीज़ है जिसमें एक इमेज धीरे-धीरे दिखती है और दूसरी इमेज धीरे-धीरे गायब होती है. उदाहरण के लिए, अगर हमारे पास धुंधला करने के चार चरण हैं, तो हम पहले चरण को फ़ेड आउट करते हैं. साथ ही, दूसरे चरण को फ़ेड इन करते हैं. जब दूसरा स्टेज पूरी तरह से दिखने लगता है और पहला स्टेज पूरी तरह से गायब हो जाता है, तब हम दूसरे स्टेज को धीरे-धीरे गायब करते हैं. साथ ही, तीसरे स्टेज को धीरे-धीरे दिखाते हैं. इसके बाद, हम तीसरे वर्शन को धीरे-धीरे हटा देते हैं और चौथे और आखिरी वर्शन को धीरे-धीरे दिखा देते हैं. इस स्थिति में, हर चरण में कुल अवधि का ¼ समय लगेगा. यह देखने में, ऐनिमेशन वाले असली ब्लर इफ़ेक्ट जैसा लगता है.
हमारे एक्सपेरिमेंट में, हर स्टेज पर ब्लर रेडियस को तेज़ी से बढ़ाने पर, सबसे अच्छे विज़ुअल नतीजे मिले. उदाहरण: अगर हमारे पास धुंधला करने के चार चरण हैं, तो हम हर चरण पर filter: blur(2^n)
लागू करेंगे. जैसे, चरण 0: 1 पिक्सल, चरण 1: 2 पिक्सल, चरण 2: 4 पिक्सल, और चरण 3: 8 पिक्सल. अगर हम will-change: transform
का इस्तेमाल करके, धुंधली की गई हर कॉपी को उसकी लेयर (जिसे "प्रमोट करना" कहा जाता है) पर रखते हैं, तो इन एलिमेंट की पारदर्शिता को बहुत तेज़ी से बदला जा सकता है. सैद्धांतिक तौर पर, इससे हमें धुंधला करने के मुश्किल काम को पहले ही पूरा करने में मदद मिलेगी. हालांकि, यह लॉजिक सही नहीं है. इस डेमो को चलाने पर, आपको पता चलेगा कि फ़्रेमरेट अब भी 60 एफ़पीएस से कम है. साथ ही, धुंधलापन पहले से ज़्यादा है.

DevTools में देखने पर पता चलता है कि GPU अब भी बहुत ज़्यादा व्यस्त है और हर फ़्रेम को ~90 मि॰से॰ तक खींच रहा है. लेकिन क्यों? We are not changing the blur value anymore, only the opacity, so what's happening? इस बार भी समस्या, धुंधलेपन वाले इफ़ेक्ट की वजह से आ रही है: जैसा कि पहले बताया गया है, अगर एलिमेंट को प्रमोट किया गया है और उसे धुंधला किया गया है, तो इफ़ेक्ट को GPU लागू करता है. इसलिए, अब हम ब्लर वैल्यू को ऐनिमेट नहीं कर रहे हैं. हालांकि, टेक्सचर अब भी अनब्लर है और इसे हर फ़्रेम में GPU से फिर से ब्लर करना होगा. फ़्रेम रेट पहले से भी कम होने की वजह यह है कि सामान्य तरीके से लागू करने की तुलना में, जीपीयू को अब ज़्यादा काम करना पड़ता है. ऐसा इसलिए, क्योंकि ज़्यादातर समय दो टेक्सचर दिखते हैं जिन्हें अलग-अलग धुंधला करना होता है.
हमने जो तरीका अपनाया है वह बहुत अच्छा नहीं है, लेकिन इससे ऐनिमेशन बहुत तेज़ी से होता है. हम धुंधली की जाने वाली इमेज का प्रमोशन नहीं करते हैं. इसके बजाय, हम पैरंट रैपर का प्रमोशन करते हैं. अगर किसी एलिमेंट को धुंधला किया गया है और उसे प्रमोट किया गया है, तो जीपीयू इस इफ़ेक्ट को लागू करता है. इस वजह से, हमारा डेमो धीमा हो गया. अगर एलिमेंट धुंधला है, लेकिन उसे प्रमोट नहीं किया गया है, तो धुंधलेपन को सबसे मिलते-जुलते पैरंट टेक्सचर में बदल दिया जाता है. हमारे मामले में, यह प्रमोट किया गया पैरंट रैपर एलिमेंट है. धुंधली की गई इमेज अब पैरंट एलिमेंट का टेक्सचर है. इसका इस्तेमाल आने वाले समय में सभी फ़्रेम के लिए फिर से किया जा सकता है. यह सिर्फ़ इसलिए काम करता है, क्योंकि हमें पता है कि धुंधले किए गए एलिमेंट में ऐनिमेशन नहीं है. साथ ही, उन्हें कैश मेमोरी में सेव करना फ़ायदेमंद है. इस तकनीक को लागू करने वाला डेमो यहां दिया गया है. मुझे लगता है कि Moto G4 इस तरीके के बारे में क्या सोचता है? स्पॉइलर अलर्ट: इसे लगता है कि यह बहुत अच्छा है:

अब हमारे पास जीपीयू पर काफ़ी हेडरूम है और 60fps पर वीडियो बहुत स्मूद चलता है. हमने कर दिखाया!
प्रोडक्शन में इस्तेमाल करना
हमारे डेमो में, हमने एक ही DOM स्ट्रक्चर को कई बार डुप्लीकेट किया है, ताकि अलग-अलग लेवल पर धुंधला करने के लिए कॉन्टेंट की कॉपी मिल सकें. आपको लग सकता है कि प्रोडक्शन एनवायरमेंट में यह कैसे काम करेगा, क्योंकि इससे लेखक की सीएसएस स्टाइल या JavaScript पर कुछ अनचाहे साइड इफ़ेक्ट पड़ सकते हैं. आपने सही कहा. शैडो डीओएम में आपका स्वागत है!
ज़्यादातर लोग शैडो डीओएम को, कस्टम एलिमेंट में "इंटरनल" एलिमेंट जोड़ने के तरीके के तौर पर देखते हैं. हालांकि, यह आइसोलेशन और परफ़ॉर्मेंस प्रिमिटिव भी है! JavaScript और CSS, शैडो DOM की सीमाओं को पार नहीं कर सकते. इससे हमें डेवलपर की स्टाइल या ऐप्लिकेशन लॉजिक में बदलाव किए बिना कॉन्टेंट को डुप्लीकेट करने की अनुमति मिलती है. हमारे पास पहले से ही हर कॉपी के लिए <div>
एलिमेंट है, ताकि उसे रास्टर किया जा सके. अब हम इन <div>
एलिमेंट का इस्तेमाल शैडो होस्ट के तौर पर करते हैं. हम attachShadow({mode: 'closed'})
का इस्तेमाल करके ShadowRoot
बनाते हैं. साथ ही, कॉन्टेंट की कॉपी को <div>
के बजाय ShadowRoot
से अटैच करते हैं. हमें यह पक्का करना होगा कि सभी स्टाइलशीट को ShadowRoot
में भी कॉपी किया जाए, ताकि यह पक्का किया जा सके कि हमारी कॉपी, ओरिजनल की तरह ही स्टाइल की गई हैं.
कुछ ब्राउज़र, Shadow DOM v1 के साथ काम नहीं करते. ऐसे ब्राउज़र के लिए, हम सिर्फ़ कॉन्टेंट को डुप्लीकेट करते हैं. साथ ही, हमें उम्मीद होती है कि इससे कोई समस्या नहीं आएगी. हम ShadyCSS के साथ Shadow DOM polyfill का इस्तेमाल कर सकते थे. हालांकि, हमने इसे अपनी लाइब्रेरी में लागू नहीं किया.
बस इतना ही. Chrome के रेंडरिंग पाइपलाइन के बारे में जानने के बाद, हमें यह पता चला कि हम अलग-अलग ब्राउज़र पर ब्लर इफ़ेक्ट को बेहतर तरीके से ऐनिमेट कैसे कर सकते हैं!
नतीजा
इस तरह के इफ़ेक्ट का इस्तेमाल हल्के में नहीं करना चाहिए. हम DOM एलिमेंट कॉपी करते हैं और उन्हें उनकी लेयर पर रखते हैं. इस वजह से, हम कम कॉन्फ़िगरेशन वाले डिवाइसों की परफ़ॉर्मेंस को बेहतर बना सकते हैं. ShadowRoot
में सभी स्टाइलशीट कॉपी करने से परफ़ॉर्मेंस पर असर पड़ सकता है. इसलिए, आपको यह तय करना चाहिए कि आपको LightDOM
में कॉपी किए गए स्टाइलशीट से बचने के लिए, अपने लॉजिक और स्टाइल में बदलाव करना है या हमारी ShadowDOM
तकनीक का इस्तेमाल करना है. हालांकि, कभी-कभी हमारी तकनीक आपके लिए फ़ायदेमंद हो सकती है. हमारी GitHub रिपॉज़िटरी में मौजूद कोड देखें. साथ ही, डेमो देखें. अगर आपका कोई सवाल है, तो Twitter पर हमसे संपर्क करें!