১. শুরু করার আগে
এই কোডল্যাবটি আপনাকে শেখাবে কীভাবে গুগল ক্রোমের নেটিভ সাপোর্টেড সর্বশেষ এপিআই ব্যবহার করে একটি নমুনা ওয়েব অ্যাপে ইনস্ট্যান্ট নেভিগেশন এবং নির্বিঘ্ন পেজ ট্রানজিশন যোগ করতে হয়।
নমুনা ওয়েব অ্যাপটি জনপ্রিয় ফল ও সবজির পুষ্টিগুণ যাচাই করে। ফলের তালিকা এবং ফলের বিবরণ পৃষ্ঠাগুলো একটি একক-পৃষ্ঠার অ্যাপ (SPA) হিসেবে তৈরি করা হয়েছে, এবং সবজির তালিকা ও সবজির বিবরণ পৃষ্ঠাগুলো একটি প্রচলিত একাধিক-পৃষ্ঠার অ্যাপ (MPA) হিসেবে তৈরি করা হয়েছে।


বিশেষভাবে, আপনি তাৎক্ষণিক নেভিগেশনের জন্য প্রি-রেন্ডারিং , ব্যাক/ফরোয়ার্ড ক্যাশে (bfcache), এবং প্রাইভেট প্রিফেচ প্রক্সি , এবং নির্বিঘ্ন পেজ ট্রানজিশনের জন্য রুট/শেয়ার্ড এলিমেন্ট ট্রানজিশন প্রয়োগ করেন। আপনি MPA পেজগুলোর জন্য প্রি-রেন্ডারিং এবং bfcache, এবং SPA পেজগুলোর জন্য শেয়ার্ড এলিমেন্ট ট্রানজিশন প্রয়োগ করেন।
সাইটের গতি ব্যবহারকারীর অভিজ্ঞতার একটি অত্যন্ত গুরুত্বপূর্ণ দিক, আর একারণেই গুগল ‘কোর ওয়েব ভাইটালস’ (Core Web Vitals) চালু করেছে। এটি এমন কিছু মেট্রিকের সমষ্টি যা বাস্তব ব্যবহারকারীর অভিজ্ঞতা পরিমাপ করার জন্য ওয়েব পেজের লোড পারফরম্যান্স, ইন্টারঅ্যাকটিভিটি এবং ভিজ্যুয়াল স্ট্যাবিলিটি নিরূপণ করে। সর্বশেষ এপিআইগুলো (API) আপনাকে আপনার ওয়েবসাইটের কোর ওয়েব ভাইটালস স্কোর বাস্তবে উন্নত করতে সাহায্য করে, বিশেষ করে লোড পারফরম্যান্সের ক্ষেত্রে।

মাইন্ডভ্যালি থেকে ডেমো
মোবাইল নেটিভ অ্যাপে নেভিগেশন এবং স্টেট পরিবর্তনকে অত্যন্ত স্বজ্ঞাত করার জন্য ব্যবহারকারীরা ট্রানজিশনের ব্যবহারে অভ্যস্ত। দুর্ভাগ্যবশত, ওয়েবে এই ধরনের ইউজার এক্সপেরিয়েন্সের প্রতিলিপি তৈরি করা সহজসাধ্য নয়। যদিও আপনি বর্তমান ওয়েব-প্ল্যাটফর্ম এপিআই (API) ব্যবহার করে একই ধরনের প্রভাব অর্জন করতে সক্ষম হতে পারেন, তবে এর ডেভেলপমেন্ট বেশ কঠিন বা জটিল হতে পারে, বিশেষ করে অ্যান্ড্রয়েড বা আইওএস অ্যাপের ফিচারগুলোর সাথে তুলনা করলে। অ্যাপ এবং ওয়েবের মধ্যে ব্যবহারকারী ও ডেভেলপারের অভিজ্ঞতার এই ব্যবধান পূরণ করার জন্যই সিমলেস এপিআই (Seamless API) ডিজাইন করা হয়েছে।


পিক্সিভ এবং টোকোপিডিয়া থেকে ডেমো
পূর্বশর্ত
জ্ঞান:
- এইচটিএমএল
- সিএসএস
- জাভাস্ক্রিপ্ট
- গুগল ক্রোম ডেভেলপার টুলস
আপনি যা শিখবেন:
কীভাবে বাস্তবায়ন করবেন:
- প্রি-রেন্ডারিং
- বিএফক্যাশ
- ব্যক্তিগত প্রিফেচ প্রক্সি
- রুট/শেয়ার করা উপাদানের রূপান্তর
আপনি যা তৈরি করবেন
Next.js দিয়ে তৈরি একটি নমুনা ওয়েব অ্যাপ, যা সর্বশেষ তাৎক্ষণিক ও নির্বিঘ্ন ব্রাউজার সুবিধা দিয়ে সমৃদ্ধ:
- প্রি-রেন্ডারিং সহ প্রায়-তাৎক্ষণিক নেভিগেশন
- ব্রাউজারের ব্যাকওয়ার্ড এবং ফরওয়ার্ড বাটনের সাথে তাৎক্ষণিক লোডের জন্য বিএফক্যাশ (bfcache) ব্যবহার করুন।
- প্রাইভেট প্রিফেচ প্রক্সি বা সাইনড এক্সচেঞ্জ (SXG) ব্যবহার করে ক্রস-অরিজিন নেভিগেশনের প্রথম অভিজ্ঞতা দারুণ।
- রুট/শেয়ার করা এলিমেন্ট ট্রানজিশনের মাধ্যমে পেজগুলোর মধ্যে একটি নির্বিঘ্ন রূপান্তর
আপনার যা যা লাগবে
- ক্রোম সংস্করণ ১০১ বা তার উচ্চতর
২. শুরু করুন
ক্রোম ফ্ল্যাগ সক্রিয় করুন
- about://flags-এ যান এবং তারপরে
Prerender2ওdocumentTransition APIরানটাইম ফ্ল্যাগগুলো সক্রিয় করুন। - আপনার ব্রাউজারটি পুনরায় চালু করুন।
কোডটি নিন
- আপনার পছন্দের ডেভেলপমেন্ট এনভায়রনমেন্টে এই গিটহাব রিপোজিটরি থেকে কোডটি খুলুন:
git clone -b codelab git@github.com:googlechromelabs/instant-seamless-demo.git
- সার্ভার চালানোর জন্য প্রয়োজনীয় ডিপেন্ডেন্সিগুলো ইনস্টল করুন:
npm install
- পোর্ট 3000-এ সার্ভারটি চালু করুন:
npm run dev
- আপনার ব্রাউজারে http://localhost:3000- এ যান।
এখন আপনি আপনার অ্যাপটি সম্পাদনা ও উন্নত করতে পারবেন। যখনই আপনি কোনো পরিবর্তন করবেন, অ্যাপটি রিলোড হবে এবং আপনার পরিবর্তনগুলো সরাসরি দেখা যাবে।
৩. প্রি-রেন্ডারিং একীভূত করুন
এই ডেমোর জন্য, স্যাম্পল অ্যাপে সবজির বিবরণ পেজটি লোড হতে খুব বেশি সময় লাগে, যার কারণ হলো সার্ভার সাইডে একটি অনির্দিষ্ট বিলম্ব। প্রি-রেন্ডারিং ব্যবহার করে আপনি এই অপেক্ষার সময়টি দূর করতে পারেন।
সবজির তালিকার পেজে প্রি-রেন্ডার বাটন যোগ করতে এবং ব্যবহারকারীর ক্লিকের পর সেগুলোর প্রি-রেন্ডারিং চালু করতে:
- একটি বাটন কম্পোনেন্ট তৈরি করুন, যা ডাইনামিকভাবে speculation-rules স্ক্রিপ্ট ট্যাগটি যুক্ত করবে:
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>
)
}
-
list-item.jsফাইলেPrerenderButtonকম্পোনেন্টটি ইম্পোর্ট করুন।
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>
)
}
- 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])
}
- অ্যাপের সাথে উপাদানগুলো সংযুক্ত করুন।
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
- প্রি-রেন্ডার-এ ক্লিক করুন।
এখন আপনি লোডিং-এর উল্লেখযোগ্য উন্নতি দেখতে পাচ্ছেন। বাস্তব ক্ষেত্রে, কিছু হিউরিস্টিকসের মাধ্যমে ব্যবহারকারীর পরবর্তী সম্ভাব্য পেজটির জন্য প্রি-রেন্ডারিং চালু করা হয়।

বিশ্লেষণ
ডিফল্টরূপে, নমুনা ওয়েব অ্যাপের analytics.js ফাইলটি DOMContentLoaded ইভেন্টটি ঘটলে একটি page-view ইভেন্ট পাঠায়। দুর্ভাগ্যবশত, এটি বুদ্ধিমানের কাজ নয়, কারণ এই ইভেন্টটি প্রি-রেন্ডারিং পর্যায়ে ফায়ার হয়।
এই সমস্যাটি সমাধান করার জন্য document.prerendering এবং prerenderingchange ইভেন্ট চালু করতে:
-
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()
})
...
চমৎকার, আপনি সফলভাবে আপনার অ্যানালিটিক্স পরিবর্তন করেছেন যাতে তা প্রি-রেন্ডারিংয়ের সাথে সামঞ্জস্যপূর্ণ হয়। এখন আপনি ব্রাউজার কনসোলে সঠিক সময়সহ পেজ-ভিউ লগগুলো দেখতে পারবেন।
৪. বিএফক্যাশ ব্লকারগুলি সরান
unload ইভেন্ট হ্যান্ডলারটি সরিয়ে ফেলুন
অপ্রয়োজনীয় unload ইভেন্ট থাকা একটি খুব সাধারণ ভুল যা এখন আর সুপারিশ করা হয় না। এটি শুধু bfcache-এর কাজকেই বাধা দেয় না, বরং এটি অনির্ভরযোগ্যও। উদাহরণস্বরূপ, এটি মোবাইল এবং সাফারিতে সবসময় চালু হয় না।
unload ইভেন্টের পরিবর্তে, আপনি pagehide ইভেন্ট ব্যবহার করেন, যা unload ইভেন্ট ঘটলে এবং কোনো পেজ বিএফক্যাশে (bfcache) রাখা হলে সব ক্ষেত্রেই ফায়ার হয়।
unload ইভেন্ট হ্যান্ডলারটি অপসারণ করতে:
-
analytics.jsফাইলে,unloadইভেন্ট হ্যান্ডলারের কোডটিpagehideইভেন্ট হ্যান্ডলারের কোড দিয়ে প্রতিস্থাপন করুন:
পাবলিক/অ্যানালিটিক্স.জেএস
// 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 HTTP হেডার দিয়ে পরিবেশিত পেজগুলো ব্রাউজারের bfcache ফিচারের সুবিধা পায় না, তাই এই হেডারটি ব্যবহারে মিতব্যয়ী হওয়া ভালো। বিশেষ করে, যদি পেজটিতে ব্যক্তিগত বা গুরুত্বপূর্ণ তথ্য, যেমন লগ-ইন করা অবস্থা, না থাকে, তাহলে সম্ভবত আপনার এটি Cache-control: no-store HTTP হেডার দিয়ে পরিবেশন করার প্রয়োজন নেই।
স্যাম্পল অ্যাপটির ক্যাশ-কন্ট্রোল হেডার আপডেট করতে:
-
getServerSidePropsকোডটি পরিবর্তন করুন:
পৃষ্ঠা/সবজি/সূচক.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 থেকে একটি পৃষ্ঠা পুনরুদ্ধার করা হয়েছে কিনা তা নির্ধারণ করুন
পেজটি প্রথমবার লোড হওয়ার সময় এবং যখনই পেজটি বিএফক্যাশ (bfcache) থেকে রিস্টোর করা হয়, তখন load ইভেন্টের ঠিক পরেই pageshow ইভেন্টটি ফায়ার হয়। pageshow ইভেন্টের একটি persisted ) প্রপার্টি আছে, যা পেজটি বিএফক্যাশ থেকে রিস্টোর করা হলে ট্রু (true) এবং না করা হলে ফলস (false) হয়। সাধারণ পেজ লোড এবং বিএফক্যাশ রিস্টোরের মধ্যে পার্থক্য করার জন্য আপনি persisted প্রপার্টিটি ব্যবহার করতে পারেন। প্রধান অ্যানালিটিক্স সার্ভিসগুলোর বিএফক্যাশ সম্পর্কে অবগত থাকার কথা, কিন্তু পেজটি বিএফক্যাশ থেকে রিস্টোর করা হয়েছে কিনা তা আপনি ম্যানুয়ালি পরীক্ষা করে ইভেন্ট পাঠাতে পারেন।
কোনো পৃষ্ঠা bfcache থেকে পুনরুদ্ধার করা হয়েছে কিনা তা নির্ধারণ করতে:
- এই কোডটি
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()
}
})
একটি ওয়েব পেজ ডিবাগ করুন
আপনার পেজগুলো bfcache-এর জন্য অপ্টিমাইজ করা আছে কিনা তা পরীক্ষা করতে এবং সেগুলোকে অযোগ্য করে তুলতে পারে এমন কোনো সমস্যা শনাক্ত করতে Chrome Developer Tools আপনাকে সাহায্য করতে পারে।
একটি নির্দিষ্ট পৃষ্ঠা পরীক্ষা করতে:
- ক্রোমে পৃষ্ঠাটিতে যান।
- ক্রোম ডেভেলপার টুলস-এ, অ্যাপ্লিকেশন > ব্যাক-ফরোয়ার্ড ক্যাশে > রান টেস্ট-এ ক্লিক করুন।
ক্রোম ডেভেলপার টুলস পেজটি bfcache থেকে পুনরুদ্ধার করা যাবে কিনা তা নির্ধারণ করতে অন্য পেজে গিয়ে আবার ফিরে আসার চেষ্টা করে।

সফল হলে, প্যানেলটি আপনাকে জানিয়ে দেয় যে পৃষ্ঠাটি ব্যাক-ফরোয়ার্ড ক্যাশে থেকে পুনরুদ্ধার করা হয়েছে:

ব্যর্থ হলে, প্যানেলটি আপনাকে জানিয়ে দেয় যে পৃষ্ঠাটি পুনরুদ্ধার করা হয়নি এবং তার কারণও জানায়। যদি কারণটি এমন কিছু হয় যা আপনি একজন ডেভেলপার হিসেবে সমাধান করতে পারেন, তাহলে প্যানেলটি আপনাকে সেটাও জানিয়ে দেয়।

৫. ক্রস-সাইট প্রিফেচিং সক্ষম করুন
প্রিফেচিং আগেভাগেই ডেটা ফেচ করা শুরু করে, যাতে ব্যবহারকারী নেভিগেট করার সময় বাইটগুলো ইতিমধ্যেই ব্রাউজারে থাকে, যা নেভিগেশনকে ত্বরান্বিত করে। এটি কোর ওয়েব ভাইটালস উন্নত করার এবং নেভিগেশনের আগে কিছু নেটওয়ার্ক কার্যকলাপকে সরিয়ে দেওয়ার একটি সহজ উপায়। এটি সরাসরি লার্জেস্ট কনটেন্টফুল পেইন্ট (LCP)-কে ত্বরান্বিত করে এবং নেভিগেশনের সময় ফার্স্ট ইনপুট ডিলে (FID) ও কিউমুলেটিভ লেআউট শিফট (CLS)-এর জন্য আরও জায়গা করে দেয়।
প্রাইভেট প্রিফেচ প্রক্সি ক্রস-সাইট প্রিফেচ সক্ষম করে, কিন্তু ব্যবহারকারীর ব্যক্তিগত তথ্য গন্তব্য সার্ভারের কাছে প্রকাশ করে না।

প্রাইভেট প্রিফেচ প্রক্সি ব্যবহার করে ক্রস-সাইট প্রিফেচিং সক্রিয় করুন
ওয়েবসাইট মালিকরা একটি সুপরিচিত ট্র্যাফিক-অ্যাডভাইস রিসোর্সের মাধ্যমে প্রিফেচিং-এর নিয়ন্ত্রণ বজায় রাখেন, যা ওয়েব ক্রলারদের জন্য /robots.txt এর অনুরূপ। এটি একটি HTTP সার্ভারকে ঘোষণা করার সুযোগ দেয় যে, বাস্তবায়নকারী এজেন্টরা যেন সংশ্লিষ্ট পরামর্শটি প্রয়োগ করে। বর্তমানে, ওয়েবসাইট মালিকরা এজেন্টকে নেটওয়ার্ক সংযোগ নিষিদ্ধ করতে বা তার গতি কমিয়ে দিতে পরামর্শ দিতে পারেন। ভবিষ্যতে, অন্যান্য পরামর্শও যোগ করা হতে পারে।
ট্র্যাফিক-পরামর্শের একটি রিসোর্স হোস্ট করতে:
- এই JSON-সদৃশ ফাইলটি যোগ করুন:
পাবলিক/সুপরিচিত/ট্র্যাফিক-পরামর্শ
[
{
"user_agent": "prefetch-proxy",
"google_prefetch_proxy_eap": {
"fraction": 1
}
}
]
google_prefetch_proxy_eap ফিল্ডটি আর্লি-অ্যাক্সেস প্রোগ্রামের জন্য একটি বিশেষ ফিল্ড এবং ` fraction ফিল্ডটি প্রাইভেট প্রিফেচ প্রক্সি দ্বারা প্রেরিত অনুরোধকৃত প্রিফেচগুলোর ভগ্নাংশ নিয়ন্ত্রণ করে।
ট্র্যাফিক অ্যাডভাইস application/trafficadvice+json MIME টাইপ সহ ফেরত দেওয়া উচিত।
-
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
৬. শেয়ার্ড এলিমেন্ট ট্রানজিশন এপিআই একীভূত করুন
যখন কোনো ব্যবহারকারী ওয়েবে এক পৃষ্ঠা থেকে অন্য পৃষ্ঠায় যান, তখন প্রথম পৃষ্ঠাটি অদৃশ্য হয়ে নতুন পৃষ্ঠাটি প্রদর্শিত হওয়ায় তাদের দেখা বিষয়বস্তু হঠাৎ এবং অপ্রত্যাশিতভাবে পরিবর্তিত হয়। এই ক্রমিক ও বিচ্ছিন্ন ব্যবহারকারীর অভিজ্ঞতা বিভ্রান্তিকর এবং এর ফলে মানসিক চাপ বৃদ্ধি পায়, কারণ ব্যবহারকারীকে বুঝতে হয় তিনি কীভাবে বর্তমান অবস্থানে পৌঁছালেন। এছাড়াও, কাঙ্ক্ষিত গন্তব্যে পৌঁছানোর জন্য অপেক্ষা করার সময় পৃষ্ঠাটি লোড হচ্ছে বলে ব্যবহারকারীর ধারণা আরও বেড়ে যায়।
মসৃণ লোডিং অ্যানিমেশন ব্যবহারকারীর মানসিক চাপ কমায়, কারণ তারা পৃষ্ঠাগুলির মধ্যে নেভিগেট করার সময় প্রাসঙ্গিক বিষয়বস্তু দেখতে পান। এটি লোডিংয়ের অনুভূত বিলম্বও হ্রাস করে, কারণ এই সময়ের মধ্যে ব্যবহারকারীরা আকর্ষণীয় ও আনন্দদায়ক কিছু দেখতে পান। এইসব কারণে, বেশিরভাগ প্ল্যাটফর্ম, যেমন অ্যান্ড্রয়েড, আইওএস, ম্যাকওএস এবং উইন্ডোজ, সহজে ব্যবহারযোগ্য প্রিমিটিভ সরবরাহ করে, যা ডেভেলপারদের নির্বিঘ্ন ট্রানজিশন তৈরি করতে সাহায্য করে।
শেয়ার্ড এলিমেন্ট ট্রানজিশনস এপিআই ডেভেলপারদের ওয়েবে একই সক্ষমতা প্রদান করে, ট্রানজিশনগুলো ক্রস-ডকুমেন্ট (MPA) বা ইন্ট্রা-ডকুমেন্ট (SPA) যাই হোক না কেন।


পিক্সিভ এবং টোকোপিডিয়া থেকে ডেমো
স্যাম্পল অ্যাপের SPA অংশের জন্য Shared Element Transitions API ইন্টিগ্রেট করতে:
-
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
}
- লিস্ট পেজে
usePageTransitionPrep()কাস্টম হুকটি কল করুন এবং তারপরেclickইভেন্টের ভিতরেtransition.start()মেথডটি ট্রিগার করতে async ফাংশনটি কল করুন।
ফাংশনের ভিতরে, 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>
)
}
- ডিটেইলস পেজে,
transition.start()কলব্যাক ফাংশনটি সম্পন্ন করতেusePageTransition()হুকটি কল করুন।
এই কলব্যাকে, ডিটেইল পেজের শেয়ার করা এলিমেন্টগুলোও রেজিস্টার করা হয়।
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>
)
...
}
এখন আপনি দেখতে পাচ্ছেন যে, ইমেজ এলিমেন্টগুলো লিস্ট এবং ডিটেইল পেজে শেয়ার করা হয়েছে এবং পেজ ট্রানজিশনে সেগুলো নির্বিঘ্নে সংযুক্ত রয়েছে। এমনকি আপনি CSS সিউডো-এলিমেন্ট ব্যবহার করে অ্যানিমেশনটিকে আরও আকর্ষণীয় করে কাস্টমাইজ করতে পারেন।


৭. অভিনন্দন
অভিনন্দন! আপনি একটি সহজ, আকর্ষণীয় এবং স্বজ্ঞাত ব্যবহারকারী অভিজ্ঞতাসহ একটি তাৎক্ষণিক ও নির্বিঘ্ন ওয়েব অ্যাপ তৈরি করেছেন।
আরও জানুন
প্রি-রেন্ডারিং
- প্রি-রেন্ডারিং, নতুন করে সাজানো
- স্পেকুলেটিভ প্রি-রেন্ডারিংয়ের মাধ্যমে ব্রাউজারে তাৎক্ষণিক পেজ লোড করা
- কুইকলিঙ্ক
বিএফক্যাশ
ক্রস-সাইট প্রিফেচিং
স্বাক্ষরিত বিনিময়
রুট/শেয়ার করা উপাদানের রূপান্তর
- শেয়ার করা উপাদান রূপান্তর
- শেয়ার্ড এলিমেন্ট ট্রানজিশন এপিআই (Shared Element Transitions API) ব্যবহার করে মসৃণ এবং সহজ পেজ ট্রানজিশন
এই API-গুলো এখনও উন্নয়নের প্রাথমিক পর্যায়ে রয়েছে, তাই অনুগ্রহ করে crbug.com- এ অথবা প্রাসঙ্গিক API-গুলোর গিটহাব রিপোজিটরিতে ইস্যু হিসেবে আপনার মতামত জানান।