發(fā)布于:2020-12-24 16:12:54
0
56
0
自從2013年首次發(fā)布以來(lái),React已成為一個(gè)非常流行的前端框架。在我們的2020開(kāi)發(fā)人員調(diào)查中,它既是第二受歡迎的網(wǎng)站框架,也是第二受歡迎的Web框架。但是它主要產(chǎn)生單頁(yè)應(yīng)用程序(SPA),并且可能給每個(gè)頁(yè)面帶來(lái)各種依賴。尋找更簡(jiǎn)單的多頁(yè)面設(shè)置的開(kāi)發(fā)人員已轉(zhuǎn)向靜態(tài)站點(diǎn)生成器(SSG),該站點(diǎn)生成器需要降價(jià)(通常使用其他模板語(yǔ)言)并構(gòu)建可以部署到Web服務(wù)器的完整站點(diǎn)結(jié)構(gòu)。隨之而來(lái)的是Next.js。
它是兩種樣式的混合,允許您預(yù)渲染仍包含React提供給站點(diǎn)的所有客戶端計(jì)算的頁(yè)面(甚至頁(yè)面上的組件)。在9.5版中,Vercel使Next變得更加通用,允許部分構(gòu)建僅更新某些已更改的頁(yè)面,輕松地逐步采用Next.js,以及一系列對(duì)開(kāi)發(fā)人員友好的更新。
我與Vercel首席執(zhí)行官Guillermo Rauch和Next.js開(kāi)發(fā)負(fù)責(zé)人Tim Neutkens進(jìn)行了交談,討論了此版本帶來(lái)的新功能,Next.js的下一步功能以及他們的方法如何幫助越來(lái)越快的網(wǎng)絡(luò)用戶保持在線狀態(tài)。
如果您想了解更多信息,那么Next.js用戶會(huì)議將于10月27日舉行。
注意:此對(duì)話已經(jīng)過(guò)編輯,以保持清晰度和長(zhǎng)度。
賴安:好吧。因此,對(duì)于不認(rèn)識(shí)的人,您能給我一些有關(guān)Next.js的概述嗎?
蒂姆:這是一個(gè)網(wǎng)絡(luò)框架,可讓您利用Facebook幾年前開(kāi)源的稱為React的技術(shù)來(lái)構(gòu)建網(wǎng)站和應(yīng)用程序。 React本身是一個(gè)視圖層,因此它允許您編寫組件并使它們相互交互,但是它并沒(méi)有涵蓋您要投入生產(chǎn)所需設(shè)置的所有這些不同內(nèi)容。服務(wù)器端渲染,編譯,轉(zhuǎn)譯,使現(xiàn)代代碼在較舊的瀏覽器中運(yùn)行(填充,優(yōu)化所有這些功能)之類的事情。這正是Next可以幫助的。它為您提供了一組效果很好的默認(rèn)設(shè)置。
Ryan:您的網(wǎng)站將其描述為單個(gè)站點(diǎn)生成器和完全渲染的服務(wù)器端動(dòng)態(tài)系統(tǒng)之間的中間地帶。您最喜歡的地方是什么?
蒂姆:Next.js允許您預(yù)渲染頁(yè)面。它在構(gòu)建時(shí)使用靜態(tài)網(wǎng)站生成在服務(wù)器上創(chuàng)建HTML,或者在服務(wù)器端使用運(yùn)行時(shí)呈現(xiàn)。接下來(lái),您可以將它們混合在一起。與大多數(shù)其他框架不同,您不受束縛,哦,我將完全靜態(tài)生成我的應(yīng)用程序。相反,您可以在服務(wù)器端渲染某些頁(yè)面,并靜態(tài)生成某些頁(yè)面。
在新版本中,我們可以更新這些靜態(tài)生成的頁(yè)面,而不必運(yùn)行新的構(gòu)建,從而重新構(gòu)建整個(gè)應(yīng)用程序。
瑞安:對(duì)。這是開(kāi)發(fā)新產(chǎn)品的好機(jī)會(huì)。您如何呈現(xiàn)所有內(nèi)容而又無(wú)需再次構(gòu)建整個(gè)Web網(wǎng)絡(luò)平臺(tái)或網(wǎng)站?
吉列爾莫:當(dāng)您使用靜態(tài)網(wǎng)站生成器時(shí),您將在構(gòu)建時(shí)創(chuàng)建一堆HTML文件。但是從技術(shù)上講,您也可以對(duì)服務(wù)器端渲染執(zhí)行相同的操作,對(duì)嗎?很多人在服務(wù)器端渲染然后緩存,所以技術(shù)是相似的。我想使用的隱喻是靜態(tài)生成在構(gòu)建時(shí)正在運(yùn)行服務(wù)器端渲染。網(wǎng)站上線之前,您需要做一些工作。
Next.js共享相同的基礎(chǔ)技術(shù)和基礎(chǔ)結(jié)構(gòu)來(lái)進(jìn)行靜態(tài)生成和服務(wù)器渲染。開(kāi)發(fā)人員可以選擇在構(gòu)建時(shí)預(yù)渲染其最重要的頁(yè)面,也可以選擇在運(yùn)行時(shí)按時(shí)預(yù)構(gòu)建一些頁(yè)面。
如果非技術(shù)人員只想使用Next.js對(duì)某個(gè)頁(yè)面的內(nèi)容進(jìn)行更改,則他們可以預(yù)覽然后提交更改。我們一次重新生成一個(gè)頁(yè)面,而不是整個(gè)網(wǎng)站。
對(duì)于像《華盛頓郵報(bào)》這樣的客戶,他們擁有數(shù)十萬(wàn)個(gè)故事。動(dòng)態(tài)更改和更新頁(yè)面的能力成為功能站點(diǎn)和非功能站點(diǎn)之間的區(qū)別。
Ryan:對(duì)于像《華盛頓郵報(bào)》這樣的動(dòng)態(tài)頁(yè)面,它們的頁(yè)面兩側(cè)和底部都有很多變化的內(nèi)容。那會(huì)自動(dòng)改變嗎?是否定期進(jìn)行預(yù)渲染?
Guillermo:Next.js的一個(gè)非??岬暮锰幨牵嗽跇?gòu)建時(shí)或在邊緣進(jìn)行渲染(正好在服務(wù)器端渲染時(shí))之外,您仍然可以在客戶端擁有React的全部功能。
Next.js允許您將計(jì)算分離并放置到任何地方。與動(dòng)畫(huà),懸停效果,點(diǎn)擊和預(yù)提取等互動(dòng)時(shí),您可以在設(shè)備上進(jìn)行計(jì)算。您可以將計(jì)算放在邊緣以便及時(shí)渲染。
您可以在構(gòu)建時(shí)進(jìn)行計(jì)算。您可以在網(wǎng)站訪問(wèn)量大增之前進(jìn)行操作。例如,當(dāng)有人訪問(wèn)《華盛頓郵報(bào)》時(shí),動(dòng)態(tài)渲染舊金山的天氣。顯然,您不會(huì)為每個(gè)訪問(wèn)者預(yù)先渲染舊金山的天氣,尤其是當(dāng)他們像來(lái)自紐約的Ryan那樣訪問(wèn)時(shí)。
因此,您具備了React和React掛鉤,React生命周期,React狀態(tài)的全部功能,可以在客戶端上增加動(dòng)態(tài)性。
Ryan:客戶端的渲染— Next.js的新功能嗎?
吉列爾莫:客戶端一直是規(guī)范。當(dāng)?shù)谝淮纬霈F(xiàn)react時(shí),人們嚴(yán)格將其用于單頁(yè)應(yīng)用程序。這實(shí)際上是促使我們創(chuàng)建Next.js的原因。我們就像,您將失去SEO。您將失去性能,因?yàn)楝F(xiàn)在您要在設(shè)備上渲染所有內(nèi)容。您可以提前渲染一些,然后與其他人共享。
我們還擔(dān)心設(shè)備上的JavaScript處理功能與我的iPhone不同的新興市場(chǎng)。在客戶端渲染所有內(nèi)容對(duì)它非常有害。這是世界上增長(zhǎng)最快的互聯(lián)網(wǎng)用戶群體。
Next.js出來(lái)首先進(jìn)行服務(wù)器渲染。但是后來(lái)我們意識(shí)到,世界上出現(xiàn)了非常有趣的用戶群體,尤其是在Jamstack生態(tài)系統(tǒng)周圍。他們還希望擁有完全靜態(tài)的頁(yè)面,句號(hào)。他們不想打服務(wù)器。只是經(jīng)過(guò)預(yù)先計(jì)算的純HTML。出現(xiàn)混合的想法是因?yàn)槲覀円庾R(shí)到我們不必在一個(gè)渲染模型和另一個(gè)渲染模型之間進(jìn)行選擇。有時(shí),它會(huì)涉及到特定頁(yè)面。然后在9.5中,我們添加了以下功能:在運(yùn)行時(shí),一旦您部署了站點(diǎn),便可以添加新的靜態(tài)頁(yè)面或刷新它們。我們稱這種增量靜態(tài)生成。
瑞恩:聽(tīng)起來(lái)您在各個(gè)頁(yè)面上都允許很多生成點(diǎn)。 9.5還帶來(lái)了什么?
蒂姆:我們?cè)噲D集中精力解決人們遇到的許多常見(jiàn)問(wèn)題。一些看似很小的更改會(huì)產(chǎn)生很大的影響,例如自動(dòng)重定向尾部斜杠,然后處理該行為,以防您的URL中出現(xiàn)尾部斜杠。
另一個(gè)是允許您設(shè)置基本路徑。以前,可以在域的子路徑上托管Next應(yīng)用程序。假設(shè)您最初只想在文檔中采用Next。您可以將其托管在/ docs上,但是很難在服務(wù)器路由/ docs,客戶端必須處理/ docs前綴以及所有這些內(nèi)容的情況下,將所有這些不同的部分協(xié)同工作。所有鏈接必須以/ docs為前綴。如果您忘記給它加上前綴,則會(huì)有隨機(jī)的404。
現(xiàn)在在9.5中,您將獲得此基本路徑選項(xiàng),如果將其設(shè)置為/ docs,它將自動(dòng)在/ docs上投放正確的資產(chǎn),然后自動(dòng)為所有URL加上前綴。您不必考慮,嘿,我想將/ docs更改為其他URL,因?yàn)槲覀冋谝苿?dòng)網(wǎng)站。您無(wú)需考慮所有這些不同的前綴或在何處設(shè)置它們。
吉列爾莫(Guillermo):這是更廣泛倡議的一部分。我們稱為重寫的另一個(gè)功能是關(guān)于Next.js的逐步采用。自最初發(fā)布以來(lái),我們已經(jīng)看到各種規(guī)模的站點(diǎn)都采用了該技術(shù),但現(xiàn)在我們已經(jīng)看到了人們對(duì)從React應(yīng)用程序或自家開(kāi)發(fā)的框架遷移到堆棧的興趣他們厭倦了維護(hù)。
大多數(shù)團(tuán)隊(duì)都不想在一夜之間完成全部重寫。眾所周知,該行業(yè)非常規(guī)避風(fēng)險(xiǎn),對(duì)采用技術(shù)保持謹(jǐn)慎。您可以一次開(kāi)始一頁(yè),也可以一次開(kāi)始一頁(yè)子樹(shù)。在Tim給出的示例中,我們決定針對(duì)網(wǎng)站的特定部分,將其完全替換為新的Next.js應(yīng)用。我要托管`/ docs`和頁(yè)面的子樹(shù)。
您可以執(zhí)行的另一種方法是使用添加的重寫選項(xiàng),其中Next.js將處理您在pages目錄中定義的頁(yè)面。例如,假設(shè)我已定義“ about.js”,這意味著我已注冊(cè)為“ / about”路線。然后,您可以說(shuō)其他所有內(nèi)容,請(qǐng)轉(zhuǎn)到舊堆棧。
這可以實(shí)現(xiàn)無(wú)花果扼殺器模式,您可以在其中繼續(xù)向Next.js添加頁(yè)面。訪問(wèn)者首先訪問(wèn)Next.js,如果此頁(yè)面位于Next.js目錄中,則將其加載。否則,訪問(wèn)者將轉(zhuǎn)到舊堆棧。您為團(tuán)隊(duì)提供了采用現(xiàn)代技術(shù)的漸進(jìn)式協(xié)作方式,同時(shí)降低了轉(zhuǎn)換的風(fēng)險(xiǎn)。它并排顯示了更改,并衡量了兩個(gè)堆棧的客戶端和服務(wù)器端性能。在很多情況下,我們看到了非常好的結(jié)果。最終,許多應(yīng)用程序成為一個(gè)Next.js應(yīng)用程序。
瑞安:這是讓他們毫無(wú)危險(xiǎn)地將腳趾伸入水中的一種簡(jiǎn)便方法。如您所說(shuō),React主要用于單頁(yè)面應(yīng)用程序。要使Next.js不再是單頁(yè)應(yīng)用程序框架,您需要做什么?
蒂姆:當(dāng)您開(kāi)始構(gòu)建Next.js應(yīng)用程序時(shí),您從pages目錄開(kāi)始。您在其中創(chuàng)建的每個(gè)值都會(huì)有一條不同的路線,這可能是一條固定路線,例如映射到/ about的about.js或一條動(dòng)態(tài)路線。
如果您要進(jìn)行動(dòng)態(tài)細(xì)分,則也可以這樣做。這聽(tīng)起來(lái)很簡(jiǎn)單,但是它允許我們創(chuàng)建一個(gè)多頁(yè)面架構(gòu),其中每個(gè)頁(yè)面本身幾乎都是React應(yīng)用程序內(nèi)的一個(gè)子應(yīng)用程序。這意味著每個(gè)頁(yè)面都將成為一個(gè)單獨(dú)的包;它是默認(rèn)情況下的代碼拆分。
如果您要導(dǎo)入的內(nèi)容非常大,例如一個(gè)1兆字節(jié)的NPM庫(kù),那么它不會(huì)影響應(yīng)用程序中的所有其他頁(yè)面。在構(gòu)建React應(yīng)用程序時(shí),您必須相當(dāng)清楚要導(dǎo)入的內(nèi)容以及它將如何影響應(yīng)用程序的其余部分。您將在初始頁(yè)面加載時(shí)為應(yīng)用程序中的每個(gè)路由發(fā)送代碼。假設(shè)您打開(kāi)一個(gè)網(wǎng)站,該網(wǎng)站有React,但使用自定義路由器構(gòu)建。它會(huì)發(fā)送儀表板以及所有設(shè)置頁(yè)面以及所有其他信息。但是您不希望在最初的營(yíng)銷頁(yè)面上看到它,對(duì)嗎?
吉列爾莫:開(kāi)發(fā)人員必須非常清楚他們交付給客戶端的JavaScript數(shù)量。之所以有些偏執(zhí),是因?yàn)樗鼈兺斗诺腏avaScript越多,使它們成為最重要的網(wǎng)絡(luò)要素的速度就越慢,例如普通用戶與頁(yè)面互動(dòng)的時(shí)間。當(dāng)他們按下商店商品上的“購(gòu)買”按鈕時(shí),該商品就能真正起作用并迅速做出響應(yīng)嗎?如果我點(diǎn)擊帶我穿Lululemon褲子的廣告(我以Lululemon的示例為例,因?yàn)樗鼈兪褂肗ext.js),那么我只想加載渲染這些褲子所需的代碼。
在這種情況下,褲子的渲染已經(jīng)在邊緣的緩存中完成了。因此,所有結(jié)構(gòu),頁(yè)面,畫(huà)廊,輪播,價(jià)格,其中大部分來(lái)自預(yù)渲染的頁(yè)面。其他一些個(gè)性化設(shè)置可能會(huì)在最后一英里發(fā)生,但是在大多數(shù)情況下,頁(yè)面的很多結(jié)構(gòu)都是預(yù)渲染的。當(dāng)我按下“購(gòu)買”按鈕時(shí),這必須非常快,因?yàn)榉駝t,我不會(huì)賣褲子。 Next.js為該團(tuán)隊(duì)自動(dòng)完成了很多工作,因?yàn)槲覀優(yōu)樗麄兲峁┝诉@種具有多個(gè)頁(yè)面入口點(diǎn)的體系結(jié)構(gòu)。該框架知道如何通過(guò)代碼將客戶端的JavaScript分成幾小束,并自動(dòng)從中提取常見(jiàn)的束。
從呈現(xiàn)管道的角度來(lái)看,不僅是代碼拆分,而且還是,我們可以呈現(xiàn)React將在客戶端中運(yùn)行的代碼。我們可以在邊緣執(zhí)行它。
瑞恩:因此,您可以構(gòu)建許多小的預(yù)渲染構(gòu)建塊并一點(diǎn)一點(diǎn)地組裝頁(yè)面。 9.5還有哪些其他新功能?
蒂姆:我們還沒(méi)有介紹的一件事就是我們改進(jìn)了快速刷新核心。反應(yīng)快速刷新使您可以在進(jìn)行編輯時(shí)保留狀態(tài),并且操作可靠。這意味著,在React中,您具有可以保留在組件內(nèi)部的狀態(tài)。假設(shè)您有一個(gè)標(biāo)簽欄,您可以在其中單擊不同的標(biāo)簽。狀態(tài)將保留在組件內(nèi)部。快速刷新允許您執(zhí)行的操作是,單擊此選項(xiàng)卡,對(duì)代碼進(jìn)行了一些更改,并且將在適當(dāng)?shù)奈恢眠M(jìn)行更新,但不會(huì)將該組件重置為其初始狀態(tài)。
編輯時(shí),該標(biāo)簽保持打開(kāi)狀態(tài)??焖偎⑿潞w了開(kāi)發(fā)時(shí)間的改進(jìn)。更新后,我們會(huì)進(jìn)行適當(dāng)?shù)母?,因此您不必一直刷新瀏覽器。但是,如果您要引入某種錯(cuò)誤怎么辦?您在應(yīng)用程序中的某處打錯(cuò)了文字,然后突然崩潰了。
在9.5中,您會(huì)得到一個(gè)非常好的消息,說(shuō),這是您搞砸的確切行。我們做了一些額外的改進(jìn)以幫助開(kāi)發(fā)人員。這也是一項(xiàng)持續(xù)的工作。我們發(fā)現(xiàn)任何對(duì)工程師和開(kāi)發(fā)人員無(wú)濟(jì)于事的錯(cuò)誤,我們正在予以改善。
吉列爾莫(Guillermo):在JavaScript世界中,這是一種動(dòng)態(tài)的語(yǔ)言,這是一個(gè)難題。開(kāi)發(fā)人員總是在香草JS之上添加語(yǔ)言,因?yàn)楹芏嗳硕枷M碌恼Z(yǔ)法能夠向下編譯并得到瀏覽器的支持,或者他們?cè)陧敳刻砑覶ypeScript。然后,在TypeScript之上,您將擁有React特有的所有語(yǔ)法,即JSX,它使您可以將類似HTML的標(biāo)簽嵌入到JS文件中。語(yǔ)言本身具有超級(jí)動(dòng)態(tài)性和通用性。在世界上,準(zhǔn)確的錯(cuò)誤實(shí)際上是罕見(jiàn)的。
確定代碼位置-您是否有有意義的堆棧跟蹤?有趣的是,它仍在與React團(tuán)隊(duì)共同努力。為其模板組件的堆棧跟蹤提供越來(lái)越好的堆棧跟蹤是一項(xiàng)即將到來(lái)的功能,因此您可以準(zhǔn)確了解在渲染管道中的哪個(gè)位置發(fā)生了某些錯(cuò)誤。
真正整潔的地方-這就是該生態(tài)系統(tǒng)的優(yōu)勢(shì)所在-這種快速刷新技術(shù)非常快。保存后,大約100毫秒左右即可在Web瀏覽器上看到更改。這為開(kāi)發(fā)人員提供了一定程度的流程,并在他們正在考慮的內(nèi)容和正在從事的工作之間保持聯(lián)系,并具有不斷迭代的能力。
它幾乎是其他任何堆棧所無(wú)法比擬的。 Swift UI開(kāi)始朝著這個(gè)方向發(fā)展。但是React給了我們前所未有的東西。人們過(guò)去經(jīng)常進(jìn)行實(shí)時(shí)重新加載。當(dāng)它檢測(cè)到更改時(shí),將刷新整個(gè)頁(yè)面,等效于按F5或刷新按鈕?,F(xiàn)在,React知道什么狀態(tài)正在改變,組件圖的哪些葉子正在改變。快速刷新技術(shù)使代碼更新非常精細(xì)地在Web瀏覽器中進(jìn)行。因?yàn)樗侨绱说木?xì),所以我們只做很少的工作。我們正朝著這個(gè)世界發(fā)展,我們正在談?wù)撋踔恋陀?00毫秒。我們可以在10、15、20毫秒內(nèi)顯示您的更改。這一切都?xì)w結(jié)為在屏幕上制作補(bǔ)丁程序,因?yàn)殚_(kāi)發(fā)人員會(huì)盡快在本地設(shè)備上進(jìn)行盡可能細(xì)致的更改。
瑞安:這是很多新東西。還有什么值得一談的嗎?
吉列爾莫:當(dāng)然可以。我們已經(jīng)添加了對(duì)Webpack 5的實(shí)驗(yàn)性支持。Tim一直在致力于這一工作,我們不僅在改善開(kāi)發(fā)人員體驗(yàn)(在本地設(shè)備上更新內(nèi)容的速度有多快),還包括在推送時(shí)以及CI / CD層會(huì)發(fā)生什么開(kāi)始建立網(wǎng)站?
Next.js在很大程度上已經(jīng)抽象出捆綁技術(shù)。您無(wú)需配置Webpack。到目前為止,Next.js一直在使用Webpack 4,但我們已經(jīng)能夠?qū)⒋蠖鄶?shù)用戶的Webpack升級(jí)到Webpack5。這是目前的試驗(yàn)性標(biāo)志,但Tim可以談?wù)撍哂芯薮蟮男阅軆?yōu)勢(shì)。
我們非常激動(dòng),它將改變Next.js的性能。
蒂姆:Webpack 5目前處于測(cè)試階段。在持續(xù)開(kāi)發(fā)中,它已經(jīng)處于測(cè)試階段一年甚至兩年以上。新版本的表面積非常大,因?yàn)樗荚诮鉀Q當(dāng)前Webpack穩(wěn)定版本中的許多不一致問(wèn)題。
當(dāng)前在Webpack中,構(gòu)建不是確定性的。這意味著,如果您使用相同的完全相同的代碼庫(kù)并運(yùn)行兩次Webpack,則不會(huì)輸出相同的完全相同的JavaScript包。如果您每次都要重新計(jì)算,通常這不是問(wèn)題,但是當(dāng)您要緩存某些內(nèi)容時(shí),這將成為問(wèn)題。但是我希望他們只重新計(jì)算在我的代碼中更改的位。在這里,確定性輸出會(huì)產(chǎn)生很大的變化。您無(wú)法將其緩存到不確定的輸出中,因?yàn)槊看螛?gòu)建時(shí)輸出都會(huì)變化。
Webpack 5的輸出完全是確定性的,它添加了以前缺少的該緩存層。實(shí)際上,根據(jù)您的應(yīng)用程序,您可以將構(gòu)建速度提高25倍。在更大的應(yīng)用上,它將產(chǎn)生很大的影響。
如果Next.js應(yīng)用程序中有許多不同的頁(yè)面,則必須編譯所有這些頁(yè)面。當(dāng)前,每次運(yùn)行構(gòu)建時(shí),它都會(huì)緩存一些工作,但不是全部。啟用Webpack 5后,您可以在CI環(huán)境和開(kāi)發(fā)中更快地運(yùn)行構(gòu)建。
在開(kāi)發(fā)中,這將極大地幫助開(kāi)發(fā)人員體驗(yàn)。 當(dāng)您啟動(dòng)Next.js實(shí)例時(shí),入門會(huì)更快。 您昨天所做的所有工作仍被緩存。
Next.js應(yīng)用程序的部署將大大加快。 它只需要重新計(jì)算已更改的位。 通常,您不會(huì)對(duì)應(yīng)用程序中的每個(gè)頁(yè)面進(jìn)行更改。 您只需要更改幾頁(yè)或一頁(yè),甚至只是改正錯(cuò)字。 在這種情況下,您希望構(gòu)建速度更快。 它即將發(fā)布,因此我們對(duì)此感到非常高興。
瑞安(Ryan):您是否想挑逗將來(lái)會(huì)發(fā)生的一些有趣的事情?
蒂姆: 我們計(jì)劃在10月27日舉行一次Next.js用戶會(huì)議,目前已經(jīng)有50,000多個(gè)注冊(cè)。 我們還將在會(huì)議上宣布許多非??岬男鹿δ堋?/span>
作者介紹
熱門博客推薦