跳至內容
返回部落格

2020 年 10 月 27 日,星期二

Next.js 10

發佈者

我們很高興推出 Next.js 10,其中包含

內建圖片元件與自動圖片優化

Next.js 的目標是改善兩個方面:開發者體驗和使用者體驗。

今年,我們已投入大量資源改善所有 Next.js 應用程式的開發者體驗和效能。我們專注於減少瀏覽器必須載入的 JavaScript 數量。

我們推出了超過 20 項新功能,以提升效能和開發者體驗。同時,Next.js 核心的 JavaScript 大小已 **減少了 16%**。

一月份,我們與 Google Chrome 團隊合作,推出了一種全新的最佳 JavaScript 程式碼分割策略。

例如,Barnebys 的 **應用程式大小減少了 23%**,而 Sumup 的 **最大 JavaScript 捆綁包大小減少了 70%**。這些改進成果 **無需修改**其 Next.js 應用程式中的 **任何程式碼** 即可達成。

公司只需將 Next.js 升級到最新版本即可自動採用此新策略。

網頁上的圖片

雖然我們致力於減少瀏覽器必須載入的 JavaScript 數量已獲得成效,但網路不僅僅是 JavaScript:它還包含標記和圖片。

圖片佔網頁總位元組數的 50%。

圖片對最大內容繪製 (LCP) 有很大的影響,因為它們通常是頁面載入時最大的可見元素。最大內容繪製是 Google 將**很快**用於其搜尋排名的核心網頁指標 即將

所有圖片中有一半的大小超過 1MB,這表示它們未針對網頁顯示進行優化。

如今,使用者使用手機、平板電腦和筆記型電腦瀏覽網頁,但圖片仍然是一刀切的。例如:網站載入 2000 x 2000 像素的圖片,但手機僅將其顯示為 100 x 100 像素。

此外,網頁上 30% 的圖片位於初始視埠之外,這表示瀏覽器載入的圖片是使用者向下捲動頁面後才會看到的。

圖片通常沒有 widthheight 屬性,導致它們在頁面載入時跳來跳去。這會損害累積版面配置偏移 (CLS) 核心網頁指標。

網站上 99.7% 的圖片未使用 WebP 等現代圖片格式。

為了以高效能的方式在網頁上使用圖片,必須考慮許多方面:大小、重量、延遲載入和現代圖片格式。

開發者必須設定複雜的建置工具來優化圖片,然而這些工具通常無法處理來自外部資料來源的使用者提交圖片,導致無法優化所有圖片。

這個不可能的開發任務無可避免地導致令人沮喪的終端使用者體驗。

Next.js 圖片元件

我們很高興宣布我們針對網頁高效能圖片的解決方案:Next.js 圖片元件和自動圖片優化。

Next.js 圖片元件最基本的功能就是可以直接取代 HTML 的 <img> 元素,是為了現代網路而演進的版本。

<img
  src="/profile-picture.jpg"
  width="400"
  height="400"
  alt="Profile Picture"
/>
import Image from 'next/image';
<Image
  src="/profile-picture.jpg"
  width="400"
  height="400"
  alt="Profile Picture"
/>;

Google Chrome 團隊協助建立了這個 React 元件,藉由將最佳實務設為預設值來提升網頁效能。

使用 next/image 元件時,圖片會自動延遲載入,這表示它們只會在使用者快要看到圖片時才進行渲染。這可以避免載入初始視埠外 30% 的圖片。

圖片尺寸會被強制執行,讓瀏覽器可以立即渲染圖片所需的空間,而不是在載入時才跳出來,避免版面偏移。

雖然 HTML <img> 元素上的 widthheight 屬性可能會造成響應式版面的問題,但**使用 next/image 時則不會發生這種情況**。使用 next/image 時,圖片會根據提供的 widthheight 的長寬比自動調整為響應式。

開發者可以標記初始視埠中的圖片,讓 Next.js 自動預先載入這些圖片。預先載入初始視埠中的圖片已被證明可以將最大內容繪製 (LCP) 提升高達 50%。

自動圖片優化

即使與 HTML <img> 元素相比有這些改進,仍然存在一個主要問題。2000 x 2000 像素的圖片會被傳送到渲染較小圖片的手機上。

Next.js 10 也解決了這個問題。next/image 元件會透過內建的圖片優化功能自動產生較小的尺寸。

內建的圖片優化功能會自動以現代圖片格式(例如 WebP,比 JPEG 小約 30%)提供圖片,如果瀏覽器支援的話。它也允許 Next.js 自動採用**未來**的圖片格式,並將其提供給支援這些格式的瀏覽器。

圖片優化功能適用於任何圖片來源。即使圖片來自外部資料來源,例如 CMS,它們也會被優化。

Next.js 10 不是在建置時優化圖片,而是在使用者請求時按需優化圖片。與靜態網站產生器和僅靜態的解決方案不同,您的建置時間不會增加,無論是提供 10 張圖片還是 1000 萬張圖片。

結論

新的 next/image 元件和自動圖片優化功能是強大的新基元,將大幅提升使用者體驗。

next/image 元件會自動處理延遲載入、預先載入關鍵圖片、跨裝置的正確大小調整,並自動支援現代格式。這些功能適用於任何來源的圖片。

我們很期待看到這些新的基元能讓您的使用者體驗提升多少速度。

更多詳細資訊,請參閱Next.js 圖片元件和自動圖片優化文件

國際化路由

今年,一些企業和社群成員協助我們的團隊了解國際化的重要性。

例如,我們了解到 72% 的消費者更有可能留在已翻譯的網站上,而 55% 的消費者表示他們只會從使用其母語的電子商務網站購買。

如果您計劃在不同的國家/地區上市,將您的專案國際化對於成功至關重要。

專案國際化有兩個主要支柱:翻譯和路由。

許多 React 函式庫會準備好應用程式進行翻譯,但大多數函式庫都希望您手動處理路由,而且通常只適用於一種渲染策略。

因此,作為 Next.js 10 的一部分,我們發布了內建的國際化路由和語言偵測支援。

這個內建的國際化路由支援 Next.js 的混合策略,因此您可以根據每個頁面選擇靜態產生或伺服器端渲染。

Next.js 10 支援兩種最常見的路由策略:子路徑路由和網域路由。

對於這兩種策略,您首先都要在 Next.js 設定中設定語系。

next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'nl'],
    defaultLocale: 'en',
  },
};

語系是UTS 語系識別碼,一種用於定義語系的標準化格式。

通常,語系識別碼由語言、地區和腳本組成,以破折號分隔:language-region-script。地區和腳本是選用的。例如:

  • en-US - 美國使用的英語
  • nl-NL - 荷蘭使用的荷蘭語
  • nl - 荷蘭語,無特定地區

設定好語系後,您可以選擇子路徑或網域路由。

子路徑路由

子路徑路由會將語系放在網址中。這允許所有語言都存在於單一網域上。

例如,您可以在網址中插入語系,例如 /nl-nl/blog/en/blog

網域路由

網域路由讓您可以將地區設定映射到頂級網域。例如,example.nl 可以映射到 nl 地區設定,而 example.com 可以映射到 en 地區設定。

網域路由需要一些額外的設定才能知道如何路由網域。

next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'nl'],
    domains: [
      {
        domain: 'example.com',
        defaultLocale: 'en',
      },
      {
        domain: 'example.nl',
        defaultLocale: 'nl',
      },
    ],
  },
};

語言偵測

Next.js 10 在 / 路由上內建了基於 Accept-Language 標頭的語言偵測功能,所有現代瀏覽器都支援此標頭。設定的地區設定將會與 Accept-Language 標頭進行比對,然後根據設定的策略進行重新導向。

搜尋引擎最佳化(SEO)

由於 Next.js 知道使用者所瀏覽頁面的語言,它會自動將 lang 屬性新增到 <html> 標籤。

Next.js 無法辨識頁面的不同語言版本,因此您需要使用 next/head 自行新增 hreflang 中繼標籤。您可以在 Google Search Console 說明文件中深入瞭解 hreflang

Next.js 中國際化的未來發展

國際化路由(Internationalized Routing)是一系列旨在簡化專案國際化和在地化功能中的第一個。國際化路由允許與大多數 React 國際化函式庫整合。

若要深入瞭解國際化路由,請參閱國際化路由說明文件

Next.js 速度洞察

在 Vercel,我們知道您無法修復您無法測量的問題。

您的訪客對網站效能越來越敏感。超過 50% 的訪客會如果網站載入時間超過 3 秒就放棄瀏覽。如果您從事電子商務,許多人發現將載入時間縮短 1/10 秒會使轉換率提高 1%

由於效能對您的成功至關重要,我們很榮幸地推出 Next.js 速度洞察。此解決方案可追蹤實際效能指標,並將這些洞察反饋到您的開發流程中。

藉由 Next.js 速度洞察

您現在將可以持續測量,而不是只測量一次。

測量結果將來自訪客實際使用的裝置,而不是您的開發裝置。

Next.js 速度洞察的重點在於關注整體情況,深入瞭解您的受眾,以及您的應用程式如何為使用者執行。

我們堅持收集真實數據,因為效能不佳的原因並不總是那麼明顯。效能下降可能來自各種地方,例如第三方指令碼和樣式表,或是過大或載入緩慢的第一方字型、圖片和影片。

核心網頁指標

Google 與網頁效能工作小組共同建立了一套指標,用於準確衡量使用者體驗網站效能的方式:恰如其分地命名為「核心網頁指標」。核心網頁指標會追蹤網站的感知載入速度、回應速度和視覺穩定性,這三者都是網站整體健康狀況的關鍵!

感知載入速度可以透過「最大內容繪製」(LCP) 來衡量,也就是所有頁面內容都已顯示的時間點。例如,當我開啟一個連結購買一雙運動鞋時,從我開啟連結到看到運動鞋、價格和「加入購物車」按鈕之間的時間就是 LCP。

頁面回應速度可以透過「首次輸入延遲 (FID)」來衡量,FID 測量的是使用者第一次與頁面互動後,必須等待多久才能看到反應。例如,從我點擊「加入購物車」到購物車中的商品數量增加之間的時間,就是 FID。

最後,視覺穩定性可以透過「累積版面配置偏移 (CLS)」來衡量,CLS 指的是元素顯示給使用者後移動的程度。例如,我們都經歷過想要點選一個按鈕,卻因為圖片延遲載入而導致按鈕移動的 frustrating 經驗,這就是版面配置偏移。

持續針對實際使用者的這些「網頁核心指標」進行測量並確保符合標準至關重要。這是唯一真正了解您的網站對使用者效能表現的方法。您的網站效能可能會因使用者的裝置、網路狀況或與頁面互動的方式而有顯著差異。載入個人化內容或廣告的網站,使用者之間的效能體驗也可能大相徑庭。

模擬測試無法捕捉到這些重要的訊號。

Next.js Speed Insights 可讓您捕捉真實世界的數據,而非僅仰賴人工基準測試。它可以實現連續的測量流程,而不是依賴偶爾的測試,確保其成為您開發流程的一部分。

Next.js Speed Insights 可讓您捕捉真實世界的數據,而非僅仰賴人工基準測試。它可以實現連續的測量流程,而不是依賴偶爾的測試,確保其成為您開發流程的一部分

立即造訪 nextjs.org/analytics 以了解如何在您的應用程式中啟用它。

Next.js Commerce

電子商務是網路上最重要的應用之一。Next.js 10 的新功能是強大的電子商務新工具。

因此,今天我們與 BigCommerce 合作發布了 Next.js Commerce,這是一款適用於電子商務網站的多合一 React 入門套件。Next.js 開發人員只需點擊幾下,即可複製、部署和完全自訂它。立即從 nextjs.org/commerce 開始。

React 17 支援

React 17 對 Next.js 沒有造成任何破壞性更新,然而仍需進行一些維護性變更,例如更新 peer dependencies。新的 JSX 轉換 在使用 React 17 時會自動啟用,無需變更任何設定。

您只需升級 Next.js 和 React 即可開始使用 React 17

終端機
npm install next@latest react@latest react-dom@latest

getStaticProps / getServerSideProps 快速重新整理

當您編輯 getStaticPropsgetServerSideProps 函式時,Next.js 現在會自動重新執行該函式並套用新的資料。這讓您可以更快地迭代,而無需重新整理頁面。

要深入了解 getStaticPropsgetServerSideProps,您可以閱讀資料提取文件

MDX 的快速重新整理

當您透過 @next/mdx 將 Next.js 與 MDX 搭配使用時,變更 MDX 內容現在會運用快速重新整理,確保瀏覽器無需在編輯時重新載入頁面。

@next/mdx 文件 會引導您如何在 Next.js 中設定 MDX。

從第三方 React 元件匯入 CSS

您現在可以在 React 元件內匯入第三方 CSS。這允許僅針對單個元件進行程式碼分割 CSS。例如,您現在可以使用 react-datepicker 函式庫,而無需在 _app.js 中匯入 CSS。

components/MyComponent.js
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
 
function MyComponent() {}

您可以參考內建 CSS 支援文件,以深入了解 Next.js 如何處理 CSS 匯入。

自動解析 href

如果您以前使用過動態路由,您可能遇到過必須同時提供 hrefas 屬性給 next/link 的情況。它看起來像這樣:

<Link href="/categories/[slug]" as="/categories/books" />

這允許 Next.js 為動態參數插入 href,然而,當開發人員忘記添加 as 或在 href 中添加 as 導致頁面轉換不使用客戶端路由時,就會造成摩擦。

幾個月前,我們著手解決開發人員的這個摩擦問題,主要目標是改善開發人員體驗和終端使用者體驗。我們逐步開發了一個允許自動解析 href 的解決方案。

我們很高興地宣布,作為 Next.js 10 的一部分,您不再需要在大部分使用案例中使用 as 屬性。這減少了開發人員的摩擦,並改善了終端使用者體驗。

此更改完全向後相容,如果您目前同時使用 hrefas,則會保留現有行為。

為了採用自動 href 解析,您只需將 next/link 的用法更改為僅使用 href,並將之前在 as 屬性中的值放入其中。

<Link href="/categories/books" />

要瞭解更多關於 next/link 和客戶端路由的資訊,您可以參考next/link 文件

@next/codemod CLI 此轉換是必要的,否則 React 快速重新整理不會將該函式檢測為有效的 React 元件。同樣,React hooks eslint 規則也不會將該函式識別為 React 元件。

在 Next.js 10 中,我們發佈了一個新的 Next.js 程式碼修改器 CLI 工具,允許您運行單個命令來更新您的應用程式:npx @next/codemod <transform> <path>

要瞭解更多關於程式碼修改器的資訊,您可以查看Next.js 程式碼修改器文件

getStaticPaths 的阻塞式後備方案

在 Next.js 9.3 中,我們推出了 getStaticPropsgetStaticPaths,並在 getStaticPaths 中加入了返回 fallback 屬性的功能。fallback 屬性允許在無需完整重建的情況下生成額外的靜態頁面,最初提供一個靜態 HTML 檔案,然後在後續請求中替換為完整渲染的內容。過去幾個月,我們收到許多來自企業的意見回饋,他們希望獲得類似但略有不同的行為:當使用者第一次請求頁面時進行阻塞式預渲染。在初始渲染之後,該頁面將會被重複用於後續請求。

Next.js 10 解決了這個問題。

我們很高興地宣布 getStaticPaths 的新模式 fallback: 'blocking',它啟用了阻塞式行為,不會將靜態後備方案發送到瀏覽器。相反,初始請求會等待預渲染完成。

pages/posts/[id].js
export function getStaticPaths() {
  return {
    // enables blocking mode for the fallback behavior
    fallback: 'blocking',
  };
}

要進一步了解用於增量生成額外靜態頁面的 fallback 行為,您可以參考fallback 文件

getStaticProps / getServerSideProps 的重新導向和 notFound 支援

自從推出 getStaticPropsgetServerSideProps 以來,我們注意到有些情況下使用者需要返回重新導向和 404 回應。為了簡化這些情況,我們現在允許從 getStaticPropsgetServerSideProps 返回兩個新的欄位:notFoundredirect

notFound 支援

當使用 true 返回 notFound 欄位時,將返回預設的 404 頁面,狀態碼為 404。這使您可以避免使用 SSG 生成額外的頁面,並且不必手動處理 404 頁面的渲染。

pages/posts/[id].js
export function getStaticProps() {
  return {
    // returns the default 404 page with a status code of 404
    notFound: true,
  };
}

redirect 支援
pages/posts/[id].js
export function getStaticProps() {
  return {
    // returns a redirect to an internal page `/another-page`
    redirect: {
      destination: '/another-page',
      permanent: false,
    },
  };
}

pages/posts/[id].js
export function getServerSideProps() {
  return {
    // returns a redirect to an external domain `example.com`
    redirect: {
      destination: 'https://example.com',
      permanent: false,
    },
  };
}

結論

我們很高興看到 Next.js 的採用率持續成長

  • 我們擁有超過 1,300 位獨立貢獻者,自 9.5 版以來新增了超過 120 位貢獻者
  • 在 GitHub 上,該專案已獲得超過 54,800 個星標。

加入 Next.js 社群,請前往 GitHub 討論區。討論區是一個社群空間,讓您可以與其他 Next.js 使用者聯繫,自由提問或分享您的作品。

致謝

我們感謝我們的社群,包括所有有助於塑造此版本發行的外部回饋和貢獻。

此版本由以下人士貢獻:@ijjk, @adebiyial, @elliottsj, @saintmalik, @HaNdTriX, @prateekbh, @amirsaeed671, @paambaati, @imagentleman, @gregrickaby, @Janpot, @atcastle, @Kirkhammetz, @remorses, @davidsonsns, @kmkzt, @slawekkolodziej, @Timer, @styfle, @timneutkens, @ykzts, @ashconnell, @orYoffe, @lfades, @justinwhall, @fbaiodias, @ludofischer, @felipeguilhermefs, @gr-qft, @TasukuUno, @YichiZ, @weichienhung, @seosmmbusiness, @HsuTing, @gsimone, @peduarte, @ztanner, @neighborhood999, @chibicode, @merceyz, @opudalo, @lunchboxav, @mohsen1, @akd-io, @justman00, @helloworld, @devknoll, @borekb, @ArthurMaverick, @sakito21, @TrySound, @omBratteng, @svenheden, @hallaji, @kettanaito, @vvo, @m-lautenbach, @jensmeindertsma, @Zeko369, @longlho, @stefanprobst, @laugharn, @sdornan, @daneroo, @mohd-akram, @austingmhuang, @sphilee, @devinekadeni, @Bacher, @nghiepit, @tomasdisk, @leader22, @paulogdm, @284km, @belgattitude, @geritol, @stigkj, @sampoder, @samrobbins85, @Pitasi, @digitalPlayer1125, @timfee, @plug-n-play, @philihp, @leerob, @dylanjha, @Kerumen, @rdimaio, @jorisw, @zerbinidamata, @jamesgeorge007, @Jashnm, 以及 @futantan!