<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] > **首先說明,這里討論的是 WebKit,描述的是 Chrome 的實現細節,而并非是 web 平臺的功能,因此這里介紹的內容不一定適用于其他瀏覽器。** > * Chrome 擁有兩套不同的渲染路徑(rendering path):硬件加速路徑和舊軟件路徑(older software path) > * Chrome 中有不同類型的層: RenderLayer(負責 DOM 子樹)和GraphicsLayer(負責 RenderLayer的子樹),只有 GraphicsLayer 是作為紋理(texture)上傳給GPU的。 > * 什么是紋理?可以把它想象成一個從主存儲器(例如 RAM)移動到圖像存儲器(例如 GPU 中的 VRAM)的位圖圖像(bitmapimage) > * Chrome 使用紋理來從 GPU上獲得大塊的頁面內容。通過將紋理應用到一個非常簡單的矩形網格就能很容易匹配不同的位置(position)和變形(transformation)。這也就是3DCSS 的工作原理,它對于快速滾動也十分有效。 # 渲染原理 一個 Web 頁面的展示,簡單來說可以認為經歷了以下下幾個步驟。 ![](https://img.alicdn.com/tps/TB1eabOLpXXXXX3XFXXXXXXXXXX-1093-167.jpg_720x720.jpg) * JavaScript:一般來說,我們會使用 JavaScript 來實現一些視覺變化的效果。比如做一個動畫或者往頁面里添加一些 DOM 元素等。 * Style:計算樣式,這個過程是根據 CSS 選擇器,對每個 DOM 元素匹配對應的 CSS 樣式。這一步結束之后,就確定了每個 DOM 元素上該應用什么 CSS 樣式規則。 * Layout:布局,上一步確定了每個 DOM 元素的樣式規則,這一步就是具體計算每個 DOM 元素最終在屏幕上顯示的大小和位置。web 頁面中元素的布局是相對的,因此一個元素的布局發生變化,會聯動地引發其他元素的布局發生變化。比如,`<body>`元素的寬度的變化會影響其子元素的寬度,其子元素寬度的變化也會繼續對其孫子元素產生影響。因此對于瀏覽器來說,布局過程是經常發生的。 * Paint:繪制,本質上就是填充像素的過程。包括繪制文字、顏色、圖像、邊框和陰影等,也就是一個 DOM 元素所有的可視效果。一般來說,這個繪制過程是在多個層上完成的。 * Composite:渲染層合并,由上一步可知,對頁面中 DOM 元素的繪制是在多個層上進行的。在每個層上完成繪制過程之后,瀏覽器會將所有層按照合理的順序合并成一個圖層,然后顯示在屏幕上。對于有位置重疊的元素的頁面,這個過程尤其重要,因為一旦圖層的合并順序出錯,將會導致元素顯示異常。 ![](https://box.kancloud.cn/3acbfdd9c60d21cb151b93f26bb438e1_650x268.png) 在 Chrome 中其實有幾種不同的層類型: * RenderLayers 渲染層,這是負責對應 DOM 子樹 * GraphicsLayers 圖形層,這是負責對應 RenderLayers子樹。 在瀏覽器渲染流程中提到了composite概念,在 DOM 樹中每個節點都會對應一個 LayoutObject,當他們的 LayoutObject 處于相同的坐標空間時,就會形成一個 RenderLayers ,也就是渲染層。RenderLayers 來保證頁面元素以正確的順序合成,這時候就會出現層合成(composite),從而正確處理透明元素和重疊元素的顯示。 某些特殊的渲染層會被認為是合成層(Compositing Layers),合成層擁有單獨的 GraphicsLayer,而其他不是合成層的渲染層,則和其第一個擁有 GraphicsLayer 父層公用一個。 而每個GraphicsLayer(合成層單獨擁有的圖層) 都有一個 GraphicsContext,GraphicsContext 會負責輸出該層的位圖,位圖是存儲在共享內存中,作為紋理上傳到 GPU 中,最后由 GPU 將多個位圖進行合成,然后顯示到屏幕上。 # 如何變成合成層 * 3D 或透視變換(perspective transform) CSS 屬性 * 使用加速視頻解碼的 元素 擁有 3D * (WebGL) 上下文或加速的 2D 上下文的 元素 * 混合插件(如 Flash) * 對自己的 opacity 做 CSS動畫或使用一個動畫變換的元素 * 擁有加速 CSS 過濾器的元素 * 元素有一個包含復合層的后代節點(換句話說,就是一個元素擁有一個子元素,該子元素在自己的層里) * 元素有一個z-index較低且包含一個復合層的兄弟元素(換句話說就是該元素在復合層上面渲染) # 合成層的優點 一旦renderLayer提升為了合成層就會有自己的繪圖上下文,并且會開啟硬件加速,有利于性能提升,里面列舉了一些特點 * 合成層的位圖,會交由 GPU 合成,比 CPU 處理要快 * 當需要 repaint 時,只需要 repaint 本身,不會影響到其他的層 * 對于 transform 和 opacity 效果,不會觸發 layout 和 paint **注意:** 1. 提升到合成層后合成層的位圖會交GPU處理,但請注意,僅僅只是合成的處理(把繪圖上下文的位圖輸出進行組合)需要用到GPU,生成合成層的位圖處理(繪圖上下文的工作)是需要CPU。 2. 當需要repaint的時候可以只repaint本身,不影響其他層,但是paint之前還有style, layout,那就意味著即使合成層只是repaint了自己,但style和layout本身就很占用時間。 3. 僅僅是transform和opacity不會引發layout 和paint,那么其他的屬性不確定。 總結合成層的優勢:一般一個元素開啟硬件加速后會變成合成層,可以獨立于普通文檔流中,改動后可以避免整個頁面重繪,提升性能。 **性能優化點:** 1. 提升動畫效果的元素 合成層的好處是不會影響到其他元素的繪制,因此,為了減少動畫元素對其他元素的影響,從而減少paint,我們需要把動畫效果中的元素提升為合成層。`提升合成層的最好方式是使用 CSS 的 will-change屬性。從上一節合成層產生原因中,可以知道 will-change 設置為opacity、transform、top、left、bottom、right 可以將元素提升為合成層。` 2. 使用 transform 或者 opacity 來實現動畫效果, 這樣只需要做合成層的合并就好了。 3. 減少繪制區域 對于不需要重新繪制的區域應盡量避免繪制,以減少繪制區域,比如一個 fix 在頁面頂部的固定不變的導航header,在頁面內容某個區域 repaint 時,整個屏幕包括 fix 的 header 也會被重繪。`而對于固定不變的區域,我們期望其并不會被重繪,因此可以通過之前的方法,將其提升為獨立的合成層。減少繪制區域,需要仔細分析頁面,區分繪制區域,減少重繪區域甚至避免重繪。` # 利用合成層可能踩到的坑 1. 合成層占用內存的問題 2. 層爆炸,由于某些原因可能導致產生大量不在預期內的合成層,雖然有瀏覽器的層壓縮機制,但是也有很多無法進行壓縮的情況,這就可能出現層爆炸的現象(簡單理解就是,很多不需要提升為合成層的元素因為某些不當操作成為了合成層)。解決層爆炸的問題,最佳方案是打破 overlap 的條件,也就是說讓其他元素不要和合成層元素重疊。簡單直接的方式:`使用3D硬件加速提升動畫性能時,最好給元素增加一個z-index屬性,人為干擾合成的排序,可以有效減少chrome創建不必要的合成層,提升渲染性能,移動端優化效果尤為明顯。 # 在chrome查看渲染層 其實在chrome中,也為我們提供了相關插件供我們查看頁面渲染層的分布情況以及GPU的占用率: * chrome開發者工具菜單→more tools→Layers(開啟渲染層功能模塊) * chrome開發者工具菜單→more tools→rendering(開啟渲染性能監測工具) 執行上面的操作后,你會在瀏覽器里看到這樣的效果: ![](https://box.kancloud.cn/9a18098f413231505f91301e0812e734_1920x951.png) * 最先是頁面右上方的小黑窗:其實提示已經說的很清楚了,它顯示的就是我們的GPU占用率,能夠讓我們清楚地知道頁面是否發生了大量的重繪。 * Layers版塊:這就是用于顯示我們剛提到的DOM渲染層的工具了,左側的列表里將會列出頁面里存在哪些渲染層,還有這些渲染層的詳細信息。 * Rendering版塊:這個版塊和我們的控制臺在同一個地方,大家可別找不到它。 前三個勾選項是我們最常使用的 * Paint flashing:勾選之后會對頁面中發生重繪的元素高亮顯示 * Layer borders:和我們的Layer版塊功能類似,它會用高亮邊界突出我們頁面中的各個渲染層 * FPS meter:就是開啟我們在(一)中提到的小黑窗,用于觀察我們的GPU占用率 # 參考資料 [瀏覽器渲染流程&Composite(渲染層合并)簡單總結](https://segmentfault.com/a/1190000014520786) [前端性能優化之 Composite](https://segmentfault.com/a/1190000014520786)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看