作者丨Somnath Singh
譯者 | 胥磊
這是不是JavaScript框架的下一次革命的開始?顯而易見,是的!
通常的Web開發(fā)中存在一對不可調(diào)和的矛盾,即一方面需要更多的JavaScript代碼來實現(xiàn)你的客戶所期望的功能,而另一方面為了使你的網(wǎng)站能被更快速的加載,又不得不去考慮減少JavaScript的代碼量。作為一名開發(fā)者總在試圖去取得這兩者間的平衡。
如果現(xiàn)在告訴你,你可以隨意寫大量的JavaScript代碼,即使達到數(shù)千兆字節(jié)仍然不需要擔心應(yīng)用的性能問題。更甚者是目前為止你所使用的每個著名的前端框架都在設(shè)計上存在根本性缺陷,你會作何感想?
首先我們要接受一個現(xiàn)實:JavaScript是不可避免的!這將使我們的工作更輕松。我們所處的困境就是我們太固執(zhí)了,不承認目前網(wǎng)絡(luò)發(fā)展混亂的這個事實。很久之前我們就得出過這樣一個結(jié)論:從服務(wù)器端發(fā)送HTML到客戶端代價太高。于是就著手開發(fā)各種替代產(chǎn)品,這些年來我們不停地開發(fā)各種的框架與構(gòu)建web的基礎(chǔ)做斗爭。
通過下面的說明,你就會完全明白我的意思。在一個典型的網(wǎng)絡(luò)應(yīng)用中,我們將服務(wù)器端生產(chǎn)的HTML發(fā)送到客戶端,然后客戶端開始渲染它,當然現(xiàn)在你是不能與它互動的,接下來瀏覽器開始加載JavaScript的部分,最后就是執(zhí)行相關(guān)程序和附加監(jiān)聽,至此你才可以開始與它互動。
那么問題來了盡管服務(wù)器端已經(jīng)將整個結(jié)構(gòu)包括視圖都已經(jīng)發(fā)送給客戶端了,但我們?nèi)砸却敝聊軌蚧?,?dǎo)致整個過程的啟動時間被不必要地增加了。
加載時間過長的主要原因是每次都要從頭開始,整個過程稱為Hydration ,也就是瀏覽器讀取JavaScript部分,進而還確定各個部分的代碼又是屬于網(wǎng)頁上哪個位置和附加監(jiān)聽。如果這就是整個問題的原因所在,難道我們不能通過懶加載來解決嗎?是可以這么做,但并不能解決問題!
試想一下,我們從服務(wù)器端發(fā)出HTML,到客戶端下載執(zhí)行,其中特定的塊以懶加載方式完成。結(jié)果你可能也已經(jīng)想到了,由于組件都是可見的,遇到懶加載的塊只能再次請求組件并完成Hydration ,這樣已經(jīng)失去延遲加載的意義了。這也違背了我們最初使用懶加載的目的。
懶加載對既有系統(tǒng)起作用,主要是對那些不在渲染樹中的組件,對渲染樹中的組件來說,懶加載就是一種干擾。但是大家都沒有認識到這一點,當你反饋應(yīng)用程序太大時,大部分人會主觀認為“只要懶加載所有東西就可以”,而沒有意識到實際上這并不容易做到,特別是我們上面提過的場景。
當然我們還可以采用島嶼架構(gòu),不需要在一開始就對所有的東西進行Hydration (代價有點高),而是在客戶與特定的組件進行交互時進行 。例如當我們與菜單進行交互時,只需要對菜單進行Hydration 。我們可以與任何特定組件互動,都只需要對特定組件Hydration 就行而不是整個應(yīng)用程序。
雖然這是一種改進,但是如果這些 “島嶼”足夠大的話,島間的通信就成了一個問題。因為你剛剛把組件都變成一個個孤島,每個島都是一個獨立應(yīng)用,應(yīng)用間的通信問題就迫切需要解決。
現(xiàn)在Qwik來了!當我們和特定組件互動時,只要將這個組件加載就行,組件的父類和子類都不再需要隨同進行加載了。
Qwik還可以足夠智能地去識別當前組件是否還需要依賴其他組件(想象下電商網(wǎng)站上的添加購物車按鈕),并喚醒依賴組件。這時我們再打開網(wǎng)絡(luò)標簽就會發(fā)現(xiàn)初始頁面加載的JavaScript為零。
加載的頁面上沒有JavaScript并不稀奇,如果你所請求的是一個靜態(tài)頁面任何的框架都能做到這一點。Qwik的奇特之處也并非與此,它通過查看你的代碼判斷后得出結(jié)論“當前不需要任何JavaScript,現(xiàn)在不需要發(fā)送”。所以你會發(fā)現(xiàn)在我們點擊按鈕之前,JavaScript并沒有被加載。
單個JS加載時間看似“點滴”,大量累加很快就會變成 瀑布”。慶幸的是我們頁面的加載時間并沒有因此變長。因為依賴Qwik可以讓你隨心所欲地寫JavaScript,而不用再用擔心包的大小或性能過慢。
Next.js vs Qwik
此外,它還會很聰明的在后臺為網(wǎng)絡(luò)遲緩的用戶預(yù)加載文件,不用特意考慮就能實現(xiàn)令人難以置信的應(yīng)用性。
獨創(chuàng)性通常被當成魔術(shù)
當我初次接觸虛機的時候就覺得非常神奇 “這不可能是真的,居然可以在一個系統(tǒng)中運行另外一個系統(tǒng)?”??此粕衿娴臇|西,背后卻是純粹的技術(shù)。Windows系統(tǒng)里面啟動Linux當初對我來說是那么不可思議,但讓我興奮是另有原因。當你啟動Linux并登錄后,打開一個應(yīng)用程序(例如文字處理器),接著開始打字,然后在某個時間你保存了虛機,然后把相關(guān)文件發(fā)送給你的朋友。當你的朋友通過文件恢復(fù)虛機時,顯示界面正好是當初我們離開時的,而不必經(jīng)過開機,打開文字處理器,再找到最后離開時的輸入位置,這才是吸引我的地方!
這些也正是Qwik所提供的。應(yīng)用在服務(wù)器端啟動,當達到一個特定的狀態(tài)后拍下快照,然后以HTML的形式將快照發(fā)送到客戶端,客戶端就可以直接展示快照時的特定狀態(tài)。從本質(zhì)上講網(wǎng)站啟動慢的原因是我們必須全部加載后再進行Hydration ,整個過程代價是高昂的。
Qwik之所以快,因為它跳過了啟動,客戶端直接展示了服務(wù)器端的確切狀態(tài),其中包含了我們想要執(zhí)行的代碼,還可以訪問語法環(huán)境,用以更新可能被其他組件共享的狀態(tài),當然狀態(tài)本身也是懶加載的。
“最好的代碼是完全沒有代碼”。Qwik的快并不是因為它的效率高,而是因為它善于避免工作,帶來了一種全新的渲染方式,稱為可恢復(fù)性渲染。這也是我們在線播放電影的方式以非線性的方式進行,由用戶決定他們想要應(yīng)用的哪部分和什么時候要。所以Qwik開辟了一個全新的世界,支持你在多個后端的邊緣服務(wù)上渲染你的頁面,然后將它們合并作為一個完整的響應(yīng)。
總結(jié)
幾千年前,釋迦摩尼就告誡我們要選擇中庸之道。但我們的開發(fā)太固執(zhí),仍然選擇走極端。有一群人告訴你要全部使用JavaScript,而另一群人則告訴你千萬不要選擇JavaScript,其余剩下的人則讓你以損失性能為代價,或多或少捆綁包袱來使用JS。
Qwik作為一股清新的空氣,與我們以前使用的框架都不同。在這我不是為某個框架做布道,但我們必須承認它的革命性。希望有更多的框架采用這種方式,它代表了前進的方向,否則我們將永遠限于循環(huán)中。
原文鏈接:https://javascript.plainenglish.io/react-and-next-js-is-dead-something-new-is-finally-replacing-it-for-good-c792c48806f6
胥磊,51CTO社區(qū)編輯,某頭部電商技術(shù)副總監(jiān),關(guān)注Java后端開發(fā),技術(shù)管理,架構(gòu)優(yōu)化,分布式開發(fā)等領(lǐng)域。