ఆధునిక వెబ్సైట్లు మరింత అద్భుతమైన విజువల్స్తో దృష్టిని ఆకర్షించడానికి పోటీ పడుతున్నాయి. Parallax heroes వ్యూపోర్ట్లోకి లోతుగా విస్తరిస్తాయి. Carousels అనంతంగా స్క్రోల్ అవుతాయి. సైన్-అప్ ఫారమ్ల వెనుక బ్యాక్గ్రౌండ్ వీడియోలు ఆటో-ప్లే అవుతాయి. డిజైన్ పోర్ట్ఫోలియోలలో ఇవి చాలా మెరుగ్గా మరియు ఆకర్షణీయంగా కనిపిస్తాయి. కానీ మీ ప్రేక్షకులలో కొంతమందికి, ఇవి శారీరక ఇబ్బందులకు కారణమవుతాయి.
వెస్టిబ్యులర్ డిజార్డర్స్ (vestibular disorders) ఉన్నవారు నిరంతర కదలికలు ఉన్న పెద్ద ప్రాంతాలను చూసినప్పుడు వికారం, తల తిరగడం లేదా మైగ్రేన్ వంటి సమస్యలను ఎదుర్కొంటారు. వారిని రక్షించడానికి, ప్రతి ప్రధాన ఆపరేటింగ్ సిస్టమ్ ఇప్పుడు "Reduce Motion" అనే యాక్సెసిబిలిటీ సెట్టింగ్ను కలిగి ఉంది. వెబ్ బ్రౌజర్లు ఆ ప్రాధాన్యతను prefers-reduced-motion మీడియా క్వెరీ ద్వారా తెలియజేస్తాయి. దీనిని సరిగ్గా పాటించాలనుకునే React డెవలపర్లు @reactuses/core నుండి useReducedMotion హుక్ను ఉపయోగించవచ్చు. ఇది OS ప్రాధాన్యతను ఒక boolean రూపంలో చదువుతుంది, వినియోగదారు తన నిర్ణయాన్ని మార్చుకుంటే వెంటనే అప్డేట్ చేస్తుంది మరియు సర్వర్-సైడ్ రెండరింగ్లో ఎటువంటి సమస్యలు లేకుండా హ్యాండిల్ చేస్తుంది.
సొంతంగా తయారుచేసే పరిష్కారాలు ఎందుకు విఫలమవుతాయి
మీరు window.matchMedia('(prefers-reduced-motion: reduce)') ఉపయోగించి ఆ ప్రాధాన్యతను స్వయంగా క్వెరీ చేయవచ్చు. చాలా మంది డెవలపర్లు అలాగే చేస్తారు, కానీ దానివల్ల చిన్న చిన్న బగ్లు వచ్చే అవకాశం ఉంది.
మొదటిది, మీరు 'change listener'ను సులభంగా మర్చిపోవచ్చు. కాంపోనెంట్ మౌంట్ అయినప్పుడు ప్రారంభ క్వెరీ ఒకసారి మాత్రమే రన్ అవుతుంది. ఒక వినియోగదారు మీ యాప్ను ఓపెన్ చేసి, కారౌసెల్ వల్ల ఇబ్బందిగా ఉందని సిస్టమ్ సెట్టింగ్స్లో 'Reduce Motion'ను మార్చుకుంటే, మీ కాంపోనెంట్కు ఆ అప్డేట్ తెలియదు. మీడియా క్వెరీ ఆబ్జెక్ట్ addEventListenerను సపోర్ట్ చేస్తుంది, కానీ దానిని సరిగ్గా కనెక్ట్ చేయడం, unmount అయినప్పుడు దానిని తొలగించడం మరియు పాత addListener సింటాక్స్కు పాలిఫిల్ (polyfilling) చేయడం వంటివి చాలా బోయిలర్ప్లేట్ కోడ్ అవసరమయ్యే పనులు, దీనివల్ల కాపీ-పాస్ట్ తప్పులు జరిగే అవకాశం ఉంది.
రెండవది, SSR సమయంలో window ఉండదు. మీ యాప్ సర్వర్లో రెండర్ అవుతుంటే, సాధారణ matchMedia కాల్ ఒక 'reference error'ను కలిగిస్తుంది మరియు రెండరింగ్ను ఆపేస్తుంది. దీనివల్ల మీరు ఆ చెక్ను typeof window !== 'undefined' గార్డ్లతో చుట్టాల్సి వస్తుంది, డిఫాల్ట్ విలువను ఊహించాల్సి వస్తుంది మరియు క్లయింట్ హైడ్రేషన్ (client hydrate) సరిగ్గా జరుగుతుందని ఆశించాల్సి వస్తుంది.
మూడవది, ప్రతి యానిమేటెడ్ కాంపోనెంట్లో ఆ లాజిక్ను మళ్ళీ మళ్ళీ రాయడం వల్ల మెయింటెనెన్స్ భారం (maintenance debt) పెరుగుతుంది. ఒక టీమ్ మెంబర్ లిజనర్ను ఒకలా రాస్తే, మరొకరు దానిని పూర్తిగా వదిలేయవచ్చు, మరియు మూడవ వ్యక్తి యానిమేషన్కు ప్రాధాన్యత ఇచ్చేలా డిఫాల్ట్ను హార్డ్-కోడ్ చేయవచ్చు. ఒక హుక్ ఈ గందరగోళాన్ని ఒకే చోట క్రమబద్ధీకరిస్తుంది.
useReducedMotion ఈ మూడు సమస్యలను పరిష్కరిస్తుంది. ఇది ఒక సాధారణ booleanను రిటర్న్ చేస్తుంది. ఇది సర్వర్లో సురక్షితంగా 'no-op'గా పనిచేస్తుంది. ఇది లిజనర్ను ఆటోమేటిక్గా అటాచ్ చేస్తుంది మరియు క్లీన్ చేస్తుంది.
దీనిని ఉపయోగించడానికి మూడు మార్గాలు
మీకు ఆ boolean లభించిన తర్వాత, దాని ఆధారంగా ఎలా స్పందించాలో ఒక వ్యూహం అవసరం. ఒకే కాంపోనెంట్ నుండి మొత్తం అప్లికేషన్ వరకు ఉపయోగపడే మూడు పద్ధతులు ఇక్కడ ఉన్నాయి.
1. అనవసరమైన పనిని నివారించడానికి CSS క్లాస్లను నియంత్రించండి
అత్యంత ప్రత్యక్షమైన పద్ధతి ఏమిటంటే, భారీ JavaScript యానిమేషన్ లూప్లు అసలు ప్రారంభం కాకుండా నిరోధించడం. ఉదాహరణకు, మీ వద్ద ఒక parallax ఇమేజ్ కాంపోనెంట్ ఉందనుకోండి, అది సాధారణంగా స్క్రోల్ ఈవెంట్లను వింటూ requestAnimationFrame లూప్లో లేయర్లను కదిలిస్తుంది. ఆ లాజిక్ను రన్ చేసి, ఆ తర్వాత విజువల్ ఫలితాన్ని ఆపేయడం కంటే, ముందుగా useReducedMotionను తనిఖీ చేయండి.
ఒకవేళ హుక్ true అని రిటర్న్ చేస్తే, కాంపోనెంట్ను ఒక స్టాటిక్ వేరియంట్ క్లాస్తో రెండర్ చేయండి మరియు స్క్రోల్ లిజనర్లను బైండ్ చేసే useEffectను స్కిప్ చేయండి. దీనివల్ల బ్రౌజర్ తక్కువ పని చేస్తుంది. మోషన్ సెన్సిటివిటీ ఉన్న వినియోగదారులు స్థిరమైన చిత్రాన్ని చూస్తారు. మిగిలిన వారందరికీ కదిలే లేయర్లు కనిపిస్తాయి. యానిమేషన్ కోడ్ అసలు ప్రారంభం కానందువల్ల, మీరు CPU మరియు బ్యాటరీని ఆదా చేయవచ్చు.
2. యానిమేషన్ లైబ్రరీలలో నేరుగా ఉపయోగించండి
మీరు Framer Motion వంటి లైబ్రరీని ఉపయోగిస్తుంటే, ఈ హుక్ మీ prop నిర్వచనాలలో నేరుగా కలిసిపోతుంది. Motion కాంపోనెంట్లు variants, transitions మరియు gestures కోసం కాన్ఫిగరేషన్ ఆబ్జెక్ట్లను స్వీకరిస్తాయి. మీరు useReducedMotion నుండి వచ్చిన booleanను ఉపయోగించి transitions పై కండిషనల్గా duration: 0ను సెట్ చేయవచ్చు, లేదా
