किसी वेब ऐप्लिकेशन पर झटपट नेविगेशन और बिना किसी रुकावट के पेज ट्रांज़िशन जोड़ें

1. शुरू करने से पहले

इस कोडलैब में, आपको यह सिखाया जाएगा कि Google Chrome के साथ काम करने वाले नए एपीआई की मदद से, किसी सैंपल वेब ऐप्लिकेशन में तुरंत नेविगेशन और पेज ट्रांज़िशन की सुविधा कैसे जोड़ी जाती है.

यह सैंपल वेब ऐप्लिकेशन, लोकप्रिय फलों और सब्ज़ियों के पोषक तत्वों की जांच करता है. फल-सूची और फल-जानकारी वाले पेजों को सिंगल-पेज ऐप्लिकेशन (एसपीए) के तौर पर बनाया गया है. वहीं, सब्ज़ी-सूची और सब्ज़ी-जानकारी वाले पेजों को ट्रेडिशनल मल्टीपल-पेज ऐप्लिकेशन (एमपीए) के तौर पर बनाया गया है.

मोबाइल पर ऐप्लिकेशन के सैंपल का स्क्रीनशॉट मोबाइल पर ऐप्लिकेशन के सैंपल का स्क्रीनशॉट

खास तौर पर, आपने तुरंत नेविगेशन के लिए प्रीरेंडरिंग, बैक/फ़ॉरवर्ड कैश मेमोरी (bfcache), और निजी प्रीफ़ेच प्रॉक्सी को लागू किया है. साथ ही, आपने पेज के ट्रांज़िशन को आसान बनाने के लिए रूट/शेयर किए गए एलिमेंट के ट्रांज़िशन को लागू किया है. एमपीए पेजों के लिए, प्रीरेंडरिंग और बीएफ़कैश लागू करें. साथ ही, एसपीए पेजों के लिए, शेयर किए गए एलिमेंट के ट्रांज़िशन लागू करें.

साइट के लोड होने में लगने वाला समय, हमेशा से ही उपयोगकर्ता अनुभव का एक अहम पहलू रहा है. इसलिए, Google ने वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी को लॉन्च किया. यह मेट्रिक का एक सेट है. इसमें वेब पेजों के लोड होने में लगने वाले समय, इंटरैक्टिविटी, और विज़ुअल स्टेबिलिटी का आकलन किया जाता है, ताकि उपयोगकर्ता के असल अनुभव का पता लगाया जा सके. नए एपीआई की मदद से, फ़ील्ड में अपनी वेबसाइट के Core Web Vitals स्कोर को बेहतर बनाया जा सकता है. खास तौर पर, लोड होने की परफ़ॉर्मेंस के लिए.

डेमो इमेज में दिखाया गया है कि बीएफ़कैश, पेज लोड होने में लगने वाले समय को कैसे कम करता है

Mindvalley का डेमो

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

pixiv का Shared Element Transitions API डेमो Tokopedia का शेयर किए गए एलिमेंट के ट्रांज़िशन एपीआई का डेमो

pixiv और Tokopedia के डेमो

ज़रूरी शर्तें

इनके बारे में जानकारी:

आपको यह जानकारी मिलेगी:

इसे लागू करने का तरीका:

  • प्रीरेंडरिंग
  • bfcache
  • निजी प्रीफ़ेच प्रॉक्सी
  • रूट/शेयर किए गए एलिमेंट के ट्रांज़िशन

आपको क्या बनाना है

Next.js की मदद से बनाया गया एक वेब ऐप्लिकेशन का सैंपल. इसमें ब्राउज़र की नई सुविधाएं शामिल हैं, जो तुरंत और बिना किसी रुकावट के काम करती हैं:

  • प्रीरेंडरिंग की मदद से, तुरंत नेविगेट करने की सुविधा
  • ब्राउज़र के पीछे और आगे जाने वाले बटन की मदद से, पेजों को तुरंत लोड करने के लिए बैक/फ़ॉरवर्ड कैश मेमोरी
  • Private Prefetch Proxy या Signed Exchange (SXG) की मदद से, अलग-अलग ऑरिजिन के बीच नेविगेट करने पर बेहतर इंप्रेशन मिलते हैं
  • रूट/शेयर किए गए एलिमेंट के ट्रांज़िशन की मदद से, पेजों के बीच आसानी से ट्रांज़िशन करना

आपको किन चीज़ों की ज़रूरत होगी

  • Chrome 101 या इसके बाद का वर्शन

2. अपनी प्रोफ़ाइल बनाना शुरू करें

Chrome फ़्लैग चालू करना

  1. about://flags पर जाएं. इसके बाद, Prerender2 और documentTransition API रनटाइम फ़्लैग चालू करें.
  2. अपना ब्राउज़र रीस्टार्ट करें.

कोड प्राप्त करें

  1. इस GitHub रिपॉज़िटरी से कोड को अपने पसंदीदा डेवलपमेंट एनवायरमेंट में खोलें:
git clone -b codelab git@github.com:googlechromelabs/instant-seamless-demo.git
  1. सर्वर चलाने के लिए ज़रूरी डिपेंडेंसी इंस्टॉल करें:
npm install
  1. पोर्ट 3000 पर सर्वर चालू करें:
npm run dev
  1. अपने ब्राउज़र में http://localhost:3000 पर जाएं.

अब अपने ऐप्लिकेशन में बदलाव किए जा सकते हैं और उसे बेहतर बनाया जा सकता है. जब भी कोई बदलाव किया जाता है, तो ऐप्लिकेशन फिर से लोड होता है और आपके बदलाव सीधे तौर पर दिखते हैं.

3. प्रीरेंडरिंग को इंटिग्रेट करना

इस डेमो के लिए, सैंपल ऐप्लिकेशन में मौजूद vegetable-details पेज को लोड होने में बहुत समय लगता है. ऐसा सर्वर साइड पर किसी वजह से होने वाली देरी की वजह से होता है. प्रीरेंडरिंग की मदद से, इंतज़ार के इस समय को कम किया जा सकता है.

सब्ज़ियों की सूची वाले पेज पर, प्रीरेंडर बटन जोड़ने के लिए और उपयोगकर्ता के क्लिक करने के बाद उन्हें प्रीरेंडर करने की अनुमति देने के लिए:

  1. बटन कॉम्पोनेंट बनाएं, जो अनुमान लगाने के नियमों वाले स्क्रिप्ट टैग को डाइनैमिक तरीके से जोड़ता है:

components/prerender-button.js

import { useContext } from 'react'
import ResourceContext from './resource-context'

// You use resource context to manage global states.
// In the PrerenderButton component, you update the prerenderURL parameter when the button is clicked.
export default function PrerenderButton() {
  const { dispatch } = useContext(ResourceContext)
  const handleClick = (e) => {
    e.preventDefault()
    e.stopPropagation()
    const parent = e.target.closest('a')
    if (!parent) {
      return
    }
    const href = parent.getAttribute('href')
    dispatch({ type: 'update', prerenderURL: href })
  }

  return (
    <button className='ml-auto bg-gray-200 hover:bg-gray-300 px-4 rounded' onClick={handleClick}>
      Prerender
    </button>
  )
}
  1. PrerenderButton फ़ाइल में PrerenderButton कॉम्पोनेंट इंपोर्ट करें.list-item.js

components/list-item.js

// Codelab: Add a PrerenderButton component.
import PrerenderButton from './prerender-button'

...
function ListItemForMPA({ item, href }) {
  return (
    <a href={href} className='block flex items-center'>
      <Icon src={item.image} />
      <div className='text-xl'>{item.name}</div>
      {/* Codelab: Add PrerenderButton component. */}
      <PrerenderButton />
    </a>
  )
}
  1. Speculation Rules API जोड़ने के लिए, कोई कॉम्पोनेंट बनाएं.

जब ऐप्लिकेशन, prerenderURL की स्थिति को अपडेट करता है, तब SpeculationRules कॉम्पोनेंट, पेज में डाइनैमिक तौर पर एक स्क्रिप्ट टैग डालता है.

components/speculationrules.js

import Script from 'next/script'
import { useContext, useMemo } from 'react'
import ResourceContext from './resource-context'

export default function SpeculationRules() {
  const { state } = useContext(ResourceContext)
  const { prerenderURL } = state

  return useMemo(() => {
    return (
      <>
        {prerenderURL && (
          <Script id='speculationrules' type='speculationrules'>
            {`
            {
              "prerender":[
                {
                  "source": "list",
                  "urls": ["${prerenderURL}"]
                }
              ]
            }
          `}
          </Script>
        )}
      </>
    )
  }, [prerenderURL])
}
  1. कॉम्पोनेंट को ऐप्लिकेशन के साथ इंटिग्रेट करें.

pages/_app.js

// Codelab: Add the SpeculationRules component.
import SpeculationRules from '../components/speculationrules'

function MyApp({ Component, pageProps }) {
  useAnalyticsForSPA()

  return (
    <ResourceContextProvider>
      <Layout>
        <Component {...pageProps} />
      </Layout>
      {/* Codelab: Add SpeculationRules component */}
      <SpeculationRules />
      <Script id='analytics-for-mpa' strategy='beforeInteractive' src='/analytics.js' />
    </ResourceContextProvider>
  )
}

export default MyApp
  1. Prerender पर क्लिक करें.

अब आपको पेज लोड होने में लगने वाले समय में काफ़ी सुधार दिखेगा. असल इस्तेमाल के मामले में, प्रीरेंडरिंग उस पेज के लिए ट्रिगर होती है जिसे उपयोगकर्ता कुछ अनुमानों के आधार पर अगली बार विज़िट कर सकता है.

प्रीरेंडरिंग के लिए, ऐप्लिकेशन के डेमो वीडियो का सैंपल

Analytics

डिफ़ॉल्ट रूप से, सैंपल वेब ऐप्लिकेशन में मौजूद analytics.js फ़ाइल, DOMContentLoaded इवेंट होने पर page-view इवेंट भेजती है. माफ़ करें, यह सही नहीं है, क्योंकि यह इवेंट प्रीरेंडरिंग फ़ेज़ के दौरान ट्रिगर होता है.

इस समस्या को ठीक करने के लिए, document.prerendering और prerenderingchange इवेंट को इस तरह से लागू करें:

  • analytics.js फ़ाइल को फिर से लिखो:

public/analytics.js

  const sendEvent = (type = 'pageview') => {
    // Codelab: Make analytics prerendering compatible.
    // The pageshow event could happen in the prerendered page before activation.
    // The prerendered page should be handled by the prerenderingchange event.
    if (document.prerendering) {
      return
    }
    console.log(`Send ${type} event for MPA navigation.`)
    fetch(`/api/analytics?from=${encodeURIComponent(location.pathname)}&type=${type}`)
  }
  ...

  // Codelab: Make analytics prerendering compatible.
  // The prerenderingchange event is triggered when the page is activated.
  document.addEventListener('prerenderingchange', () => {
    console.log('The prerendered page was activated.')
    sendEvent()
  })
  ...

बहुत बढ़िया! आपने अपने आंकड़ों में बदलाव कर लिया है, ताकि वे प्रीरेंडरिंग के साथ काम कर सकें. अब आपको ब्राउज़र कंसोल में, पेज-व्यू लॉग सही समय के साथ दिखेंगे.

4. bfcache को ब्लॉक करने वाले कॉम्पोनेंट हटाना

unload इवेंट हैंडलर को हटाना

ज़रूरत न होने पर भी unload इवेंट को शामिल करना, एक सामान्य गलती है. अब ऐसा करने का सुझाव नहीं दिया जाता. इससे न सिर्फ़ bfcache काम नहीं करता, बल्कि यह भरोसेमंद भी नहीं है. उदाहरण के लिए, यह हमेशा मोबाइल और Safari पर ट्रिगर नहीं होता.

unload इवेंट के बजाय, pagehide इवेंट का इस्तेमाल करें. यह इवेंट, unload इवेंट के ट्रिगर होने पर और किसी पेज को bfcache में रखने पर ट्रिगर होता है.

unload इवेंट हैंडलर को हटाने के लिए:

  • analytics.js फ़ाइल में, unload इवेंट हैंडलर के कोड को pagehide इवेंट हैंडलर के कोड से बदलें:

public/analytics.js

// Codelab: Remove the unload event handler for bfcache.
// The unload event handler prevents the content from being stored in bfcache. Use the pagehide event instead.
window.addEventListener('pagehide', () => {
  sendEvent('leave')
})

कैश मेमोरी कंट्रोल करने वाले हेडर को अपडेट करना

Cache-control: no-store एचटीटीपी हेडर का इस्तेमाल करके दिखाए गए पेजों को ब्राउज़र की bfcache सुविधा का फ़ायदा नहीं मिलता. इसलिए, इस हेडर का कम से कम इस्तेमाल करना बेहतर होता है. खास तौर पर, अगर पेज में लॉग इन की स्थिति जैसी निजी या ज़रूरी जानकारी नहीं है, तो शायद आपको उसे Cache-control: no-store एचटीटीपी हेडर के साथ दिखाने की ज़रूरत नहीं है.

सेंपल ऐप्लिकेशन के कैश-कंट्रोल हेडर को अपडेट करने के लिए:

  • getServerSideProps कोड में बदलाव करें:

pages/vegetables/index.js

export const getServerSideProps = middleware(async (ctx) => {
  const { req, res } = ctx
  // Codelab: Modify the cache-control header.
  res.setHeader('Cache-Control', 'public, s-maxage=10, stale-while-revalidate=59')
  ...

pages/vegetables/[name].js

export const getServerSideProps = middleware(async (ctx) => {
  const { req, res, query } = ctx
  // Codelab: Modify the cache-control header.
  res.setHeader('Cache-Control', 'public, s-maxage=10, stale-while-revalidate=59')
  ...

यह पता लगाना कि किसी पेज को bfcache से वापस लाया गया है या नहीं

pageshow इवेंट, पेज के शुरुआती लोड होने पर load इवेंट के ठीक बाद ट्रिगर होता है. साथ ही, जब भी पेज को bfcache से वापस लाया जाता है, तब भी यह इवेंट ट्रिगर होता है. pageshow इवेंट में persisted प्रॉपर्टी होती है. अगर पेज को bfcache से वापस लाया गया है, तो इसकी वैल्यू सही होती है. अगर पेज को bfcache से वापस नहीं लाया गया है, तो इसकी वैल्यू गलत होती है. persisted प्रॉपर्टी का इस्तेमाल करके, पेज के सामान्य लोड और बैक-फ़ॉरवर्ड कैश मेमोरी से पेज वापस लाने के बीच अंतर किया जा सकता है. ज़्यादातर बड़ी Analytics सेवाओं को bfcache के बारे में पता होना चाहिए. हालांकि, यह देखा जा सकता है कि पेज को bfcache से वापस लाया गया है या नहीं. साथ ही, इवेंट को मैन्युअल तरीके से भेजा जा सकता है.

यह पता लगाने के लिए कि किसी पेज को बैक/फ़ॉरवर्ड कैश मेमोरी से वापस लाया गया है या नहीं:

  • इस कोड को analytics.js फ़ाइल में जोड़ें.

public/analytics.js

  // Codelab: Use the pageshow event handler for bfcache.
  window.addEventListener('pageshow', (e) => {
    // If the persisted flag exists, the page was restored from bfcache.
    if (e.persisted) {
      console.log('The page was restored from bfcache.')
      sendEvent()
    }
  })

किसी वेब पेज को डीबग करना

Chrome डेवलपर टूल की मदद से, अपने पेजों की जांच की जा सकती है. इससे यह पक्का किया जा सकता है कि वे bfcache के लिए ऑप्टिमाइज़ किए गए हैं. साथ ही, उन समस्याओं की पहचान की जा सकती है जिनकी वजह से वे bfcache के लिए ज़रूरी शर्तें पूरी नहीं करते.

किसी पेज की जांच करने के लिए:

  1. Chrome में उस पेज पर जाएं.
  2. Chrome डेवलपर टूल में, ऐप्लिकेशन > बैक-फ़ॉरवर्ड कैश मेमोरी > टेस्ट चलाएं पर क्लिक करें.

Chrome डेवलपर टूल, पेज से बाहर जाने और फिर वापस आने की कोशिश करता है. इससे यह पता चलता है कि पेज को bfcache से वापस लाया जा सकता है या नहीं.

49bf965af35d5324.png

अगर पेज को बैक-फ़ॉरवर्ड कैश मेमोरी से वापस लाया जाता है, तो पैनल में यह जानकारी दिखती है:

47015a0de45f0b0f.png

अगर पेज को वापस नहीं लाया जा सका, तो पैनल में आपको इसकी जानकारी मिलेगी. साथ ही, इसकी वजह भी बताई जाएगी. अगर समस्या ऐसी है जिसे डेवलपर के तौर पर ठीक किया जा सकता है, तो पैनल में इसकी जानकारी भी दी जाती है.

dcf0312c3fc378ce.png

5. क्रॉस-साइट प्रीफ़ेचिंग की सुविधा चालू करना

प्रीफ़ेचिंग की सुविधा, फ़ेच करने की प्रोसेस को जल्दी शुरू कर देती है. इससे, जब उपयोगकर्ता नेविगेट करता है, तब बाइट पहले से ही ब्राउज़र में मौजूद होते हैं. इससे नेविगेशन की प्रोसेस तेज़ हो जाती है. यह वेबसाइट की परफ़ॉर्मेंस की मेट्रिक को बेहतर बनाने का एक आसान तरीका है. इससे नेविगेशन से पहले, कुछ नेटवर्क गतिविधि को ऑफ़सेट किया जा सकता है. इससे सबसे बड़े एलिमेंट को रेंडर करने में लगने वाला समय (एलसीपी) कम हो जाता है. साथ ही, नेविगेशन के दौरान फ़र्स्ट इनपुट डिले (एफ़आईडी) और लेआउट शिफ़्ट होने में लगने वाला समय (सीएलएस) कम हो जाता है.

निजी प्रीफ़ेच प्रॉक्सी, एक से ज़्यादा साइटों पर प्रीफ़ेच करने की सुविधा चालू करती है. हालांकि, यह उपयोगकर्ता की निजी जानकारी को डेस्टिनेशन सर्वर के साथ शेयर नहीं करती.

Private Prefetch Proxy कैसे काम करती है

Private Prefetch Proxy की मदद से, अलग-अलग साइटों पर पहले से फ़ेच करने की सुविधा चालू करना

वेबसाइट के मालिकों के पास, प्रीफ़ेचिंग को कंट्रोल करने का विकल्प होता है. इसके लिए, वे traffic-advice रिसोर्स का इस्तेमाल करते हैं. यह वेब क्रॉलर के लिए /robots.txt की तरह ही होता है. इससे एचटीटीपी सर्वर यह एलान कर सकता है कि लागू करने वाले एजेंट को इससे जुड़ी सलाह का पालन करना चाहिए. फ़िलहाल, वेबसाइट के मालिक एजेंट को नेटवर्क कनेक्शन को अनुमति न देने या थ्रॉटल करने का सुझाव दे सकते हैं. आने वाले समय में, इसमें अन्य सलाह भी जोड़ी जा सकती हैं.

ट्रैफ़िक की जानकारी देने वाले संसाधन को होस्ट करने के लिए:

  1. इस JSON जैसी फ़ाइल को जोड़ें:

public/.well-known/traffic-advice

[
  {
    "user_agent": "prefetch-proxy",
    "google_prefetch_proxy_eap": {
      "fraction": 1
    }
  }
]

google_prefetch_proxy_eap फ़ील्ड, अर्ली ऐक्सेस प्रोग्राम के लिए एक खास फ़ील्ड है. वहीं, fraction फ़ील्ड, अनुरोध की गई उन प्रीफ़ेच की संख्या को कंट्रोल करने के लिए होता है जिन्हें Private Prefetch Proxy भेजती है.

ट्रैफ़िक की जानकारी, application/trafficadvice+json MIME टाइप के साथ दिखाई जानी चाहिए.

  1. next.config.js फ़ाइल में, रिस्पॉन्स हेडर को कॉन्फ़िगर करें:

next.config.js

const nextConfig = {
  // Codelab: Modify content-type for traffic advice file.
  async headers() {
    return [
      {
        source: '/.well-known/traffic-advice',
        headers: [
          {
            key: 'Content-Type',
            value: 'application/trafficadvice+json',
          },
        ],
      },
    ]
  },
}

module.exports = nextConfig

6. Shared Element Transitions API को इंटिग्रेट करना

जब कोई उपयोगकर्ता वेब पर एक पेज से दूसरे पेज पर जाता है, तो उसे दिखने वाला कॉन्टेंट अचानक बदल जाता है. ऐसा इसलिए होता है, क्योंकि पहला पेज गायब हो जाता है और नया पेज दिखने लगता है. उपयोगकर्ता को अलग-अलग चरणों में मिलने वाला यह अनुभव, उसे भ्रमित कर सकता है. साथ ही, इससे उस पर ज़्यादा मानसिक दबाव पड़ता है, क्योंकि उसे यह पता लगाना होता है कि वह इस पेज पर कैसे पहुंचा. इसके अलावा, इस अनुभव से उपयोगकर्ताओं को यह पता चलता है कि पेज लोड होने में कितना समय लगेगा.

लोडिंग के दौरान दिखने वाले स्मूथ ऐनिमेशन से, उपयोगकर्ताओं पर पड़ने वाला मानसिक दबाव कम होता है. ऐसा इसलिए, क्योंकि वे एक पेज से दूसरे पेज पर जाते समय कॉन्टेक्स्ट में बने रहते हैं. साथ ही, इससे लोडिंग के दौरान लगने वाले समय में भी कमी आती है, क्योंकि इस दौरान उपयोगकर्ताओं को कुछ दिलचस्प और मज़ेदार दिखता है. इन वजहों से, ज़्यादातर प्लैटफ़ॉर्म ऐसे प्रिमिटिव उपलब्ध कराते हैं जिन्हें इस्तेमाल करना आसान होता है. इनकी मदद से डेवलपर, ट्रांज़िशन को आसानी से बना सकते हैं. जैसे, Android, iOS, MacOS, और Windows.

शेयर्ड एलिमेंट ट्रांज़िशन एपीआई, डेवलपर को वेब पर एक जैसी सुविधा देता है. इससे कोई फ़र्क़ नहीं पड़ता कि ट्रांज़िशन क्रॉस-डॉक्यूमेंट (एमपीए) हैं या इंट्रा-डॉक्यूमेंट (एसपीए).

pixiv का Shared Element Transitions API डेमो Tokopedia का शेयर किए गए एलिमेंट के ट्रांज़िशन एपीआई का डेमो

pixiv और Tokopedia के डेमो

सैंपल ऐप्लिकेशन के एसपीए वाले हिस्से के लिए, Shared Element Transitions API को इंटिग्रेट करने के लिए:

  1. use-page-transition.js फ़ाइल में ट्रांज़िशन को मैनेज करने के लिए, कस्टम हुक बनाएं:

utils/use-page-transition.js

import { useEffect, useContext, useRef, useCallback } from 'react'
import ResourceContext from '../components/resource-context'

// Call this hook on this first page before you start the page transition. For Shared Element Transitions, you need to call the transition.start() method before the next page begins to render, and you need to do the Document Object Model (DOM) modification or setting of new shared elements inside the callback so that this hook returns the promise and defers to the callback resolve.
export const usePageTransitionPrep = () => {
  const { dispatch } = useContext(ResourceContext)

  return (elm) => {
    const sharedElements = elm.querySelectorAll('.shared-element')
    // Feature detection
    if (!document.createDocumentTransition) {
      return null
    }

    return new Promise((resolve) => {
      const transition = document.createDocumentTransition()
      Array.from(sharedElements).forEach((elm, idx) => {
        transition.setElement(elm, `target-${idx}`)
      })
      transition.start(async () => {
        resolve()
        await new Promise((resolver) => {
          dispatch({ type: 'update', transition: { transition, resolver } })
        })
      })
    })
  }
}

// Call this hook on the second page. Inside the useEffect hook, you can refer to the actual DOM element and set them as shared elements with the transition.setElement() method. When the resolver function is called, the transition is initiated between the captured images and newly set shared elements.
export const usePageTransition = () => {
  const { state, dispatch } = useContext(ResourceContext)
  const ref = useRef(null)
  const setRef = useCallback((node) => {
    ref.current = node
  }, [])

  useEffect(() => {
    if (!state.transition || !ref.current) {
      return
    }
    const { transition, resolver } = state.transition
    const sharedElements = ref.current.querySelectorAll('.shared-element')
    Array.from(sharedElements).forEach((elm, idx) => {
      transition.setElement(elm, `target-${idx}`)
    })
    resolver()
    return () => {
      dispatch({ type: 'update', transition: null })
    }
  })

  return setRef
}
  1. लिस्ट पेज में usePageTransitionPrep() कस्टम हुक को कॉल करें. इसके बाद, click इवेंट में transition.start() तरीके को ट्रिगर करने के लिए, एसिंक फ़ंक्शन को कॉल करें.

फ़ंक्शन के अंदर, shared-element क्लास के एलिमेंट इकट्ठा किए जाते हैं और उन्हें शेयर किए गए एलिमेंट के तौर पर रजिस्टर किया जाता है.

components/list-item.js

// Codelab: Add the Shared Element Transitions API.
import { usePageTransitionPrep } from '../utils/use-page-transition'
...

function ListItemForSPA({ item, href }) {
  // Codelab: Add Shared Element Transitions.
  const transitionNextState = usePageTransitionPrep()
  const handleClick = async (e) => {
    const elm = e.target.closest('a')
    await transitionNextState(elm)
  }
  return (
    <Link href={href}>
      <a className='block flex items-center' onClick={handleClick}>
        <Icon src={item.image} name={item.name} className='shared-element' />
        <div className='text-xl'>{item.name}</div>
      </a>
    </Link>
  )
}
  1. ज़्यादा जानकारी वाले पेज पर, usePageTransition() हुक को कॉल करें, ताकि transition.start() कॉलबैक फ़ंक्शन पूरा हो सके.

इस कॉलबैक में, ज़्यादा जानकारी वाले पेज में शेयर किए गए एलिमेंट भी रजिस्टर किए जाते हैं.

pages/fruits/[name].js

// Codelab: Add the Shared Element Transitions API.
import { usePageTransition } from '../../utils/use-page-transition'

const Item = ({ data }) => {
  const { name, image, amountPer, nutrition } = data
  // Codelab: Add the Shared Element Transitions API.
  const ref = usePageTransition()

  return (
    <div className={'flex flex-col items-center justify-center py-4 px-4 sm:flex-row'} ref={ref}>
      <div className='flex flex-col items-center sm:w-2/4'>
        <Image
          className='object-cover border-gray-100 border-2 rounded-full shared-element'
          src={image}
          width='240'
          height='240'
          alt={`picture of ${name}`}
        />
        <h1 className='text-4xl font-bold mt-4'>{name}</h1>
      </div>

      <div className='sm:w-2/4 w-full'>
        <Nutrition amountPer={amountPer} nutrition={nutrition} />
      </div>
    </div>
  )
...
}

अब आपको दिखेगा कि इमेज एलिमेंट, सूची और जानकारी वाले पेजों पर शेयर किए गए हैं. साथ ही, पेज ट्रांज़िशन में आसानी से कनेक्ट किए गए हैं. सीएसएस सूडो-एलिमेंट का इस्तेमाल करके, ऐनिमेशन को अपनी पसंद के मुताबिक बनाया जा सकता है, ताकि वह और भी ज़्यादा आकर्षक लगे.

शेयर्ड एलिमेंट ट्रांज़िशन के बिना, सैंपल ऐप्लिकेशन का डेमो वीडियो शेयर्ड एलिमेंट ट्रांज़िशन के साथ ऐप्लिकेशन के डेमो वीडियो का सैंपल

7. बधाई हो

बधाई हो! आपने एक ऐसा वेब ऐप्लिकेशन बनाया है जो तुरंत खुल जाता है और आसानी से काम करता है. साथ ही, यह उपयोगकर्ताओं को दिलचस्प अनुभव देता है और इसे इस्तेमाल करना आसान है.

ज़्यादा जानें

प्रीरेंडरिंग

bfcache

क्रॉस-साइट प्रीफ़ेचिंग

साइन किए गए एक्सचेंज

रूट/शेयर किए गए एलिमेंट के ट्रांज़िशन

ये एपीआई अब भी डेवलपमेंट के शुरुआती चरण में हैं. इसलिए, कृपया अपने सुझाव/राय/शिकायत crbug.com पर शेयर करें. इसके अलावा, इन्हें संबंधित एपीआई के GitHub डेटाबेस में समस्याओं के तौर पर भी शेयर किया जा सकता है.