قابلیت‌های جدید Next.js

?What is New in Next.js

26 آبان 1400
قابلیت های جدید در Next.js

Next.js یک فریم ورک محبوب است که قدرت react را به سمت سرور می آورد. شما می توانید با استفاده از این فریم ورک قابلیت هایی مانند Server Side-Rendering و امثال آن را انجام بدهید و در عین حال از ویژگی های قدرتمند next مانند داشتن یک سیستم routing فایل محور نیز استفاده کنید. اخیرا نسخه ۱۱ از next.js توسط تیم توسعه next معرفی شد، بنابراین فرصت خوبی است که قابلیت های جدید next.js در دو نسخه اخیر (۱۰ و ۱۱) را به صورت خلاصه بررسی کنیم چرا که این دو نسخه قابلیت های مهمی را به next اضافه کرده اند.

سطح مقاله: این مقاله برای افرادی تنظیم شده است که با next.js کار کرده اند. اگر با next.js آشنا نیستید، خواندن این مقاله به شما پیشنهاد نمی شود.

وبپک ۵

از این به بعد next.js به صورت پیش فرض از webpack 5 استفاده می کند و نیازی به تعریف فایل پیکربندی خاص (next.config.js) ندارد. قبلا برای استفاده از webpack 5 باید در فایل پیکربندی next.config.js به صورت دستی تنظیماتی را اعمال می کردید. با انجام این کار به قابلیت هایی مانند fast refresh دسترسی خواهیم داشت و زمان راه اندازی سرور توسعه نیز کمتر می شود. زمانی که وبپک ۵ فعال باشد قابلیت های زیر را نیز خواهید داشت:

  • Caching بهتر: کشینگ به کامپایلر اجازه می دهد که بین دستورات next build از نتایج قبلی نیز استفاده کند. در این مدل جدید فقط فایل های تغییر پیدا کرده دوباره compile می شود و فایل های قبلی دست نخورده باقی می مانند. برخی از توسعه دهندگان next گزارش داده اند که build های آن ها حدود 63 درصد سریع تر شده است.
  • Fast Refresh بهتر: next.js از این به بعد از قابلیت ارتقاء یافته fast refresh استفاده می کند که به طور متوسط حدود ۱۰۰ تا ۲۰۰ میلی ثانیه در هر refresh سریع تر است.
  • Caching دراز مدت: از این به بعد next می تواند به شکل بهتری از کشینگ در دراز مدت استفاده کند. به طور مثال در این سیستم جدید اگر محتوایی تغییر نکرده باشد هش (hash) آن نیز تغییر نخواهد کرد تا بین دستورات next build بازتولید نشوند.
  • Tree Shaking بهتر: همانطور که می دانید Tree Shaking به معنی حذف کد های بی استفاده یا به اصطلاح مُرده از باندل نهایی است. این قابلیت برای کسانی که از ماژول های CommonJS استفاده می کنند قابل دسترسی نبود اما از این به بعد قابل دسترسی است.

تیم توسعه next توضیح داده است که حدود ۳۴۰۰ تست جداگانه را روی هر pull request در گیت هاب انجام داده اند تا مطمئن شوند استفاده از وبپک ۵ برای کاربرانشان هیچ مشکلی ایجاد نمی کند!

راه اندازی سریع تر

همانطور که می دانید در next دستوری به نام next dev وجود دارد که سرور توسعه را راه اندازی می کند. از این به بعد این دستور پس از اولین اجرا ۲۴ درصد سریع تر عمل می کند. به طور مثال vercel گزارش می دهد که این زمان از ۳.۳ ثانیه به ۲.۵ ثانیه رسیده است.

همچنین dependency graph (وابستگی های next به پکیج های دیگر) جدید و به روز رسانی شده اند تا علاوه بر سرعت بیشتر در زمان نصب next.js در سیستم توسعه دهندگان، سایز کوچک تری نیز داشته باشد. در نسخه های قبلی next.js حجم وابستگی ها حدود ۹۶.۵ مگابایت بود در حالی که از نسخه ۱۰.۱ حجم این وابستگی ها حدود ۳۹.۹ مگابایت است! زمان نصب نیز از ۱۵ ثاینه به ۵ ثاینه رسیده است که یعنی حجم وابستگی ها ۵۸ درصد کوچک تر و سرعت نصب ۳ برابر سریع تر شده است. تعداد این وابستگی ها در نسخه های قبلی حدود ۴۲۴ پکیج بوده است که در نسخه جدید به ۱۸۷ پکیج رسیده است.

همچنین در نسخه ۱۱ از next.js تیم توسعه یک Babel loader کاملا جدید را برای webpack نوشته اند که یک لایه کشینگ را به آن اضافه می کند و باعث افزایش سرعت پروژه می شود. در نظر داشته باشید که شما به عنوان توسعه دهنده هیچ تغییری را در این زمینه احساس نمی کنید به جز اینکه سرعت کامپایل شدن پروژه بالاتر رفته است.

دسترسی پذیری (Accessibility)

دسترسی پذیری به مجموعه ای از مفاهیم گفته می شود که به کاربران دارای نقص جسمی کمک می کند بدون مشکل با وب سایت شما تعامل داشته باشند. به طور مثال کاربران کم بینا یا نابینا برای استفاده از وب سایت شما از دستگاه های صفحه خوان (screen reader) استفاده می کنند. از این به بعد next.js تغییر آدرس صفحه را به صورت خودکار به این دستگاه ها اعلام می کند

routing بر اساس header و Query Parameters

از این به بعد دستورات rewrite و redirect و headers خصوصیتی به نام has را دارند که به شما اجازه می دهد header ها یا cookies ها یا query string ها را دریافت کنید. یک مثال کاربردی از این قابلیت redirect کردن کاربران دارای مرورگر قدیمی بر اساس خصوصیت User-Agent در header درخواست ارسال شده است. برای این کار به فایل پیکربندی next.config.js می رویم و می گوییم:

module.exports = {

  async redirects() {

    return [

      {

        source: '/:path((?!old-browser$).*)',

        has: [

          {

            type: 'header',

            key: 'User-Agent',

            value:

              'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; Microsoft; Lumia 950)'

          }

        ],

        destination: '/old-browser',

        permanent: false

      }

    ]

  }

}

همانطور که می بینید کد بالا مشخص کرده است که هر کاربری با مرورگرهای قدیمی (مثلا موزیلا نسخه ۵) به آدرس خاصی در سایت ما (در کد بالا old-browser/) منتقل شود. مثال استفاده دیگری redirect کردن کاربران بر اساس منطقه جغرافیایی آن ها است:

module.exports = {

  async redirects() {

    return [

      {

        source: '/:path((?!uk/).*)',

        has: [

          {

            type: 'header',

            key: 'x-vercel-ip-country',

            value: 'GB'

          }

        ],

        destination: '/uk/:path*',

        permanent: true

      }

    ]

  }

}

و در نهایت redirect کردن کاربران بر اساس login بودن یا نبودن آن ها در حساب کاربری خودشان:

module.exports = {

  async redirects() {

    return [

      {

        source: '/',

        has: [

          {

            type: 'header',

            key: 'x-authorized',

            value: '(?<authorized>yes|true)'

          }

        ],

        destination: '/dashboard?authorized=:authorized',

        permanent: false

      }

    ]

  }

}

این قابلیت از کاربردی ترین تغییرات next است.

بهینه سازی خودکار Webfont

بر اساس گزارشات منتشر شده در سال قبل (۲۰۲۰) حدود ۸۲ درصد سایت ها از web font ها استفاده می کنند. web font به فونت های دلخواهی گفته می شود که به صورت پیش فرض در تمام سیستم ها وجود ندارد. آمار ۸۲ درصدی که به شما ارائه دادم آمار وب سایت های انگلیسی بود بنابراین این مقدار در وب سایت های فارسی حدود صد در صد است. چرا؟ به دلیل اینکه فونت های پیش فرضی در سیستم عامل ها برای فونت فارسی وجود ندارد و متون فارسی به شکل پیش فرض بسیار زشت و ناخوانا نمایش داده می شوند بنابراین تقریبا تمام سایت های ایرانی از یک فونت مانند ایران سنس یا نازنین یا ... استفاده می کنند.

next.js به صورت خودکار کد های CSS مربوط به web font شما را به شکل inline در می آورد تا نیازی به دور زدن مرورگر برای دریافت فونت و سپس دریافت استایل هایش نباشد. این مسئله باعث افزایش سرعت اعمال فونت و ارتقاء معیار های First Contentful Paint و Largest Contentful Paint می شود. به کد زیر توجه کنید:

// روش قدیم

<link

  href="https://fonts.googleapis.com/css2?family=Inter"

  rel="stylesheet"

/>




// روش جدید

<style data-href="https://fonts.googleapis.com/css2?family=Inter">

  @font-face{font-family:'Inter';font-style:normal.....

</style>

متاسفانه فعلا فقط از Google Fonts پشتیبانی می شود اما در آینده نزدیک پشتیبانی از ارائه دهندگان دیگر نیز انجام خواهد شد.

صفحات خطای 500 شخصی

همانطور که می دانید خطای ۵۰۰ در تعاملات HTTP به معنی بروز خطا در سمت سرور است. شما از این به بعد می توانید در پوشه pages یک فایل به نام 500.js ایجاد کنید و سپس کد های دلخواهتان را در آن بنویسید تا در هنگام بروز خطای ۵۰۰ این صفحه به کاربران نمایش داده شود. مثالی ساده:

// pages/500.js آدرس

export default function Custom500() {

    return <h1>500 - Server-side error occurred reload page</h1>

}

ارتقاء documentation

در نسخه های جدید next.js صفحات documentation پیشرفت زیادی داشته اند و نسبت به قبل جزئیات زیادی را اضافه کرده اند. حالا افراد تازه کار نیز می توانند به راحتی این صفحات را مطالعه کرده و کار با next.js را یاد بگیرند. به طور مثال در این صفحات انتقال پروژه از gatsby و انتقال پروژه از CRA (برنامه create-react-app) و انتقال پروژه از React Router و غیره نیز اضافه شده است تا حتی به صورت خاص با پروژه شما سازگاری داشته باشد.

بهینه سازی تصاویر

یکی از عملیات های سنگین در برنامه های وب، بهینه سازی تصاویر و ویدیو ها است. تصاویر تقریبا نیمی از محتوای کل اینترنت را تشکیل می دهند بنابراین بهینه سازی آن ها امری ضروری است اما بهینه سازی آن ها همیشه دردسر های خودش را دارد. مثلا نیاز به پکیج های خارجی داریم یا باید با مفاهیم تخصصی گرافیک آشنا باشیم تا بتوانیم تصاویر را فشرده کنیم و دستورات لازم برای بهینه سازی را بنویسیم. خوشبختانه از این به بعد next.js کامپوننت خاصی به نام Image را معرفی کرده است که به صورت خودکار تصاویر را بهینه سازی می کند. next.js برای افزایش سرعت از زبان WebAssembly استفاده می کند که علاوه بر کاهش حجم و افزایش سرعت از تراشه های جدید M1 ساخت شرکت اپل نیز پشتیبانی می کند.

ما قبلا برای نمایش تصاویر بدین شکل عمل می کردیم:

<img src="/logo.png" width="5" height="8" alt="Project Logo">

اما از این به بعد از کامپوننت خاص Image استفاده می کنیم:

import Image from 'next/image';




<Image src="/logo.png" width="5" height="8" alt="Project Logo">

باید بدانید که تیم Google Chrome برای ساخت این کامپوننت با تیم next همکاری کرده اند و حاصل تلاششان چیزی است که امروز مشاهده می کنید. با استفاده از این کامپوننت خاص تصاویر شما به صورت پیش فرض در قالب WebP نمایش داده می شوند که حجم کمتر و کیفیت بهتری نسبت به تصاویر JPEG دارد. نکته جالب اینجاست که فرآیند بهینه سازی در هنگام درخواست کاربران انجام می شود نه در زمان ساخت HTML! بنابراین سرعت build افزایش پیدا می کند.

همچنین ۵ ساختار یا layout جدید نیز به کامپوننت Image اضافه شده است:

  • layout=fill: دیگر نیازی به مشخص کردن width و height تصاویر ندارید بلکه تصاویر خودشان نگهدارنده خود را پُر می کنند.
  • layout=fixed: رفتار عادی و پیش فرض تصاویر.
  • layout=responsive: طول و عرض تصاویر منعطف و قابل تغییر است تا در طراحی های واکنش گرا مشکل ساز نباشند.
  • layout=intrinsic: تصاویر نمی توانند بزرگ شوند اما می توانند در صفحات کوچک، کوچک تر شوند.
  • objectFit=cover: تعیین تصویر به عنوان تصویر پس زمینه

البته در نسخه ۱۱ به بعد از next.js می توانید با اضافه کردن کلیدواژه import و بارگذاری تصویر با آن به next بگویید که خودش طول و عرض تصاویر را تشخیص دهد:

import Image from 'next/image'

import author from '../public/me.png'




export default function Home() {

  return (

    // بارگذاری شده است import تصویر با استفاده از

    // بنابراین نیازی به تعریف طول و عرض برای تصویر نیست.

    <Image src={author} alt="Picture of the author" />

  )

}

همچنین next از این به بعد می تواند placeholder های تصاویر را تار کند تا بارگذاری تصویر ظاهر زیباتری بگیرد:

<Image src={author} alt="Picture of the author" placeholder="blur" />

نتیجه به شکل زیر خواهد بود:

البته شما می توانید با خصوصیت blurDataURL و استفاده از سرویس هایی مانند blurha.sh سیستم تار کردن خودتان را پیاده سازی کنید:

<Image

  src="https://nextjs.org/static/images/learn.png"

  blurDataURL="data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAIAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAb/xAAhEAACAQMDBQAAAAAAAAAAAAABAgMABAUGIWEREiMxUf/EABUBAQEAAAAAAAAAAAAAAAAAAAMF/8QAGhEAAgIDAAAAAAAAAAAAAAAAAAECEgMRkf/aAAwDAQACEQMRAD8AltJagyeH0AthI5xdrLcNM91BF5pX2HaH9bcfaSXWGaRmknyJckliyjqTzSlT54b6bk+h0R//2Q=="

  alt="Picture of the author"

  placeholder="blur"

/>

قابلیت دیگری که در زمینه تصاویر انجام شده است، تعریف loader های شخصی است. این loader ها توابعی هستند که نحوه حل شدن یک URL به یک تصویر را مشخص می کنند تا شما بتوانید بهینه سازی تصاویر یا بارگذاری آن ها را از سرویس های خارجی مانند CDN ها نیز انجام بدهید.

شما می توانید یک مثال استفاده از loader ها را در کد زیر مشاهده کنید:

import Image from 'next/image'




const myLoader = ({ src, width, quality }) => {

  return `https://example.com/${src}?w=${width}&q=${quality || 75}`

}




const MyImage = (props) => {

  return (

    <Image

      loader={myLoader}

      src="me.png"

      alt="Picture of the author"

      width={500}

      height={500}

    />

  )

}

extend کردن فایل پیکربندی tsconfig.json

فرض کنید یک فایل tsconfig.json را دارید که تنظیمات پایه را برای تمام پروژه های شما دارد و حالا می خواهید برای هر پروژه تنظیمات خاصی را به آن اضافه کنید. از این به بعد می توانید این کار را با کلیدواژه extend انجام بدهید:

{

  "extends": "./tsconfig.base.json"

}

با انجام این کار تنظیمات پایه پروژه از فایلی به نام tsconfig.base.json بارگذاری می شوند اما می توانید خودتان تنظیمات ریزتر را مشخص کنید.

تشخیص فعال بودن Preview Mode

از این به بعد می توانید فعال بودن Preview Mode را تشخیص بدهید تا نمایش برخی از کامپوننت ها را فقط برای ادیتور هایتان مجاز کنید:

port { useRouter } from 'next/router'




function MyComponent() {

  const { isPreview } = useRouter()

  return <>{isPreview ? <h1>Preview Mode Enabled</h1> : null}</>

}

همکاری با گوگل در Conformance

پروژه Conformance سیستمی است که توسط گوگل ابداع شده است و در اصل مجموعه ای از قوانین و راه حل های مختلف است که روی بارگذاری بهینه و Core Web Vitals تمرکز می کند اما نگاهی به مباحث امنیت و دسترسی پذیری (accessibility) نیز دارد.

زمانی که شما یک پروژه را شروع می کنید می دانید که در آینده بزرگ تر خواهد شد بنابراین مدیریت آن مشکل تر خواهد شد و اغلب باید با مباحثی مانند UX (تجربه کاربری) نیز آشنا باشید تا بتوانید یک وب سایت ایده آل را تحویل بدهید. هدف پروژه Conformance تولید ابزار هایی است که به صورت جداگانه و اختصاصی برای هر فریم ورک تولید شده اند. از این به بعد next.js (نسخه ۱۱ به بعد) به صورت پیش فرض از ESLint استفاده می کند اما خودش قوانینی را برایتان آماده کرده است که در هنگام توسعه به شما گوشزد شود. استفاده از ESLint به صورت عمومی تاثیر مثبتی در توسعه برنامه های خوب دارد اما تیم Next.js قوانین خاصی را برای ESLint تعریف کرده است تا دقیقا مناسب پروژه های next.js باشند بنابراین اگر جایی در برنامه کد اشتباه یا نامناسبی را بنویسید حتما به شما گوشزد خواهد شد.

برای استفاده از این قابلیت، پس از به روز رسانی پروژه به نسخه ۱۱ از next.js دستور npx next lint را اجرا نمایید. زمانی که این دستور را اجرا کنید چنین نتیجه ای می گیرید:

We created the .eslintrc file for you and included the base Next.js ESLint configuration.




./pages/about.js

7:9  Warning: Do not include stylesheets manually. See: https://nextjs.org/docs/messages/no-css-tags.  @next/next/no-css-tags

10:7  Warning: External synchronous scripts are forbidden. See: https://nextjs.org/docs/messages/no-sync-scripts.  @next/next/no-sync-scripts




./pages/index.js

4:10  Warning: Do not use the HTML <a> tag to navigate to /about/. Use Link from 'next/link' instead. See: https://nextjs.org/docs/messages/no-html-link-for-pages.  @next/next/no-html-link-for-pages




Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/basic-features/eslint#disabling-rules




✨  Done in 1.94s.

همانطور که می بینید توضیحات جالبی در این باره به شما داده می شود و اگر جایی کد هایتان را بهینه ننوشته باشید به شما ذکر داده می شود.

کامپوننت Script

در نسخه ۱۱ از next.js کامپوننت جدیدی به نام Script اضافه شده است که به شما اجازه می دهد بارگذاری اسکریپت های خارجی را کنترل کنید تا سرعت بارگذاری سایتتان ضربه نخورد. منظورم از اسکریپت های خارجی اسکریپت هایی است که از سرور های دیگری می آیند و مواردی مانند نمایش تبلیغات یا analytics (آمار بازدید) یا ویجت های پشتیبانی و تماس با مشتری را پیاده سازی می کنند. این کامپوننت سه حالت را دریافت می کند:

  • beforeInteractive: این حالت برای اسکریپت هایی است که برای نمایش صفحه حیاتی هستند بنابراین باید قبل از نمایش و تعامل پذیر بودن صفحه بارگذاری شوند. مثلا اسکریپت های تشخیص ربات یا دریافت اجازه از کاربر برای ذخیره کوکی از این دسته اسکریپت ها هستند. این اسکریپت ها قبل از باندل جاوا اسکریپتی اجرا می شوند.
  • afterInteractive: این حالت پیش فرض است. این حالت برای اسکریپت هایی است که می توانند پس از نمایش و تعامل پذیر شدن صفحه بارگذاری و اجرا شوند. اسکریپت های مربوط به analytics (تحلیل آمار بازدید و غیره) از این دسته از اسکریپت ها هستند.
  • lazyOnload: این حالت برای اسکریپت هایی است که وجود آن ها در بارگذاری اولیه صفحه اصلا اهمیتی ندارد و می توانند در زمان بیکار بودن مرورگر کاربر بارگذاری شوند. دکمه های اشتراک گذاری در صفحات اجتماعی از این دسته اسکریپت ها هستند.

از این به بعد برای بارگذاری اسکریپت هایتان باید از این کامپوننت استفاده نمایید:

<Script

  src="https://polyfill.io/v3/polyfill.min.js?features=Array.prototype.map"

  strategy="beforeInteractive" // lazyOnload, afterInteractive

/>

یا مثلا منتظر پاسخ کاربر درباره یک سوال می مانیم و پس از تایید او اسکریپت را بارگذاری می کنیم:

<Script

  src={url} // دریافت اجازه از کاربر

  strategy="beforeInteractive"

  onLoad={() => {

    // بارگذاری اسکریپت ها

  }}

/>

امیدوارم این تغییرات به درک شما از قابلیت های جدید next.js کمک کرده باشد.


منبع: وب سایت nextjs

نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.