作者:京東物流 盧旭
大前端包括哪些技術(shù)棧
大前端指的是涵蓋所有與前端開發(fā)相關(guān)的技術(shù)和平臺(tái),應(yīng)用于各類設(shè)備和操作系統(tǒng)上。大前端不僅包括Web開發(fā),還包括移動(dòng)端開發(fā)和跨平臺(tái)應(yīng)用開發(fā),具體包括:
?原生應(yīng)用開發(fā):Android、iOS、鴻蒙(HarmonyOS)等;
?Web前端框架:Vue、React、Angular等;
?小程序開發(fā):微信小程序、京東小程序、支付寶小程序等;
?跨平臺(tái)解決方案:React Native、Flutter、Taro、Weex等。
什么是渲染
?渲染:在計(jì)算機(jī)中,渲染是指將計(jì)算機(jī)程序中的圖形數(shù)據(jù)(三維模型、紋理、光源等)通過計(jì)算和圖形處理技術(shù),最終轉(zhuǎn)化為圖像的過程。這個(gè)過程不僅限于靜態(tài)圖像的生成,也包括動(dòng)畫和視頻的渲染,以實(shí)現(xiàn)逼真的視覺效果。
?渲染原理:是指將代碼轉(zhuǎn)換為用戶可以看到的UI界面的過程。如在Web前端領(lǐng)域,渲染原理主要涉及如何將HTML、CSS和JavaScript等代碼轉(zhuǎn)化為用戶界面上的實(shí)際顯示效果。這個(gè)過程通常包括解析、布局、繪制等步驟,具體根據(jù)不同的平臺(tái)有不同的實(shí)現(xiàn)方式,渲染引擎也有所不同。?
Android渲染原理
Android的渲染引擎負(fù)責(zé)將應(yīng)用程序的用戶界面渲染到屏幕上。其中的核心組件包括:
?SurfaceFlinger?:負(fù)責(zé)合并來自不同應(yīng)用程序的圖形輸出,并將其組合成一個(gè)屏幕圖像。它管理著EventControlThread、DispSyncThread等線程,以及處理VSYNC信號(hào),確保UI的平滑顯示?;
?Skia:Android的2D圖形庫,用于繪制應(yīng)用程序的用戶界面;Skia實(shí)現(xiàn)了Canvas系統(tǒng),可以處理矢量圖形、文本和位圖等不同類型的繪圖需求。
?OpenGL ES/Vulkan: 兩種主要的圖形API,用于處理高性能的3D渲染;OpenGL ES是移動(dòng)設(shè)備上常用的圖形API標(biāo)準(zhǔn),而Vulkan是較新的高效低開銷圖形API。
?Hardware Composer (HWC):HAL(Hardware Abstraction Layer)組件,可與GPU和顯示器直接交互;它處理來自SurfaceFlinger的圖層,并決定如何高效地組合這些圖層。
?Gralloc:圖形緩沖區(qū)分配器,它負(fù)責(zé)管理內(nèi)存從不同的圖形組件(如SurfaceFlinger、應(yīng)用程序)之間的共享和分配。通過Gralloc,多個(gè)圖形組件可以有效地在共享的緩沖區(qū)上進(jìn)行繪制操作。
?RenderThread:這是UI渲染pipeline的一個(gè)重要部分,特別是對(duì)于繪制復(fù)雜UI的應(yīng)用程序;它運(yùn)行在一個(gè)獨(dú)立的線程上,以處理資源密集型的渲染任務(wù),避免阻塞主線程。
?Choreographer?:通過內(nèi)部的FrameDisplayEventReceiver接收VSYNC信號(hào),統(tǒng)一處理InputEvent、Animation和Traversal等任務(wù)。它負(fù)責(zé)協(xié)調(diào)UI的繪制,確保在每個(gè)VSYNC信號(hào)到達(dá)時(shí)執(zhí)行必要的繪制操作
?GLSurfaceView: 提供一個(gè)OpenGL ES繪圖表面,并且可以將OpenGL的繪圖命令路由到相關(guān)的GL context中;通常用于實(shí)現(xiàn)高級(jí)別的3D圖形渲染。
?TextureView:可以在應(yīng)用程序中作為一個(gè)UI組件來顯示內(nèi)容,如視頻和其他動(dòng)畫,它內(nèi)部使用Texture來高效管理。
?WebView: 用于處理H5頁面顯示的組件,它內(nèi)部不僅涉及HTML渲染,還包含圖形渲染組件。
View和ViewGroup是應(yīng)用框架層的核心組件,View是界面的基本元素,而ViewGroup是View的容器。渲染引擎通過遍歷View樹,計(jì)算每個(gè)View的大小和位置,并將其繪制到屏幕上。主要涉及以下幾個(gè)步驟:
?測(cè)量(Measurement):在這個(gè)階段,渲染引擎會(huì)遍歷View樹,并調(diào)用每個(gè)View的onMeasure方法來計(jì)算其大小。這個(gè)過程會(huì)從上到下(從根View到子View)進(jìn)行,以確保每個(gè)View都根據(jù)其父View的大小約束來確定自己的大小。
?布局(Layout):通過XML布局文件或者Java/Kotlin代碼定義View層級(jí),系統(tǒng)解析后會(huì)生成相應(yīng)的View樹,在測(cè)量階段完成后,渲染引擎會(huì)進(jìn)入布局階段。在這個(gè)階段,它會(huì)調(diào)用每個(gè)View的onLayout方法來確定其在屏幕上的位置。這個(gè)過程同樣是從上到下進(jìn)行的,以確保每個(gè)View都被放置在正確的位置上。
?繪制(Draw):渲染引擎會(huì)遍歷View樹,并調(diào)用每個(gè)View的onDraw方法來將其內(nèi)容繪制到屏幕上。這個(gè)過程可能會(huì)使用到GPU加速來提高繪制效率。
?合并圖層(Layer Merge):將不同視圖的圖層合并為最終的顯示圖像。
?顯示到屏幕(Display to Screen):將合并后的圖像顯示到屏幕上。
Android的渲染過程是自上向下的遞歸測(cè)量和布局過程,Android 系統(tǒng)的渲染管道充分利用了多線程、硬件加速和顯示同步技術(shù),確保流暢的用戶體驗(yàn)。從應(yīng)用程序定義的界面,經(jīng)過 View 系統(tǒng)層的繪制,到 GPU 硬件加速實(shí)現(xiàn),再到最終合成顯示。這些組件共同承擔(dān)了將應(yīng)用程序的圖形內(nèi)容高效地顯示到設(shè)備屏幕上的任務(wù),確保圖形渲染的高效性和穩(wěn)定性。
iOS渲染原理
iOS 的渲染原理是核心組件的共同協(xié)作,實(shí)現(xiàn)高效且流暢的界面顯示;主要核心組件包括:
?UIKit/Core Animation層:UIKit 中的所有界面元素都是基于 UIView 和 CALayer 的,它們共同起作用來描述并管理視圖的層級(jí)關(guān)系和屬性(例如背景顏色、邊框、陰影等);DisplayLink是解決屏幕刷新率問題,DisplayLink在每次屏幕刷新前會(huì)調(diào)用回調(diào)函數(shù),保證整個(gè)渲染過程的刷新頻率與屏幕刷新頻率同步,確保幀率。
?Core Animation:Compositing是在代碼執(zhí)行修改界面的屬性之后,UIKit 會(huì)將這些修改提交給 Core Animation,后者會(huì)將這些屬性變化組合在一起,并生成一個(gè)光柵化的視圖圖像。這些圖像然后會(huì)被傳遞到合成器進(jìn)行處理。Animation是Core Animation 負(fù)責(zé)處理動(dòng)畫效果,通過離屏渲染和硬件加速來提高性能,這樣保證界面動(dòng)畫的流暢性和穩(wěn)定性。
?Render Server:Layer Tree是當(dāng)應(yīng)用程序?qū)?a target="_blank">信息提交給 Core Animation,Core Animation 會(huì)將這些信息發(fā)送到一個(gè)叫作 Render Server 的后臺(tái)進(jìn)程。Render Server 會(huì)處理這個(gè)層級(jí)樹(Layer Tree),并對(duì)其進(jìn)行必要的合成和繪制操作。打包成二進(jìn)制元數(shù)據(jù),發(fā)送到GPU進(jìn)行實(shí)際渲染,Render Server打包所有的Layer信息并發(fā)送到GPU進(jìn)行實(shí)際的渲染處理。
?Metal/ OpenGL ES:繪制指令是Render Server 將合成后的層(Layer)提交給 Metal 或 OpenGL ES,這些渲染框架會(huì)根據(jù)指令調(diào)度圖形處理單元(GPU)進(jìn)行實(shí)際的繪制操作。它們負(fù)責(zé)將高層次的繪圖指令轉(zhuǎn)換為低層次的 GPU 指令。
?GPU 渲染:GPU 負(fù)責(zé)執(zhí)行這些繪圖指令,把每一幀繪制到屏幕緩沖區(qū)。GPU加速能夠顯著提高圖形的繪制效率和性能。
?VSync 和 Framebuffer:VSync(垂直同步)是為了避免屏幕撕裂現(xiàn)象,iOS 使用 VSync 機(jī)制。VSync 會(huì)在屏幕刷新期間觸發(fā)通知,使應(yīng)用程序和 Render Server 知道什么時(shí)候該提交新的一幀數(shù)據(jù)。
?Framebuffer是GPU 完成渲染后,幀緩沖區(qū) (Framebuffer) 中的內(nèi)容被送到顯示控制器,最終顯示在屏幕上。
整個(gè)過程是 CPU 和 GPU 的協(xié)作工作,分階段地處理和優(yōu)化每一幀的渲染,確保最終的顯示效果流暢、精美;此外,通過使用硬件加速和高效的渲染算法,iOS 渲染系統(tǒng)能夠在保持高性能的同時(shí)節(jié)省設(shè)備的電力消耗;而繪制流程主要包括布局、繪制和渲染,如下:
??布局階段?:在iOS中,布局是通過Auto Layout系統(tǒng)實(shí)現(xiàn)的,這是一個(gè)基于約束的布局系統(tǒng),它根據(jù)視圖及其子視圖的約束條件計(jì)算位置和大小。當(dāng)約束條件發(fā)生變化時(shí),Layout Engine會(huì)重新計(jì)算視圖的位置和大小,這個(gè)過程稱為布局?;布局階段涉及到視圖的層級(jí)關(guān)系設(shè)置,包括視圖的位置、大小、背景色等屬性。這個(gè)階段還包括了計(jì)算和設(shè)置視圖的frame,這是通過約束的計(jì)算來確定的?。
?繪制階段?:繪制階段涉及到將視圖的內(nèi)容繪制到屏幕上。這包括調(diào)用drawRect:和drawLayer:inContext:等方法,這些方法在視圖需要重繪時(shí)被調(diào)用?。在這個(gè)階段,視圖會(huì)將其內(nèi)容繪制到圖層上。每個(gè)UIView對(duì)象都有一個(gè)layer屬性,指向一個(gè)CALayer類的對(duì)象,視圖會(huì)將自己繪制到這個(gè)圖層上?。
?渲染階段?:渲染階段是將繪制好的圖層內(nèi)容呈現(xiàn)到屏幕上。這個(gè)過程涉及到圖層的提交、核心動(dòng)畫的處理、OpenGL幾何形狀的設(shè)置以及最終的屏幕渲染?。渲染階段主要由GPU執(zhí)行,而布局和繪制階段主要由CPU處理。CPU和GPU的協(xié)同工作使得iOS設(shè)備的圖形渲染高效且流暢?。
鴻蒙渲染原理
鴻蒙系統(tǒng)(HarmonyOS)是華為開發(fā)的一種微內(nèi)核操作系統(tǒng),用于包括智能手機(jī)、平板、智能手表、物聯(lián)網(wǎng)設(shè)備等。鴻蒙系統(tǒng)的渲染原理涉及多個(gè)方面,主要包括UI渲染、圖形處理和硬件加速等。鴻蒙采用了分布式架構(gòu)設(shè)計(jì),可以實(shí)現(xiàn)一次開發(fā),多端部署。
鴻蒙的渲染流程包括以下幾個(gè)步驟:
1.ArkUI聲明式UI:開發(fā)者使用ArkUI編寫界面描述文件。
2.編譯生成Render Node樹:將ArkUI文件編譯成中間表示形式Render Node樹。
3.生成VNode樹:將Render Node樹轉(zhuǎn)換為VNode樹,用于虛擬DOM的管理和更新。
4.渲染合成:根據(jù)VNode樹的數(shù)據(jù)結(jié)構(gòu)和屬性信息進(jìn)行繪制操作,最終輸出到屏幕上。
鴻蒙的亮點(diǎn)在于提供了分布式UI能力,即可以在多個(gè)設(shè)備上進(jìn)行協(xié)同渲染,讓UI不僅局限于一個(gè)設(shè)備上運(yùn)行,而是分布式地在多個(gè)終端設(shè)備上共同運(yùn)行,從而提升性能和用戶體驗(yàn)。
Vue渲染原理
Vue.js是一款JavaScript框架,用于構(gòu)建用戶界面;Vue的渲染原理基于虛擬DOM技術(shù);當(dāng)組件的狀態(tài)發(fā)生變化時(shí),Vue會(huì)創(chuàng)建一個(gè)新的虛擬DOM樹來反映這些變化;然后,Vue會(huì)比較新老虛擬DOM樹的差異,并計(jì)算出最小的修改量來更新實(shí)際的DOM結(jié)構(gòu),其渲染流程包括以下主要步驟:
?初始化:當(dāng)創(chuàng)建 Vue 實(shí)例時(shí),Vue 會(huì)進(jìn)行初始化,包括綁定數(shù)據(jù)、計(jì)算屬性、方法和偵聽器。響應(yīng)式系統(tǒng)會(huì)將數(shù)據(jù)對(duì)象轉(zhuǎn)換為響應(yīng)式對(duì)象,并初始化模板編譯器和渲染函數(shù)。
?解析模板:Vue首先會(huì)解析模板,并生成一個(gè)抽象語法樹(AST)。這個(gè)過程中,Vue會(huì)將模板中的指令和屬性轉(zhuǎn)換為對(duì)應(yīng)的AST節(jié)點(diǎn)。
?生成渲染函數(shù):Vue根據(jù)AST生成一個(gè)渲染函數(shù),該函數(shù)用于生成虛擬DOM樹。渲染函數(shù)是一個(gè)JavaScript函數(shù),用于生成VNode(Vue的虛擬DOM節(jié)點(diǎn))并將其渲染到真實(shí)的DOM樹上。
?執(zhí)行渲染函數(shù):當(dāng)組件的狀態(tài)發(fā)生變化時(shí),Vue會(huì)重新執(zhí)行渲染函數(shù),生成一個(gè)新的虛擬DOM樹。
?對(duì)比新舊虛擬DOM樹:Vue會(huì)對(duì)比新舊虛擬DOM樹的差異,找出需要更新的部分。這個(gè)過程通過Vue內(nèi)部的“diff”算法實(shí)現(xiàn),該算法會(huì)對(duì)比新舊虛擬DOM樹的結(jié)構(gòu)和屬性,找出差異。
?更新DOM:根據(jù)差異更新真實(shí)的DOM樹。Vue會(huì)最小化DOM操作的次數(shù),只更新需要變化的部分,而不必重新渲染整個(gè)頁面。
Vue的渲染原理通過響應(yīng)式系統(tǒng)和虛擬DOM協(xié)同工作,實(shí)現(xiàn)了高效的數(shù)據(jù)綁定和靈活的視圖更新策略。我們只需關(guān)注數(shù)據(jù)的變化,Vue會(huì)自動(dòng)處理視圖的更新,大大提高了開發(fā)效率和用戶體驗(yàn)。
React渲染原理
React的渲染原理有幾個(gè)核心概念:Virtual DOM(虛擬DOM)、Reconciliation(協(xié)調(diào))。
?Virtual DOM:Virtual DOM是React用來描述真實(shí)DOM樹的一個(gè)JavaScript對(duì)象樹,其結(jié)構(gòu)和真實(shí)的DOM樹一一對(duì)應(yīng)。當(dāng)組件的狀態(tài)(state)或?qū)傩裕╬rops)發(fā)生變化時(shí),React不是直接操作真實(shí)的DOM樹,而是在內(nèi)存中創(chuàng)建一個(gè)新的Virtual DOM樹。
?Diffing 算法:React通過比較新舊Virtual DOM樹的差異(使用Diff算法),來確定哪些部分需要更新,并只對(duì)更新的部分進(jìn)行對(duì)應(yīng)的DOM操作,從而提高了渲染效率。
?Reconciliation:當(dāng)組件狀態(tài)或?qū)傩园l(fā)生變化時(shí),React需要調(diào)用Reconciliation算法來決定哪些DOM節(jié)點(diǎn)需要更新以及如何更新。Reconciliation算法的基本流程包括比較新舊Virtual DOM的根節(jié)點(diǎn),判斷是否可以復(fù)用,以及根據(jù)節(jié)點(diǎn)的類型和屬性進(jìn)行更新或替換。React采用遞歸遍歷的方式來比較新舊Virtual DOM,這也是為什么更新操作不適合過于頻繁的原因,因?yàn)檫f歸遍歷是一個(gè)高消耗的操作。
React的渲染流程可以大致分為兩個(gè)階段:render階段和commit階段。
?render階段:在這個(gè)階段,React會(huì)調(diào)合(reconcile)虛擬DOM,計(jì)算出最終要渲染出來的虛擬DOM。這個(gè)過程包括生成Fiber對(duì)象、收集副作用、找出哪些節(jié)點(diǎn)發(fā)生了變化,并打上不同的flags。Diff算法也是在這個(gè)階段執(zhí)行的。render階段的工作都是在內(nèi)存中進(jìn)行的,計(jì)算出更新后的Fiber樹,但在這個(gè)階段并沒有更新UI,視圖不會(huì)有任何更改。
?commit階段:在這個(gè)階段,React會(huì)根據(jù)上一步計(jì)算出來的虛擬DOM,同步地渲染具體的UI。渲染器(Renderer)會(huì)根據(jù)協(xié)調(diào)器(Reconciler)計(jì)算出來的虛擬DOM,同步地渲染節(jié)點(diǎn)到視圖上。這個(gè)過程是同步執(zhí)行的,不可以被打斷。
React的渲染原理通過Virtual DOM和Reconciliation算法,以及調(diào)度器、協(xié)調(diào)器和渲染器的協(xié)同工作,實(shí)現(xiàn)了高效、可靠的UI更新。
小程序渲染原理
小程序(這里以微信小程序?yàn)槔?,其它大同小異)的渲染原理主要如下?/p>
?微信小程序采用了雙線程模型,將渲染和邏輯處理分離到不同的線程中,從而提高了渲染速度和效率。具體來說,渲染層負(fù)責(zé)頁面的渲染和繪制工作,而邏輯層則負(fù)責(zé)處理小程序的業(yè)務(wù)邏輯和數(shù)據(jù)處理。
?渲染層:負(fù)責(zé)將WXML模板和WXSS樣式解析并生成最終的頁面。渲染層會(huì)構(gòu)建DOM樹和樣式表,并通過底層的圖形系統(tǒng)進(jìn)行繪制和顯示;
?邏輯層:使用獨(dú)立的JSCore作為運(yùn)行環(huán)境,執(zhí)行小程序的JavaScript代碼,處理用戶的輸入和事件,并更新頁面的狀態(tài)。邏輯層與渲染層之間通過特定的通信機(jī)制進(jìn)行數(shù)據(jù)傳輸和事件通知。
渲染流程主要包括解析和編譯、預(yù)加載、頁面渲染和繪制與顯示,具體如下:
?解析和編譯?:當(dāng)用戶打開小程序時(shí),小程序框架首先對(duì)小程序的代碼進(jìn)行解析和編譯。這一過程包括將小程序的代碼轉(zhuǎn)換成可執(zhí)行的指令,并生成對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu),如頁面樹和組件樹。解析和編譯過程需要消耗一定的時(shí)間,但在后續(xù)的頁面渲染中能夠大大提高效率。
??預(yù)加載?:在解析和編譯完成后,小程序框架進(jìn)行預(yù)加載。預(yù)加載是指在用戶進(jìn)入具體頁面之前,提前加載可能需要使用的資源,如圖片、樣式文件等。通過預(yù)加載,小程序能夠在用戶切換頁面時(shí)減少加載時(shí)間,提高渲染速度。
??頁面渲染?:當(dāng)用戶進(jìn)入具體頁面時(shí),小程序框架將頁面樹和組件樹渲染到屏幕上。渲染過程包括計(jì)算每個(gè)組件的位置和尺寸、應(yīng)用樣式和布局,并生成最終的繪制指令。
?繪制與顯示?:小程序框架將渲染得到的繪制指令交給底層的圖形系統(tǒng)進(jìn)行繪制。圖形系統(tǒng)會(huì)將指令轉(zhuǎn)換成圖像,并顯示在屏幕上。
微信小程序的渲染原理是一個(gè)基于雙線程模型的高效渲染過程,通過渲染層和邏輯層的分離與協(xié)同工作,實(shí)現(xiàn)了頁面的快速渲染和流暢的用戶體驗(yàn)。
ReactNative渲染原理
React Native是基于React技術(shù)棧開發(fā)跨平臺(tái)移動(dòng)應(yīng)用的一種框架;React Native的渲染原理主要涉及JavaScript線程與原生線程的交互,以及React的Virtual DOM(虛擬DOM)機(jī)制。其渲染原理如下:
?JavaScript線程與原生線程的交互:React Native在JavaScript線程中運(yùn)行JavaScript代碼,包括React組件的渲染邏輯;當(dāng)JavaScript線程計(jì)算出需要進(jìn)行UI更新時(shí),這些更新會(huì)被序列化并通過一個(gè)叫做Bridge的機(jī)制發(fā)送給原生線程;原生線程接收到更新后,會(huì)負(fù)責(zé)實(shí)際的UI繪制和更新操作,包括創(chuàng)建和更新原生UI組件。
?Virtual DOM機(jī)制:React Native利用React的Virtual DOM機(jī)制來優(yōu)化UI的更新;當(dāng)組件的狀態(tài)或?qū)傩园l(fā)生變化時(shí),React Native會(huì)在JavaScript線程中創(chuàng)建一個(gè)新的Virtual DOM樹;然后,React Native會(huì)使用Diff算法比較新舊Virtual DOM樹的差異,找出需要更新的部分;只有差異部分會(huì)被通過Bridge發(fā)送給原生線程進(jìn)行更新,從而減少了數(shù)據(jù)傳輸量,提高了性能。
React Native的渲染流程主要包括以下幾個(gè)步驟:
?組件渲染:在JavaScript線程中,React Native組件的render方法會(huì)被調(diào)用,生成對(duì)應(yīng)的Virtual DOM描述。這個(gè)描述會(huì)被React的渲染系統(tǒng)用來構(gòu)建組件樹。
?Diff算法比較:當(dāng)組件的狀態(tài)或?qū)傩园l(fā)生變化時(shí),React Native會(huì)使用Diff算法比較新舊Virtual DOM樹的差異。這個(gè)過程會(huì)找出需要更新的部分,并準(zhǔn)備相應(yīng)的更新指令。
?數(shù)據(jù)序列化與傳輸:更新指令會(huì)被序列化為原生線程可理解的數(shù)據(jù)格式。然后,這些數(shù)據(jù)會(huì)通過Bridge機(jī)制發(fā)送給原生線程。
?原生UI更新:原生線程接收到更新指令后,會(huì)解析這些指令并應(yīng)用到實(shí)際的UI控件上。這包括創(chuàng)建新的原生UI組件、更新現(xiàn)有組件的屬性或移除不再需要的組件等。
?渲染結(jié)果展示:經(jīng)過原生線程的處理后,UI的更新會(huì)實(shí)時(shí)反映在移動(dòng)設(shè)備的屏幕上。用戶可以看到最新的界面效果,并根據(jù)需要進(jìn)行進(jìn)一步的交互。
React Native的渲染原理和主要流程通過JavaScript線程與原生線程的緊密協(xié)作,以及Virtual DOM和Diff算法的優(yōu)化,實(shí)現(xiàn)了在JavaScript中編寫UI代碼并在App原生環(huán)境中高效渲染的能力。這種機(jī)制不僅提高了應(yīng)用的性能,還降低了跨平臺(tái)開發(fā)的復(fù)雜性和成本。
Flutter渲染原理
Flutter是Google推出的開源UI框架,主要用于多平臺(tái)的應(yīng)用開發(fā)。其渲染原理是構(gòu)建跨平臺(tái)應(yīng)用的關(guān)鍵部分,主要基于其獨(dú)特的三層樹結(jié)構(gòu):Widget樹、Element樹和RenderObject樹(或稱為渲染樹)。這三層結(jié)構(gòu)的設(shè)計(jì)旨在優(yōu)化性能,減少不必要的重繪和重建。
?Widget樹:Widget是Flutter中用戶界面的不可變描述,是構(gòu)成Flutter應(yīng)用程序的基本元素。Widget樹是存放渲染內(nèi)容的配置數(shù)據(jù)結(jié)構(gòu),創(chuàng)建非常輕量,在頁面刷新的過程中隨時(shí)會(huì)重建。
?Element樹:Element是Widget樹和RenderObject樹之間的中間層,負(fù)責(zé)將Widget樹的變化抽象化,并管理RenderObject的復(fù)用。Element持有Widget的引用,并可以對(duì)其屬性進(jìn)行修改,而不是完全重建整個(gè)樹。
?RenderObject樹(渲染樹):RenderObject樹用于應(yīng)用界面的布局和繪制,保存了元素的大小、布局等信息。RenderObject的創(chuàng)建和銷毀相對(duì)耗能,因此Element樹會(huì)緩存RenderObject對(duì)象,以便在需要時(shí)復(fù)用。
Flutter的渲染流程主要包括以下幾個(gè)階段:
?構(gòu)建(Build):Flutter框架根據(jù)Widget樹中的變化調(diào)用每個(gè)Widget的build方法;build方法返回一個(gè)新的Widget,表示當(dāng)前Widget的最新狀態(tài);此階段主要確定哪些Widget需要更新。
?布局(Layout):在構(gòu)建階段之后,F(xiàn)lutter框架執(zhí)行布局過程;為每個(gè)需要更新的Widget確定其在屏幕上的位置和大??;調(diào)用每個(gè)Widget的layout方法,根據(jù)其約束條件(如最大寬度、最小高度等)計(jì)算出最佳的位置和大小。
?繪制(Paint):布局階段完成后,F(xiàn)lutter框架執(zhí)行繪制過程;根據(jù)每個(gè)Widget的布局信息將其繪制到屏幕上;調(diào)用每個(gè)Widget的paint方法,將Widget的內(nèi)容繪制到一個(gè)離屏的Canvas上。
?合成(Compositing):在繪制階段完成后,F(xiàn)lutter框架執(zhí)行合成過程;將所有已繪制的Canvas組合成最終的顯示圖像;調(diào)用每個(gè)Widget的compositing方法,將它們的繪制結(jié)果合并到一起。
?顯示(Display):合成階段完成后,F(xiàn)lutter框架將最終的顯示圖像發(fā)送給硬件,將其顯示在屏幕上。
綜上所述,F(xiàn)lutter的渲染原理通過三層樹結(jié)構(gòu)的設(shè)計(jì)和優(yōu)化,實(shí)現(xiàn)了高效、流暢的跨平臺(tái)應(yīng)用界面渲染。
Taro渲染原理
Taro框架的核心思想是通過將Vue或React中編寫的代碼進(jìn)行抽象和統(tǒng)一規(guī)范,然后映射到不同的平臺(tái)上,通過組件化的方式實(shí)現(xiàn)統(tǒng)一代碼覆蓋多個(gè)平臺(tái)。這種方式大大提高了代碼的復(fù)用率和開發(fā)效率。主要如下:
?統(tǒng)一抽象規(guī)范:Taro框架定義了一套跨平臺(tái)的組件、事件、CSS樣式等規(guī)范,使得在編寫React代碼時(shí),能夠通過這些抽象出來的規(guī)范來編寫,從而實(shí)現(xiàn)跨平臺(tái)的兼容性。
?代碼轉(zhuǎn)換:Taro框架為不同的平臺(tái)提供對(duì)應(yīng)的代碼轉(zhuǎn)換工具,將抽象的React代碼轉(zhuǎn)換為應(yīng)該在目標(biāo)平臺(tái)上運(yùn)行的代碼。這一步驟是Taro實(shí)現(xiàn)跨平臺(tái)渲染的關(guān)鍵。
?統(tǒng)一API:將不同平臺(tái)上的API進(jìn)行兼容性處理和封裝,使得在不同平臺(tái)上的開發(fā)人員都可以通過同樣的API進(jìn)行開發(fā)。這樣做不僅降低了開發(fā)難度,還提高了開發(fā)效率。
?差異化處理:針對(duì)不同的平臺(tái)特性,Taro框架進(jìn)行了特定平臺(tái)的定制化開發(fā),充分利用不同平臺(tái)的特性,提供更多豐富的功能支持。這種差異化處理使得Taro框架在不同平臺(tái)上都能發(fā)揮出最佳的性能。
而渲染技術(shù)主要包括以下幾個(gè)方面:
?虛擬DOM:React或Vue使用虛擬DOM來提高頁面渲染的性能。虛擬DOM是在內(nèi)存中維護(hù)的一個(gè)輕量級(jí)的JavaScript對(duì)象樹,它表示了真實(shí)的DOM結(jié)構(gòu)。通過比較新舊虛擬DOM的差異,然后只更新實(shí)際DOM中需要改變的部分,從而避免不必要的DOM操作,提高渲染效率。
?事件處理:Taro框架對(duì)事件處理進(jìn)行了跨平臺(tái)封裝,使得開發(fā)者可以使用統(tǒng)一的API來處理不同平臺(tái)上的事件。這種封裝方式簡化了事件處理的復(fù)雜度,提高了開發(fā)效率。
?Prerender技術(shù):Prerender是由Taro CLI提供的一種技術(shù),用于提高小程序頁面初始化的渲染速度。它通過將頁面初始化的狀態(tài)直接渲染為無狀態(tài)的wxml,在框架和業(yè)務(wù)邏輯運(yùn)行之前執(zhí)行渲染流程,從而提高頁面的加載速度。Prerender技術(shù)的實(shí)現(xiàn)原理與服務(wù)端渲染類似,但它是針對(duì)小程序端進(jìn)行的優(yōu)化。
Taro框架的渲染原理主要基于React或Vue的跨平臺(tái)渲染技術(shù),通過統(tǒng)一抽象規(guī)范、代碼轉(zhuǎn)換、統(tǒng)一API和差異化處理等手段實(shí)現(xiàn)代碼的跨平臺(tái)復(fù)用和高效渲染;Taro還提供了Prerender等技術(shù)來優(yōu)化頁面加載速度,提升用戶體驗(yàn)?;谶@些技術(shù)使得Taro框架成為了一個(gè)功能強(qiáng)大、易用、跨平臺(tái)兼容的開發(fā)框架。
瀏覽器的渲染原理
瀏覽器的渲染原理是一個(gè)復(fù)雜的過程,涉及到多個(gè)組件和線程的協(xié)作,才能確保網(wǎng)頁能夠正確、快速地顯示在用戶面前。瀏覽器渲染原理主要如下:
?瀏覽器的主要組件
?界面控件:包括地址欄、前進(jìn)后退按鈕、書簽菜單等,這些是用戶與瀏覽器交互的界面部分。
?瀏覽器引擎:它是瀏覽器的核心,負(fù)責(zé)協(xié)調(diào)各個(gè)組件的工作,處理用戶的請(qǐng)求和操作。
?渲染引擎:它負(fù)責(zé)解析HTML、CSS,構(gòu)建DOM樹和Render樹,最終將網(wǎng)頁內(nèi)容呈現(xiàn)給用戶。
?網(wǎng)絡(luò)組件:它負(fù)責(zé)發(fā)送HTTP請(qǐng)求,獲取網(wǎng)頁資源。
?JS解釋器:它用于解析執(zhí)行JavaScript代碼,實(shí)現(xiàn)網(wǎng)頁的動(dòng)態(tài)效果。
?數(shù)據(jù)存儲(chǔ)持久層:它用于存儲(chǔ)cookies、localStorage等數(shù)據(jù)。
?瀏覽器的多進(jìn)程架構(gòu)
?隔離性:每個(gè)標(biāo)簽頁運(yùn)行在獨(dú)立的進(jìn)程中,避免了一個(gè)標(biāo)簽頁崩潰影響到其他標(biāo)簽頁。
?安全性:不同進(jìn)程之間不共享資源和地址空間,減少了安全隱患。
?瀏覽器的主要線程
?GUI渲染線程:它負(fù)責(zé)渲染瀏覽器界面HTML元素,當(dāng)界面需要重繪或回流時(shí),該線程會(huì)執(zhí)行。
?JavaScript引擎線程:它負(fù)責(zé)解析執(zhí)行JavaScript代碼,與GUI渲染線程互斥,確保DOM操作的安全。
?定時(shí)觸發(fā)器線程:它負(fù)責(zé)計(jì)時(shí)并觸發(fā)定時(shí)事件。
?事件觸發(fā)線程:它將事件添加到待處理隊(duì)列中,等待JS引擎處理。
?異步http請(qǐng)求線程:它負(fù)責(zé)處理XMLHttpRequest請(qǐng)求,將狀態(tài)變更事件放入JS引擎的處理隊(duì)列中。
?渲染流程
?解析HTML,構(gòu)建DOM樹:當(dāng)用戶輸入網(wǎng)址或點(diǎn)擊鏈接時(shí),瀏覽器會(huì)向服務(wù)器發(fā)送請(qǐng)求,獲取網(wǎng)頁的HTML文件。瀏覽器開始解析HTML文件,將其轉(zhuǎn)換為瀏覽器能夠理解和操作的文檔對(duì)象模型(DOM)樹。DOM樹是由HTML標(biāo)簽和它們的層級(jí)關(guān)系組成的樹狀結(jié)構(gòu),表示了網(wǎng)頁的結(jié)構(gòu)和內(nèi)容。
?樣式計(jì)算(CSSOM樹構(gòu)建與渲染樹生成):CSSOM樹構(gòu)建,瀏覽器解析CSS文件或
審核編輯 黃宇 標(biāo)簽中的樣式信息,將其轉(zhuǎn)換為瀏覽器能夠理解的樣式表對(duì)象模型(CSSOM)樹。CSSOM樹表示了文檔中所有元素的樣式信息。渲染樹生成:瀏覽器將DOM樹和CSSOM樹合并,形成渲染樹(Render Tree)。渲染樹是DOM樹的一個(gè)可視化表示,只包含需要顯示的節(jié)點(diǎn)和這些節(jié)點(diǎn)的樣式信息。
?布局:瀏覽器根據(jù)渲染樹中的信息,計(jì)算每個(gè)節(jié)點(diǎn)的幾何信息(如位置、大小等),并生成布局樹(Layout Tree)。布局階段會(huì)確定頁面上所有元素的位置和大小,確保它們能夠按照預(yù)期的方式排列。
?分層:為了更高效地渲染頁面,瀏覽器會(huì)對(duì)布局樹進(jìn)行分層處理,生成分層樹(LayerTree)。擁有層疊上下文屬性(如定位屬性、透明屬性、CSS濾鏡、z-index等)的元素會(huì)被提升為單獨(dú)的圖層。分層有助于瀏覽器進(jìn)行并行繪制,減少重繪和重排的開銷。
?繪制:瀏覽器遍歷分層樹中的每個(gè)圖層,使用圖形庫將圖層的內(nèi)容繪制成圖像。繪制階段會(huì)生成一個(gè)繪制列表,該列表包含了繪制每個(gè)元素所需的指令和順序。繪制操作是由渲染引擎中的合成線程來完成的。
?合成顯示:合成線程將圖層劃分為圖塊(tile),并將圖塊轉(zhuǎn)換為位圖(通過柵格化操作)。柵格化操作通常使用GPU來加速生成位圖。一旦所有圖塊都被柵格化,合成線程就會(huì)生成一個(gè)繪制圖塊的命令(DrawQuad),并將該命令提交給瀏覽器進(jìn)程。瀏覽器進(jìn)程根據(jù)DrawQuad命令生成頁面,并將其顯示到屏幕上。
?交互處理:當(dāng)用戶與頁面進(jìn)行交互(點(diǎn)擊、滾動(dòng)、輸入等)時(shí),瀏覽器會(huì)更新渲染樹,并重新進(jìn)行布局和繪制。
瀏覽器的渲染原理是涉及資源的加載、解析、構(gòu)建DOM和CSSOM樹、布局、繪制、合成以及交互處理等多個(gè)步驟;涉及多線程處理、緩存機(jī)制、?DNS解析、?TCP連接等,確保了網(wǎng)頁的快速、穩(wěn)定、高效渲染。
它們的相同點(diǎn)與不同點(diǎn)
?相同點(diǎn)
?層次結(jié)構(gòu):所有技術(shù)棧都基于某種形式的樹狀結(jié)構(gòu)來管理UI組件。
?測(cè)量和布局:渲染過程通常包含測(cè)量、布局、繪制階段。
?更新機(jī)制:大多數(shù)框架都采用某種形式的Diff算法來優(yōu)化DOM更新,以提高性能。
?不同點(diǎn)
?運(yùn)行環(huán)境不同:APP運(yùn)行在操作系統(tǒng)之上,具有更高的權(quán)限和更豐富的系統(tǒng)資源;H5頁面是基于瀏覽器渲染,受到瀏覽器沙箱模型的限制;小程序受到宿主環(huán)境類瀏覽器環(huán)境的限制。
?渲染機(jī)制不同:APP渲染通常涉及到底層的圖形渲染接口(如Skia、OpenGL等),可以直接與GPU交互;而瀏覽器渲染則主要依賴于HTML、CSS和JavaScript等前端技術(shù),并通過瀏覽器引擎(如Blink、Gecko等)進(jìn)行渲染。iOS和Android利用GPU進(jìn)行硬件加速渲染,大大提升復(fù)雜UI的繪制性能。Web前端如Vue和React采用虛擬DOM和Diff算法來更新UI。小程序等跨平臺(tái)框架通常需要在邏輯層與視圖層之間進(jìn)行橋接通信。Web和小程序通常依賴瀏覽器或宿主環(huán)境的渲染引擎。
?性能優(yōu)化不同:APP渲染可以利用操作系統(tǒng)的特性進(jìn)行更深入的性能優(yōu)化(如硬件加速、內(nèi)存管理等);而瀏覽器渲染則受到瀏覽器引擎和前端技術(shù)的限制,在性能優(yōu)化上可能相對(duì)較弱。
?跨平臺(tái)性不同:APP需要針對(duì)不同的操作系統(tǒng)和設(shè)備進(jìn)行開發(fā)和適配;而瀏覽器渲染則具有更好的跨平臺(tái)性,可以在不同的瀏覽器和設(shè)備上運(yùn)行。
?協(xié)同渲染:鴻蒙OS的分布式UI能力允許跨設(shè)備協(xié)同渲染,而其他框架通常只在單個(gè)設(shè)備上進(jìn)行渲染。
綜上所述,APP渲染、H5頁面渲染、小程序渲染在多個(gè)方面存在多個(gè)區(qū)別。這些區(qū)別源于它們不同的運(yùn)行環(huán)境、渲染機(jī)制、性能優(yōu)化和跨平臺(tái)性等因素。
隨著技術(shù)的發(fā)展,大前端的各種技術(shù)棧不斷涌現(xiàn),各自發(fā)展出了適合自身特性的渲染機(jī)制。不同技術(shù)棧在各自的應(yīng)用領(lǐng)域都有獨(dú)特的優(yōu)勢(shì)和適用場(chǎng)景,我們根據(jù)項(xiàng)目需求和團(tuán)隊(duì)情況選擇合適的技術(shù)棧,可以更高效地實(shí)現(xiàn)高性能的UI和良好的用戶體驗(yàn)。
審核編輯 黃宇
-
Android
+關(guān)注
關(guān)注
12文章
3935瀏覽量
127339 -
gpu
+關(guān)注
關(guān)注
28文章
4729瀏覽量
128890 -
前端
+關(guān)注
關(guān)注
1文章
192瀏覽量
17748 -
代碼
+關(guān)注
關(guān)注
30文章
4779瀏覽量
68521 -
DOM
+關(guān)注
關(guān)注
0文章
18瀏覽量
9572
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論