2022 年前端大事記

大家好,我是 ConardLi

去年我總結了 2021 年 JavaScript 大事記 之後,最近好多小夥伴催更我的 2022 年總結,這就來了。

今年的總結不再侷限於 JavaScript 生態,其中也包括了 Web、網絡等前端需要關注的領域,所以我將其更名爲 《2022 年前端大事記》。

[1-11] Chrome 開始實施私有網絡控制策略

私有網絡請求指的是目標服務器的 IP 地址比請求發起者獲取的 IP 地址更私密的請求。例如,從公共網站 (https://www.douyin.com) 到內網網站 (http://argus.bytedance.net) 的請求,或從內網網站到 localhost 的請求。

Chrome 統計,有數十萬人遭受了針對私有網絡的攻擊,簡單說,就是你打開一個公共的網站,這個網站裏會去請求你內網裏的地址,然後竊取信息。基於此類問題,Chrome 提出了私有網絡控制策略,此策略會限制網站向私有網絡上的服務器發送請求的能力。

你必須要部署下面兩個 Header,否則所有私有網絡訪問都會失敗:

瞭解更多:

[1-21] Vue 3 成爲新的默認版本!

Vue 32022 年 2 月 7 日 成爲新的默認版本!

除了 Vue 核心庫以外,還幾乎改進了框架的每個方面。

瞭解更多:https://zhuanlan.zhihu.com/p/460055155

[1-22] document.domain 被禁用

Chrome 101 版本開始,document.domain 將變爲可讀屬性。

當兩個頁面的 document.domain 都設置爲二級域名的時候,瀏覽器就會將兩個來源視爲同源,利用這個方法我們可以繞過瀏覽器的同源策略。

也就是意味着上述這種跨域的方式被禁用了,後續可以替換爲 postMessage 的跨域方案。

瞭解更多:

[2-13] Node.js 支持 Fetch API

Fetch API 是當前最流行的跨平臺 HTTP Client API

在最新的 Node.js v17.5 版本中,增加了對 Fetch API 的支持,後續無需再借助 axios、needle、node-fetch、request 等第三方請求庫了!

這並不是簡單的支持了一個新的原生 HTTP 請求庫那麼簡單,這意味着很多之前在 Web 中用到 FetchNPM 包也可以在 Node.js 裏以同樣的方式工作了,這些包同樣可以實現跨平臺兼容了~

瞭解更多:

[2-27] User-Agent 攜帶信息即將進行刪減

爲了減輕 User-Agent 的身份標識作用, Chrome 正在逐步減少 User-Agent 中的信息。

以下幾部分信息都會逐步縮減:

瀏覽器會推薦大家使用新的 User-Agent Client,裏面只會包括下面幾部分信息:

例如,Chrome/99.0.2345.12 這樣的版本號將會被簡化爲 Chrome/99.0.0.0 ,這大大的減輕了 UA 對用戶的身份標識作用。

具體減少計劃:

Chrome 92:使用 navigator.userAgent 、navigator.appVersion 和 navigator.platform 會在控制檯打印警告。

Chrome 95:支持爲的網站註冊原始試用,開始對減少的 UA 字符串進行測試和反饋。

Chrome 101:User-Agent 將會減少 Chrome MINOR.BUILD.PATCH 版本信息。推薦遷移到新的 User-Agent Client。

Chrome 107:PC 端的 User-Agent 字符串和 JS API(navigator.userAgent 、navigator.appVersion 、navigator.platform)將會直接縮減。

Chrome 110:移動端的的 User-Agent 字符串和 JS API 將會縮減。

Chrome 113:全面縮減。

瞭解更多:

[3-07] JavaScript 將新增兩個原始數據類型

JavaScript 即將推出兩個新的數據類型:RecordTuple ,該提案目前已經到達  Stage: 2

RecordTuple 在用法上和對象、數據保持一致只不過他們是隻讀的:

// Record, 一個非常不可變的類對象結構
const myRecord = #{
 name: 'ConardLi',
 age: 23
}

myRecord.name = 'xxx'; // TypeError "Cannot assign to read only property 'name' of object '[object Object]'"

// Tuple, 一個非常不可變的類數組結構
const myTuple = #['1', '2', '3']

myTuple[0] = '4' // TypeError "Cannot assign to read only property '0' of object '[object Tuple]'"

另外還有一個很重要的點,當我們去比較 RecordTuple 的值時,只會對比它們的值,而不再對比引用。

console.log(#{ a: 1, b: 2 } === #{ b: 2, a: 1 });

// true

瞭解更多:https://github.com/tc39/proposal-record-tuple

[3-08] Chrome/Edge/Firefox/Safari 決定合力解決 Web 兼容性問題 !

瀏覽器製造商 Apple、Google、MicrosoftMozilla ,以及軟件公司 BocoupIgalia 正在合力制定一項名爲 Interop 2022Web 兼容性規範,以使 Web 技術和代碼在不同的設備和瀏覽器中有統一的渲染效果(利好前端開發)。

這是有史以來第一次,所有市場上主要的瀏覽器供應商和利益相關者齊心協力地解決瀏覽器兼容性問題。此前,互相爲競爭關係的瀏覽器廠商常常在 Web 技術的兼容性上出現分歧,尤其是 IE 還活着的時候,前端一個頁面三套代碼的情況十分常見。

想要跟進規範的整體進度,可以查看 Interop 2022 dashboard

瞭解更多:https://web.dev/interop-2022/

[3-09] TS 團隊提議爲 JS 增加類型註釋提案

在過去的 JavaScript 調查報告中,靜態類型一直是 JavaScript 開發者強烈要求的一個功能。

微軟 TypeScript 團隊提出了一項新的提案,在提案中希望可以爲 JavaScript 帶來可選的類型註釋語法。提案的目的是讓開發者能夠直接運行用 TypeScript、Flow 或其他靜態類型庫編寫的程序,而不需要再編譯一次。

如果提案能夠順利實施,將是 JavaScript 語法的一個重大變革,目前提案已經到達 Stage: 1 階段。

提案地址:https://github.com/tc39/proposal-type-annotations

[3-16] vue-cli 的依賴項被供應鏈投毒

vue-cli 的依賴項 node-ipc 包的作者 RIAEvangelist 是個反戰人士,他特意新建了一個 peacenotwar 倉庫來宣傳他的反戰理念。

更過分的是,作者不只添加了反戰標語,還在 node-ipc 10.1.1-10.1.2 版本中添加了惡意 JS 文件刪除俄羅斯和白俄羅斯用戶文件:

攻擊源碼在倉庫中仍可找到。源碼經過壓縮,簡單地將一些關鍵字符串進行了 base64 編碼。其行爲是利用第三方服務探測用戶 IP,針對俄羅斯和白俄羅斯 IP,會嘗試覆蓋當前目錄、父目錄和根目錄的所有文件,把所有內容替換成 ❤。

node-ipcnpm 上具有周百萬次的下載量,這是又一次對脆弱的 npm 生態進行的一次沉痛打擊。

瞭解更多:百萬周下載量的 npm 包以反戰爲名進行供應鏈投毒!

Chrome 將在 100 到 103 版本啓動 Cookie CHIPS 試用版本!

CHIPS 指的是具有獨立分區狀態的 Cookie,它允許開發者將 Cookie 選擇到 “分區” 存儲中,每個頂級站點都有單獨的 Cookie jar``。CHIPS 引入了一個新的 Cookie 屬性:Partitioned ,它可以讓頂級上下文(頂級站點或第 First-Party Sets)決定哪些 Cookie 進行分區。

例如:在站點 A 中通過 iframe 嵌入了一個站點 C,正常情況下如果三方 Cookie 被禁用後,C 是無法在 A 站點訪問到它的 Cookie 的。如果 C 在它的 Cookie 上指定了 Partitioned 屬性,這個 Cookie 將保存在一個特殊的分區 jar 中。它只會在站點 A 中通過 iframe 嵌入站點 C 時纔會生效,瀏覽器會判定只會在頂級站點爲 A 時才發送該 Cookie。當用戶訪問一個新站點時,例如站點 B,如果也它通過 iframe 嵌入了站點 C,這時在站點 B 下的站點 C 是無法訪問到之前在 A 下面設置的那個 Cookie 的。

瞭解更多:誰能幫我們順利過渡到沒有三方 Cookie 的未來?

[3-29]  React 18 正式版發佈

2022 年 3 月 29 號,React18 正式版發佈。

瞭解更多:https://reactjs.org/blog/2022/03/29/react-v18.html

[4-06] Chrome 100 發佈

版本號分析可能出現的問題:Chrome 版本即將突破 100 ?這個問題不容忽視!

Google 發佈了 Web 100 個令人激動的瞬間 (https://developer.chrome.com/100/),同時也在推特上發起了 #100CoolWebMoments 活動。

Chrome 100 將是最後一個默認支持未刪減的 User-Agent 字符串的版本。Chrome 推薦大家用新的 User-Agent Client Hints API 替換 User-Agent 字符串。

瞭解更多:Chrome 100:有風險也有機遇!

[4-10] ShadowRealm API 進入 statge3 階段

ShadowRealm API 是一個新的 JavaScript 提案,目前已進入 statge3

它允許一個 JS 運行時創建多個高度隔離的 JS 運行環境(realm),每個 realm 具有獨立的全局對象和內建對象。

每個 ShadowRealm 實例都有自己獨立的運行環境,它提供了兩種方法讓我們來執行運行環境中的代碼:

const sr = new ShadowRealm();
console.assert(
  sr.evaluate(`'ab' + 'cd'`) === 'abcd'
);

瞭解更多:

[4-17] Change Array by copy 提案進入 stage3

Change Array by copy 提案,目前已經處於 stage3 階段。

該提案爲數組新增了四個非破壞性(不改變原數組)方法:

瞭解更多:

[4-19] HTML 新增比 iframe 更安全的 fencedframe 標籤

Fenced frames 是一項 隱私沙盒 提案,它建議頂級站點應該對數據進行分區。

Chrome97 版本開始對 Fenced frames 提供支持。

它是一個新的 HTML 標籤,使用方式和 iframe 類似:

<fencedframe src="conardli.html"></fencedframe>

從對比上來看,iframe 還是要更靈活的,Fenced frames 是無法取代 iframe 的,但是當我們需要在同一頁面上顯示來自不同頂級分區的數據時,建議使用 Fenced frames 作爲更私有的嵌入框架。

如果嵌入的網頁是受信任的,還是用 iframe 即可。

瞭解更多:

[4-25] Chrome 支持 Priority Hints,可控制網頁資源加載優先級

Chrome 101 正式發佈了 Priority Hints,用於指定頁面資源的加載優先級,即 fetchpriority 屬性,幫助瀏覽器根據優先級優化加載順序,從而優化頁面加載體驗。

當瀏覽器開始解析網頁,並開始下載圖片、Script 以及 CSS 等資源的時候,瀏覽器會爲每個資源分配一個代表資源下載優先級的 fetch priority 標誌,而默認的資源下載順序就取決於這個優先級標誌。

另外瀏覽器還給我們提供了一些諸如 async、defer、preload 等主動干預資源下載優先級的能力,但是有些場景還是滿足不了:比如網頁首屏有多張輪播圖,我們只希望提高第一張圖片下載的優先級;CSS、Font 資源默認有相同的優先級,但是並不是所有 CSSFont 資源都是一樣重要的。

這個時候, Priority Hints 就派上用場了。

瞭解更多:如何控制 Web 資源加載的優先級?

[5-04] React 計劃支持 useEvent Hook(隨後夭折)

React 的核心開發者 DanReact 增加了一項新的提案 useEvent

目的是爲了解決下面這個場景:

function Chat() {
  const [text, setText] = useState('');

  // 🟡 每次 text 變化都會產生新的函數引用
  const onClick = useCallback(() ={
    sendMessage(text);
  }[text]);

  return <SendButton onClick={onClick} />;
}

當我們使用 useCallback 包裹事件處理函數時,每次狀態發生變化,都會產生一個新的引用。

function Chat() {
  const [text, setText] = useState('');

  // ✅ 永遠是同一個函數引用
  const onClick = useEvent(() ={
    sendMessage(text);
  });

  return <SendButton onClick={onClick} />;
}

使用 useEvent 包裹事件處理函數,可以讓我們每次都能獲取到最新的狀態,而且狀態變更後不會產生新的函數引用。

提案地址:https://github.com/reactjs/rfcs/blob/useevent/text/0000-useevent.md

當然,這個提案最終還是在 9 月份夭折了,因爲它最大的問題是它相當於引入了一個新的概念,會增加 Hooks 的使用理解成本,你可能會從要不要使用 useCallback 的選擇中增加一個要不要使用 useEvent ...

所以 React 團隊計劃發佈一個不同的、範圍更小的 RFC 來取代這個 RFC。

[5-16] 瀏覽器最新私有預取代理方案,LCP 提升 30%!

爲了實現更安全隱私的數據預取,Google 提出了一種新的數據預取方案:Private prefetch proxy(私有預取代理),Google Search 已經實施了這項方案,導航的 LCP 預計有 20%-30% 的提升!

此方案具有較好的安全性,可防止代理抓包、防止用戶識別,並且可以更好的和瀏覽器緩存進行結合。

瞭解更多:Google 最新的性能優化方案,LCP 提升 30%!

[5-25] HTML 新增 inert 屬性

Safari 15.5、Chrome 102、Firefox Nightly 目前均對 HTML inert 屬性提供了支持。

<div inert>
  <label for="button2">codemmhy</label>
  <button id="button2">I am inert</button>
</div>

inert 是一個全局的 HTML 屬性,它可以告訴瀏覽器忽略元素的用戶輸入事件,包括焦點事件和來自輔助技術的其他事件。主要是下面兩種用例:

inert 主要是爲了提升網頁的可訪問性,比如對於視力障礙的人,他不是依靠視覺來感知網頁內容,而是藉助了一些其他的輔助技術,再之前就有可能會和我們隱藏掉的內容進行一些意外的交互。

inert 可以讓我們能夠從選項卡順序和可訪問性樹中直接刪除元素,這就會避免上面的問題!

瞭解更多:

[6-05] 瀏覽器支持直接運行 Python 代碼

PyCon US 2022 的主題演講中,AnacondaCEO Peter Wang 公佈了一個相當令人興奮的項目 — PyScript

PyScript 是一個 JavaScript 框架,可以爲開發者提供了在標準 HTML 中嵌入編寫 Python 代碼的能力、使用 Python 調用 JavaScript 函數庫,以及創建 Python Web 應用。

這意味着後續我們可以在瀏覽器直接運行 Python 代碼。

瞭解更多:https://pyscript.net/

[6-06] HTTP/3 標準化爲 RFC 9114

IETF QUICHTTP 工作組成員 Robin Mark 在推特上宣佈,歷時 5 年,HTTP/3 終於被標準化爲 RFC 9114,這是 HTTP 超文本傳輸協議的第三個主要版本。

HTTP/3 採用了谷歌多年探索的基於 UDPQUIC 協議,原名叫 HTTP-over-QUIC,在 2018 年被 IETF 批准更名爲 HTTP/3。目前,Chrome、Firefox 等主流瀏覽器均表示支持 HTTP/3

IETF 標準地址:https://www.rfc-editor.org/rfc/rfc9114.html

[6-13] WWDC 2022:WebKit 發佈多項新能力

在本屆蘋果全球開發者大會(WWDC 2022) 中,蘋果宣佈了 Safari 16 beta 版本的發行, WebKit 帶來了諸多新的 Web 能力,包括:

瞭解更多:WWDC 2022:哪些是前端開發者要關注的信息?

[6-15] IE 正式宣佈退役!

27 歲的微軟 IE 瀏覽器宣告退役。6 月 15 日晚,微軟 Edge 瀏覽器在官網宣佈,微軟正式結束對網頁瀏覽軟件 “Internet Explorer(IE)” 的支持,IE 瀏覽器正式退役了。發佈於 1995 年夏天的 IE ,最終在 2022 年的夏天,結束了它的旅程。

瞭解更多:微軟官方聲明

[6-17] Chrome 正式支持 File Handling API、Navigation API

Chrome 102 版本正式支持了 File Handling APINavigation API

File Handling API 可以讓已安裝的 PWA 向操作系統註冊文件處理程序。註冊後,用戶就可以單擊文件然後使用已安裝的 PWA 打開它了。這非常適合與文件交互的 PWA 程序,例如圖像編輯器、IDE、文本編輯器等。

想要讓你的 PWA 支持文件處理功能,你需要更新一下 web app manifest,添加一個 file_handlers 數組,其中包含有關你的 PWA 可以處理的文件類型的詳細信息。你需要指定要打開的 URL、MIME 類型、文件類型的圖標和啓動類型。啓動類型定義是否應在單個客戶端或多個客戶端中打開多個文件。

"file_handlers"[
  {
    "action""/open-csv",
    "accept"{"text/csv"[".csv"]},
    "icons"[
      {
        "src""csv-icon.png",
        "sizes""256x256",
        "type""image/png"
      }
    ],
    "launch_type""single-client"
  }
]

然後,想要在 PWA 啓動時訪問這些文件,你需要爲 launchQueue 對象指定一個使用者。啓動被排隊,直到它們被消費者處理。

// Access from Window.launchQueue.
launchQueue.setConsumer((launchParams) ={
  if (!launchParams.files.length) {
    // Nothing to do when the queue is empty.
    return;
  }
  for (const fileHandle of launchParams.files) {
    // Handle the file.
    openFile(fileHandle);
  }
});

在很多 Web 開發的場景下,我們需要在沒有網頁中的導航的情況下去更新頁面的 URL,特別是在 SPA 應用裏面,我們在切換了導航之後,不希望刷新網頁,只更新頁面中的內容。之前我們一般都是用 History API 去實現的。

let stateObj = {
    data: "ConardLi",
}

history.pushState(stateObj, "home""bar.html")

但是用過的都知道,這玩意實在是太難用了,而且還很笨重,也容易出現問題。Navigation API 提供了一種更友好的方式來幫助我們操作網頁的導航。

要使用 Navigation API,我們需要在全局對象上添加一個 navigate 監聽器。

navigation.addEventListener('navigate'(navigateEvent) ={
  switch (navigateEvent.destination.url) {
    case 'https://blog.conardli.top/':
      navigateEvent.transitionWhile(loadIndexPage());
      break;
    case 'https://www.conardli.top/':
      navigateEvent.transitionWhile(loadCatsPage());
      break;
  }
});

這個事件採用了集中處理的機制:它會被所有類型的導航觸發,無論是用戶執行了一個動作(例如點擊鏈接、提交表單或返回和前進)還是以代碼的方式觸發導航。在大多數情況下,它會讓你的代碼覆蓋瀏覽器對該操作的默認行爲。對於 SPA,這可能意味着讓用戶保持在同一頁面上並加載或更改網站的內容。

瞭解更多:

[6-24] ECMAScript 2022 正式發佈!

2022 年 6 月 22 日,第 123 屆 ECMA 大會批准了 ECMAScript 2022 語言規範,這意味着它現在正式成爲標準。

主要特性:

瞭解更多:https://262.ecma-international.org/

[6-28] Deno 推出新一代全棧框架 Fresh

Fresh 是一個面向 JavaScriptTypeScript 開發人員的全棧現代 Web 框架,基於 Deno 運行時,前端渲染基於 Preact,由 Deno 原班人馬開發,它的核心是路由框架和模板引擎的組合,可在服務器上按需渲染頁面。

Fresh 可以在運行時做到按需構建,代碼可以直接在服務器和客戶端上運行。例如將 TypeScriptJSX 轉換爲純 JavaScript 都可以在運行時按需完成,可以實現非常快速的迭代和部署。

瞭解更多:

[7-11] 新一代 javaScript 運行時 Bun.js 發佈

近日,新一代 javaScript 運行時 Bun.js 發佈了。和傳統的 Node.js 這種傳統的 javaScript 運行時不同,Bun.js 直接內置了打包器、轉譯器、任務運行器和 npm 客戶端,這意味着你不再需要 Webpack/Rollup/esbuild/Snowpack/Parcel/Rome/swc/babel 就可以直接運行 TypeScript、JSX

另外,Bun.js 原生支持了數百個 Node.jsWeb API,包括約 90%Node-API 函數 (fs、path、Buffer 等)。

Bun.js 的目標是可以在瀏覽器之外的其他地方運行世界上大多數 JavaScript,爲你未來的基礎架構帶來性能和複雜性的增強,並通過更好、更簡單的工具提高開發者的生產力!

瞭解更多:

[7-15] Vite 3.0 發佈

20212 月,Evan You 式推出了 Vite 2.0 版本,自此之後 Vite 生態飛速增長,很快達到了每週 100 萬的 npm 下載量,距離 v2 發佈 16 個月,Vite 3 正式發佈!

主要更新如下:

瞭解更多:https://vitejs.dev/blog/announcing-vite3.html

在今年的 12 月份,Vite 又發佈了 4.0 版本,不過相比 3.0 版本更新範圍較小,所以不過多介紹

[7-16] Chrome 對 HTTP 103 狀態碼提供支持

HTTP 103 狀態碼 (Early Hints) 是一個信息性 HTTP 狀態代碼,可以用於在最終響應之前發送一個初步的 HTTP 響應,它可以算作 HTTP/2 Server Push 的升級改良版。

利用 HTTP 103 狀態碼,可以讓服務器在服務器處理主資源的同時向瀏覽器發送一些關鍵子資源(JavaScript、CSS 或字體文件)或頁面可能使用的其他來源的提示。

瀏覽器可以使用這些提示來預熱連接,並在等待主資源響應的同時請求子資源。換句話說,Early Hints 可以通過提前做一些工作來幫助瀏覽器利用這種服務器思考時間,從而提升頁面的渲染性能。

Chrome 宣佈在 Chrome 103 版本對 HTTP 103 狀態碼提供了支持。

瞭解更多:

[7-29] Firefox 支持了 backdrop-filter

Firefox 103 版本正式支持了 backdrop-filter 屬性,可以輕鬆實現一個毛玻璃效果。

Firefox 是最後一個支持 backdrop-filter 屬性的瀏覽器,目前所有瀏覽器均已對它提供支持。

瞭解更多:https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter

[8-03] 容器查詢和 :has() 屬性

Chrome 105 新增了容器查詢和 :has() 屬性,這兄弟倆可以讓我們能夠查詢父選擇器的大小和樣式信息,同時使子元素可以擁有響應式樣式邏輯。有點類似 @media 查詢,區別是它們根據的是容器的大小而不是視口的大小進行判斷的。

要使用容器查詢,我們可以在卡片容器上設置 container-typeinline-size

.ard-container {
  container-type: inline-size;
}

然後我們就可以使用 @container 將該容器的樣式應用到它的任何子節點:

.card {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

@container (max-width: 400px) {
  .card {
    grid-template-columns: 1fr;
  }
}

當容器小於 400px 時,它就會切換到單列布局。

我們可以使用 :has() 僞類更進一步,它可以讓我們檢查父元素是否包含具有特定參數的子元素。例如,p:has(span) 表示一個段落選擇器,你可以使用它來設置父段落本身或其中的任何內容的樣式。

p:has(span) {
  /* magic styles */
}

figure:has(figcaption) {
  /* this figure has a figcaption */
}

瞭解更多:https://developer.chrome.com/blog/has-with-cq-m105/

[8-11] Islands 架構框架 Astro 1.0 正式發佈

Astro 是一個新型的 SSR 框架,它的測試版已經運行一年多。近期 Astro 1.0 終於發佈了正式版本!

Astro 採用了獨特的 Island 組件架構,團隊稱這是一種用於構建更快網站的新型 Web 架構。與傳統的 SPA 不同,Astro 的組件不會被打包到一個 JavaScript 文件中。相反,每個組件都被視爲一個獨立的小型應用程序,與所有其他組件隔離存在。

瞭解更多:

[8-18] HTTP/2 Server Push 將被刪除

Server Push 即在瀏覽響應 HTML 文件的時候,服務器會同時將所需的資源文件主動推送給瀏覽器。

瀏覽器在收到推送的資源之後會緩存到本地。等解析 HTML 發現需要加載對應資源的時候會直接從本地讀取,不必再等待網絡傳輸了。

雖然這聽起來很神奇,但這個方案有非常大的缺陷:Server Push 很難避免推送瀏覽器已經擁有的子資源,其實很多資源在瀏覽器第一次請求到就已經緩存下來了。這種 “過度推動” 會導致網絡帶寬的使用效率降低,從而顯着阻礙性能優勢。總體而言,Chrome 數據顯示 HTTP2/Push 實際上對整個網絡的性能產生了負面影響。

Chrome 宣佈將在下一個主要版本(Chrome 106)中將刪除對其的支持。

瞭解更多:https://developer.chrome.com/blog/removing-push/

[10-13] React 新提案:use Hook

就在 useEvent Hook 剛剛夭折不久,React 又計劃提供新一個新的 Hook:use,是的就叫 use,它可以讓開發者更輕鬆的使用 Suspense 訪問任意異步數據源。

正常情況下我們在 JavaScript 中請求異步數據一般要藉助 Promise,對應的函數就要使用 asyncawait

async function Note({id, isEditing}) {
  const note = await db.posts.get(id);
  return (
    <div>
      <h1>{note.title}</h1>
      <section>{note.body}</section>
      {isEditing ? <NoteEditor note={note} /> : null}
    </div>
  );
}

而新增的 use Hook,你可以類比爲 await,正如 await 只能在 async 函數內部使用一樣,use 只能在 React 組件和 Hooks 內部使用,而且你可以嵌套在條件、塊和循環中使用,而無需將邏輯拆分爲單獨的組件,這使得我們在 React 中編寫異步代碼變得非常靈活:

function Note({id, shouldIncludeAuthor}) {
  const note = use(fetchNote(id));

  let byline = null;
  if (shouldIncludeAuthor) {
    const author = use(fetchNoteAuthor(note.authorId));
    byline = <h2>{author.displayName}</h2>;
  }

  return (
    <div>
      <h1>{note.title}</h1>
      {byline}
      <section>{note.body}</section>
    </div>
  );
}

瞭解更多:

[10-13] Lerna V6 發佈

Lerna 曾經是最流行的 JS monorepo 工具之一,在去年 Lerna 的核心作者提到了 Learn 已經基本不再維護,在今年 5 月份,Nrwl 宣佈接管了 Lerna

隨後,Nrwl 接管 Lerna 後發佈了第一個全新的正式版本 Lerna v6,推出了新的網站,並宣佈讓 Lerna 的速度提高了 10 倍!

瞭解更多:復活了!Lerna V6 帶來了哪些新東西?

[10-25] Chrome 107:支持識別渲染阻塞資源

對頁面性能的可靠洞察對於我們構建好的用戶體驗是至關重要的,在以前,我們通常會依靠一些複雜的啓發式方法來確定資源是否阻塞頁面的渲染。

Chrome 107Performance API 新增了一個 renderBlockingStatus 屬性,這個屬性會提供來自瀏覽器的直接信號,用於識別阻塞頁面渲染的資源,直到它們被下載下來。

下面的代碼片段顯示瞭如何獲取所有資源的列表並使用新的 renderBlockingStatus 屬性列出所有阻塞頁面渲染的資源。

// 獲取所有資源
const res = window.performance.getEntriesByType('resource');

// 過濾出阻塞渲染的資源
const blocking =   res.filter(({renderBlockingStatus}) =>
      renderBlockingStatus === 'blocking');

優化這些阻塞資源的加載方式(改爲異步加載或增加一些預渲染優化)對於我們網站的 Core Web Vitals 是非常有幫助的,大家可以用起來了~

瞭解更多:Chrome 最近帶來了哪些有意思的新東西?

[10-25] Turbopack 發佈

在今年的 Next.js 大會上,伴隨着 Next.js 13 的發佈,也推出了一個新的工具:Turbopack

Turbopack 是針對 JavaScriptTypeScript 優化的增量打包工具,由 Webpack 的創建者 Tobias KoppersNext.js 團隊使用 Rust 編寫。

在剛推出的時候, Turbopack  給出了一份性能測試數據,數據對常見的打包工具的性能做了對比,結果顯示Turbopack 的性能比 Vite10 倍,比 Webpack700 倍。

此數據一出,在前端圈引起了巨大的爭議,Vite 的作者尤雨溪也親自迴應數據不是很客觀,我們現在在 Turbopack 官網看到的最新數據已經有了變化,測試基準也可以隨意調整(處理 1000-30000React 組組件)

可以發現在最新的測試中,相比 ViteTurbopack 仍然有着不錯的性能優勢,Turbopack 目前只用於 Next.js 13 Dev server,未來還會推出獨立的 CLI 工具,並支持其他框架,如 SvelteVue

瞭解更多:https://turbo.build/pack

[11-04] 瀏覽器存儲新提案:Storage Buckets API

多年來,Web 生態系統中已經發展出很多可用於存儲的 API,例如 IndexedDB、localStorageshowNotification() 等等。

whatwg 新增了 Storage 標準通過定義存儲的持久化、容量估算、過期時間等能力來整合這些 API

// 從存儲桶中訪問 IndexedDB
const inboxDb = await new Promise(resolve ={
  const request = inboxBucket.indexedDB.open("messages");
  request.onupgradeneeded = () ={ /* migration code */ };
  request.onsuccess = () => resolve(request.result);
  request.onerror = () => reject(request.error);
});

// 從存儲桶中使用 File API
const draftFile = await draftsBucket.createFile(
    ["Attachment data"]"attachment.txt",
    { type: "text/plain", lastModified: Date.now() 
});

// 從存儲桶中訪問 cache API
const inboxCache = await inboxBucket.caches.open("attachments");

瞭解更多:它的出現將統一所有瀏覽器存儲 API ?!

[11-07] TypeScript 支持新的 satisfies 操作符

在使用 TypeScript 類型推斷的時候,有很多情況下會讓我們面臨兩難的選擇:我們即希望確保某些表達式能夠匹配某些類型,但也希望保留這個表達式的特定類型用來類型推斷。這就讓我們陷入了兩難的境地,我們用更嚴格了類型約束了寫出 bug 的可能性,但是卻失去了類型推斷的能力。

satisfies 關鍵字就是用來解決這個問題的,它既能讓我們驗證表達式的類型是否與某個類型匹配,也可以保留基於值進行類型推斷的能力:

type Colors = "red" | "green" | "blue";

type RGB = [red: number, green: number, blue: number];

const palette = {
    rad: [255, 0, 0],
    // 可以捕獲到錯別字 rad
    green: "#00ff00",
    blue: [0, 0, 255]
} satisfies Record<Colors, string | RGB>;

// 都可以調用
const a = palette.red.at(0);
const b = palette.green.toUpperCase();

瞭解更多:TypeScript 4.9 發佈!重點新特性解讀

[11-08] Rome 發佈第一個穩定版本

Rome 是一個使用 Rust 編寫的格式化和 Lint 工具,可以用於 JavaScript、TypeScript、JSON、HTML、MarkdownCSS 的格式化。相比傳統的 Lint 工具,它的處理速度非常快,可以在 300毫秒 - 1秒 內處理 6000 個文件。

但是它的野心不止於此,它的目標是將數十種前端語言工具(Babel、ESLint、webpack、Prettier、Jest 等)統一爲一個從頭開始構建的易於使用的工具。

瞭解更多:https://rome.tools/blog/2022/11/08/rome-10/

[11-16] Nuxt 3.0 穩定版發佈

Nuxt3 基於 Vite、Vue3Nitro 等現代框架重寫,具有一流的 Typescript 支持,經過兩年多研究、社區反饋、創新和實驗,終於發佈穩定版本。

瞭解更多:https://nuxt.com/v3

[11-29] 新的 CSS 視口單位

爲了解決移動端網頁滾動時,動態工具欄自動收縮的問題,CSS 工作組規定了視口的各種狀態。

新的視口也分配了單位:

另外還有一個  Dynamic viewport(動態視口)

當動態工具欄展開時,動態視口等於小視口的大小。當動態工具欄被縮回時,動態視口等於大視口的大小。

相應的,它的視口單位以 dv 爲前綴:dvw, dvh, dvi, dvb, dvmin, dvmax

目前,各大瀏覽器均已經對新的視口單位提供了支持:

瞭解更多:Chrome 108 :發佈新的 CSS 佈局單位!

[12-14] SvelteKit 1.0 發佈!

SvelteKit 是一個用 Svelte 構建 Web 應用程序的框架,可以滿足不同規模的應用開發,提供了非常靈活和體驗良好的基於文件系統的路由架構。Svelte 是一個 UI 組件框架,因其出色的性能和易用性而受到開發者喜愛。

經過兩年的開發,SvelteKit 1.0 已正式發佈,現在可用於生產環境,它提供了服務端渲染、路由管理、針對 JS 和 CSS 的代碼分割,以及針對不同 Serverless 平臺生成不同代碼的適配器等功能。

瞭解更多:https://svelte.dev/blog/announcing-sveltekit-1.0

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/HfgifbdzBSOZkDb0ru0XsA