react 中渲染html_如何在React中識別和解決浪費的渲染

react 中渲染html

by Nayeem Reza

通過Nayeem Reza

如何在React中識別和解決浪費的渲染 (How to identify and resolve wasted renders in React)

So, recently I was thinking about performance profiling of a react app that I was working on, and suddenly thought to set a few performance metrics. And I did come across that the first thing I need to tackle is wasted renders I’m doing in each of the webpages. You might be thinking about what are wasted renders by the way? Let’s dive down in.

因此,最近,我正在考慮對正在使用的React應用進行性能分析,并突然想到設置一些性能指標。 我確實發現,我需要解決的第一件事是在每個網頁中執行的渲染浪費 。 您可能正在考慮哪些浪費的渲染? 讓我們深入。

From the beginning, React has changed the whole philosophy of building web apps and subsequently the way front-end developers think. With its introduction of Virtual DOM, React makes UI updates as efficient as they can ever be. This makes the web app experience neat. Have you ever wondered how to make your React applications faster? Why do moderately sized React web apps still tend to perform poorly? The problems lie in how we are actually using React!

從一開始,React就改變了構建Web應用程序的整個哲學,并隨后改變了前端開發人員的思維方式。 通過引入Virtual DOM ,React使UI更新盡可能高效。 這使Web應用程序體驗更簡潔。 您是否曾經想過如何使您的React應用程序更快? 為什么中等大小的React Web應用仍然表現不佳? 問題在于我們如何實際使用React!

React如何工作 (How React works)

A modern front-end library like React doesn’t make our app faster wondrously. First, we developers should understand how React works. How do the components live through the component lifecycles in the applications lifetime? So, before we dive into any optimization technique, we need to have a better understanding of how React actually works under the hood.

像React這樣的現代前端庫并不能使我們的應用程序更快地運轉。 首先,我們的開發人員應該了解React的工作方式。 組件在應用程序生命周期中如何在組件生命周期中生存? 因此,在我們深入研究任何優化技術之前,我們需要更好地了解React在幕后的實際工作方式。

At the core of React, we have the JSX syntax and React’s powerful ability to build and compare virtual DOMs. Since its release, React has influenced many other front-end libraries. For example, Vue.js also relies on the idea of virtual DOMs.

作為React的核心,我們擁有JSX語法和React強大的能力來構建和比較虛擬DOM 。 自發布以來,React已經影響了許多其他前端庫。 例如,Vue.js也依賴于虛擬DOM的想法。

Each React application begins with a root component. We can think of the whole application as a tree formation where every node is a component. Components in React are ‘functions’ that render the UI based on the data. That means props and state it receives; say that is CF

每個React應用程序都以一個根組件開始。 我們可以將整個應用程序視為樹狀結構,其中每個節點都是一個組件。 React中的組件是“功能”,它們基于數據呈現UI。 這意味著道具和它收到的狀態 。 說那是CF

UI = CF(data)

Users interact with the UI and cause the change in data. The interactions are anything a user can do in our application. For example, clicking a button, sliding images, dragging list items around, and AJAX requests invoking APIs. All those interactions only change the data. They never cause any change in the UI.

用戶與UI交互并導致數據更改。 用戶可以在我們的應用程序中進行任何交互。 例如,單擊按鈕,滑動圖像,拖動列表項,以及AJAX請求調用API。 所有這些交互只會更改數據。 它們永遠不會導致UI發生任何變化。

Here, data is everything that defines the state of an application. Not just what we have stored in our database. Even different front-end states like which tab is currently selected or whether a checkbox is currently checked or not are part of this data. Whenever there is a change in data, React uses the component functions to re-render the UI, but only virtually:

在這里,數據就是定義應用程序狀態的所有內容。 不只是我們存儲在數據庫中的內容。 甚至不同的前端狀態(例如當前選中哪個選項卡或當前是否選中復選框)也屬于此數據。 每當數據發生變化時,React都會使用組件函數來重新渲染UI,但實際上只是:

UI1 = CF(data1)UI2 = CF(data2)

React computes the differences between the current UI and the new UI by applying a comparison algorithm on the two versions of its virtual DOM.

React通過在其虛擬DOM的兩個版本上應用比較算法來計算當前UI和新UI之間的差異。

Changes = Difference(UI1, UI2)

React then proceeds to apply only the UI changes to the real UI on the browser. When the data associated with a component changes, React determines if an actual DOM update is required. This allows React to avoid potentially expensive DOM manipulation operations in the browser. Examples such as creating DOM nodes and accessing existing ones beyond necessity.

然后,React繼續將僅UI更改應用于瀏覽器上的實際UI。 當與組件關聯的數據更改時,React會確定是否需要實際的DOM更新。 這使得React可以避免瀏覽器中潛在的昂貴DOM操作操作。 諸如創建DOM節點和訪問現有節點等不必要的示例。

This repeated differentiating and rendering of components can be one of the primary sources of React performance issues in any React app. Building a React app where the differentiating algorithm fails to reconcile effectively, causing the entire app to be rendered repeatedly which is actually causing wasted renders and that can result in a frustratingly slow experience.

組件的這種重復區分和渲染可能是任何React應用程序中React性能問題的主要來源之一。 在差異化算法無法有效協調的情況下構建React應用程序,導致整個應用程序被重復渲染,這實際上導致浪費的渲染,并可能導致令人沮喪的緩慢體驗。

During the initial render process, React builds a DOM tree like this —

在初始渲染過程中,React會像這樣構建DOM樹-

Suppose that a part of the data changes. What we want React to do is re-render only the components that are directly affected by that specific change. Possibly skip even the differentiating process for the rest of the components. Let’s say some data changes in Component 2 in the above picture, and that data has been passed from R to B and then 2. If R re-renders then it’ll re-render each of its children that means A, B, C, D and by this process what actually React does is this:

假設一部分數據發生了變化。 我們希望React要做的是僅重新渲染受該特定更改直接影響的組件。 甚至可以跳過其余組件的區分過程。 假設上圖中的組件2中有一些數據更改,并且該數據已從R傳遞到B ,然后傳遞到2 。 如果R重新渲染,那么它將重新渲染它的每個子元素,這意味著A,B,C,D,并且通過此過程,React實際執行的操作是:

In the image above, all the yellow nodes are rendered and differentiated. This results in wasted time/computation resources. This is where we will primarily put our optimization efforts. Configuring each component to only render and differentiate when it is necessary. This will allow us to reclaim those wasted CPU cycles. First, we’ll take a look into the way that we can identify wasted renders of our application.

在上圖中,所有黃色節點都被渲染和區分。 這導致浪費時間/計算資源。 這是我們主要進行優化工作的地方。 配置每個組件以僅在必要時進行渲染和區分。 這將使我們能夠回收那些浪費的CPU周期。 首先,我們將研究確定應用程序浪費的渲染的方式。

識別浪費的渲染 (Identify wasted renders)

There are a few different ways to do this. The simplest method is to toggle on the highlight updates option in the React dev tools preference.

有幾種不同的方法可以做到這一點。 最簡單的方法是在React開發工具首選項中打開突出顯示更新選項。

While interacting with the app, updates are highlighted on the screen with colored borders. By this process, you should see components that have re-rendered. This lets us spot re-renders that were not necessary.

與應用程序交互時,更新會在屏幕上以彩色邊框突出顯示。 通過此過程,您應該看到已重新渲染的組件。 這使我們可以發現不必要的重新渲染。

Let’s follow this example.

讓我們跟隨這個例子。

Note that when we’re entering a second todo, the first ‘todo’ also flashes on the screen on every keystroke. This means it is being re-rendered by React together with the input. This is what we are calling a “wasted” render. We know it is unnecessary because the first todo content has not changed, but React doesn’t know this.

請注意,當我們輸入第二個待辦事項時,每次按鍵時,第一個“待辦事項”也會在屏幕上閃爍。 這意味著它將由React與輸入一起重新渲染。 這就是我們所謂的“浪費”渲染。 我們知道這是沒有必要的,因為第一個待辦事項內容沒有更改,但是React不知道這一點。

Even though React only updates the changed DOM nodes, re-rendering still takes some time. In many cases, it’s not a problem, but if the slowdown is noticeable, we should consider a few things to stop those redundant renders.

即使React僅更新已更改的DOM節點,但重新渲染仍需要一些時間。 在很多情況下,這不是問題,但是如果速度下降明顯,我們應該考慮一些事情來停止那些多余的渲染。

使用shouldComponentUpdate方法 (Using shouldComponentUpdate method)

By default, React will render the virtual DOM and compare the difference for every component in the tree for any change in its props or state. But that is obviously not reasonable. As our app grows, attempting to re-render and compare the entire virtual DOM at every action will eventually slow the whole thing down.

默認情況下,React將渲染虛擬DOM并比較樹中每個組件的差異,以了解其屬性或狀態的任何變化。 但這顯然是不合理的。 隨著我們的應用程序的增長,在每次操作時嘗試重新渲染和比較整個虛擬DOM最終都會使整個過程變慢。

React provides a simple lifecycle method to indicate if a component needs re-rendering and that is, shouldComponentUpdate which is triggered before the re-rendering process starts. The default implementation of this function returns true.

React提供了一個簡單的生命周期方法來指示組件是否需要重新渲染,即應該在重新渲染過程開始之前觸發的shouldComponentUpdate 。 該函數的默認實現返回true

When this function returns true for any component, it allows the render differentiating process to be triggered. This gives us the power of controlling the render differentiating process. Suppose we need to prevent a component from being re-rendered, we need simply to return false from that function. As we can see from the implementation of the method, we can compare the current and next props and state to determine whether a re-render is necessary:

當此函數對任何組件返回true時,它將允許渲染區分過程被觸發。 這使我們能夠控制渲染差異化過程。 假設我們需要防止組件被重新渲染,我們只需要從該函數返回false即可。 從該方法的實現中可以看出,我們可以比較當前和下一個道具和狀態,以確定是否需要重新渲染:

使用純組件 (Using pure components)

As you work on React you definitely know about React.Component but what’s the deal with React.PureComponent? We’ve already discussed shouldComponentUpdate lifecycle method, in pure components, there is already a default implementation of, shouldComponentUpdate() with a shallow prop and state comparison. So, a pure component is a component that only re-renders if props/state is different from the previous props and state.

在工作過程中上React你肯定知道React.Component但什么是該交易的React.PureComponent ? 我們已經討論了shouldComponentUpdate生命周期方法,在純組件中,已經有默認的shouldComponentUpdate()實現,帶有淺層shouldComponentUpdate()和狀態比較。 因此,純組件是僅在props/state與先前的propsstate不同的情況下才重新渲染的組件。

In shallow comparison, primitive data-types like string, boolean, number are being compared by value and complex data-types like array, object, function are compared by reference
在淺層比較中,原始數據類型(例如字符串,布爾值,數字)通過值進行比較,而復雜數據類型(例如數組,對象,函數)通過??引用進行比較

But, what if we have a functional stateless component in which we need to implement that comparison method before each re-rendering happens? React has a Higher Order Component React.memo. It is like React.PureComponent but for functional components instead of classes.

但是,如果我們有一個功能性的無狀態組件,該組件需要在每次重新渲染發生之前實現該比較方法,該怎么辦? React有一個更高階的組件React.memo 。 它類似于React.PureComponent但用于功能組件而不是類。

By default, it does the same as shouldComponentUpdate() which only shallowly compares the props object. But, if we want to have control over that comparison? We can also provide a custom comparison function as the second argument.

默認情況下,它的作用與shouldComponentUpdate()相同,后者僅淺層比較props對象。 但是,如果我們想控制該比較? 我們還可以提供自定義比較功能作為第二個參數。

使數據不變 (Making Data Immutable)

What if we could use a React.PureComponent but still have an efficient way of telling when any complex props or states like an array, object, etc. have changed automatically? This is where the immutable data structure makes life easier.

如果我們可以使用React.PureComponent但仍然有一種有效的方式來告知任何復雜的道具或狀態(例如數組,對象等)何時自動更改怎么辦? 這是不可變數據結構使生活更輕松的地方。

The idea behind using immutable data structures is simple. As we’ve discussed earlier, for complex data-types the comparison performs over their reference. Whenever an object containing complex data changes, instead of making the changes in that object, we can create a copy of that object with the changes which will create a new reference.

使用不可變數據結構的想法很簡單。 如前所述,對于復雜的數據類型,比較將在其引用上進行。 每當包含復雜數據的對象發生更改時,我們無需在該對象中進行更改,而可以使用更改創建該對象的副本,這將創建一個新引用。

ES6 has object spreading operator to make this happen.

ES6具有對象散布算子以實現此目的。

We can do the same for arrays too:

我們也可以對數組做同樣的事情:

避免為相同的舊數據傳遞新的引用 (Avoid passing a new reference for the same old data)

We know that whenever the props for a component changes, a re-render happens. But sometimes the props didn’t change. We write code in a way that React thinks it did change, and that’ll also cause a re-render but this time it’s a wasted render. So, basically, we need to make sure that we’re passing a different reference as props for different data. Also, we need to avoid passing a new reference for the same data. Now, we’ll look into some cases where we’re creating this problem. Let’s look at this code.

我們知道,每當props的成分變化,重新繪制發生。 但是有時候props沒有變。 我們以React認為確實有所改變的方式編寫代碼,這也會導致重新渲染,但是這次是浪費的渲染。 因此,基本上,我們需要確保傳遞不同的參考作為支持不同數據的道具。 同樣,我們需要避免傳遞相同數據的新引用。 現在,我們將研究造成這種問題的某些情況。 讓我們看一下這段代碼。

Here’s the content for the BookInfo component where we’re rendering two components, BookDescription and BookReview. This is the correct code, and it works fine but there is a problem. BookDescription will re-render whenever we get new reviews data as props. Why? As soon as the BookInfo component receives new props, the render function is called to create its element tree. The render function creates a new book constant that means a new reference is created. So, BookDescription will get this book as a news reference, that’ll cause the re-render of BookDescription. So, we can refactor this piece of code to this:

這是BookInfo組件的內容,我們在其中渲染兩個組件BookDescriptionBookReview 。 這是正確的代碼,可以正常工作,但是存在問題。 每當我們獲得新的評論數據作為道具時, BookDescription將重新呈現。 為什么? 一旦BookInfo組件收到新的道具,就會調用render函數來創建其元素樹。 render函數創建一個新的book常量,這意味著將創建一個新的引用。 因此, BookDescription將把這book作為新聞參考,這將導致BookDescription的重新呈現。 因此,我們可以將這段代碼重構為:

Now, the reference is always the same, this.book and a new object isn’t created at render time. This re-rendering philosophy applies to every prop including event handlers, like:

現在,引用始終是相同的, this.book和渲染時不會創建新對象。 這種重新渲染的理念適用于包括事件處理程序在內的每個prop ,例如:

Here, we’ve used two different ways (binding methods and using arrow function in render) to invoke the event-handler methods but both will create a new function every time the component re-renders. So, to fix these issues, we can bind the method in the constructor and using class properties which is still in experimental and not standardized yet but so many devs are already using this method of passing functions to other components in production ready applications:

在這里,我們使用了兩種不同的方式(綁定方法和在render中使用arrow函數)來調用事件處理程序方法,但是每次組件重新渲染時,這兩種方法都會創建一個新函數。 因此,要解決這些問題,我們可以將方法綁定到constructor并使用仍在實驗中且尚未標準化的類屬性,但是許多開發人員已經在使用此方法將功能傳遞給生產就緒應用程序中的其他組件:

結語 (Wrapping up)

Internally, React uses several clever techniques to minimize the number of costly DOM operations required to update the UI. For many applications, using React will lead to a fast user interface without doing much work to optimize for performance specifically. Nevertheless, if we can follow the techniques I’ve mentioned above to resolve wasted renders then for large applications we’ll also get a very smooth experience in terms of performance.

在內部,React使用幾種巧妙的技術來最小化更新UI所需的昂貴的DOM操作的數量。 對于許多應用程序而言,使用React將導致快速的用戶界面,而無需進行大量工作來專門針對性能進行優化。 但是,如果我們可以遵循上面提到的技術來解決浪費的渲染,那么對于大型應用程序,我們還將在性能方面獲得非常流暢的體驗。

翻譯自: https://www.freecodecamp.org/news/how-to-identify-and-resolve-wasted-renders-in-react-cc4b1e910d10/

react 中渲染html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/391769.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/391769.shtml
英文地址,請注明出處:http://en.pswp.cn/news/391769.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php變量的數據類型

一、類型 標量類型: 布爾型 整型 浮點型 字符串 復合類型: 數組 對象 特殊類型: 資源 null 1. 布爾型 true false 以下值認為是false 其他值都認為是true; 布爾值false 整型值0 浮點的0 空字符串和字符串0 空數組 空對象(只適用于php4) 特殊類型null 2. 整型 正整數和負整…

[習題].FindControl()方法 與 PlaceHolder控件 #2(動態加入「子控件」的事件)

這是我的文章備份,有空請到我的網站走走, http://www.dotblogs.com.tw/mis2000lab/ 才能掌握我提供的第一手信息,謝謝您。 http://www.dotblogs.com.tw/mis2000lab/archive/2011/07/26/placeholder_findcontrol_eventhandler.aspx [習題].Fi…

西雅圖治安_數據科學家對西雅圖住宿業務的分析

西雅圖治安介紹 (Introduction) Airbnb provides an online platform for hosts to accommodate guests with short-term lodging. Guests can search for lodging using filters such as lodging type, dates, location, and price, and can search for specific types of hom…

leetcode 1438. 絕對差不超過限制的最長連續子數組(滑動窗口+treemap)

給你一個整數數組 nums ,和一個表示限制的整數 limit,請你返回最長連續子數組的長度,該子數組中的任意兩個元素之間的絕對差必須小于或者等于 limit 。 如果不存在滿足條件的子數組,則返回 0 。 示例 1: 輸入&#…

react-redux圖解_如何將React連接到Redux —圖解指南

react-redux圖解by Princiya由Princiya 如何將React連接到Redux —圖解指南 (How to connect React to Redux — a diagrammatic guide) This post is aimed at people who already know React and Redux. This will aid them in better understanding how things work under …

幾種機器學習算法的優缺點

1決策樹(Decision Trees)的優缺點 決策樹的優點: 一、 決策樹易于理解和解釋.人們在通過解釋后都有能力去理解決策樹所表達的意義。 二、 對于決策樹,數據的準備往往是簡單或者是不必要的.不需要預處理數據。…

【貪心】買賣股票的最佳時機含手續費

/** 貪心:每次選取更低的價格買入,遇到高于買入的價格就出售(此時不一定是最大收益)。* 使用buy表示買入股票的價格和手續費的和。遍歷數組,如果后面的股票價格加上手續費* 小于buy,說明有更低的買入價格更新buy。如…

本科畢設論文——基于Kinect的拖拉機防撞系統

基于Kinect的拖拉機防撞系統電子信息科學與技術專業學生 sukeysun 摘要:隨著智能車輛技術的發展,智能導航定位和實時車載監控等技術被更多的應用到日常生活照。在農業領域上,車輛自主感知道路環境并制定實時避障策略還存在不足,特…

排序算法Java代碼實現(二)—— 冒泡排序

本篇內容: 冒泡排序冒泡排序 算法思想: 冒泡排序的原理是:從左到右,相鄰元素進行比較。 每次比較一輪,就會找到序列中最大的一個或最小的一個。這個數就會從序列的最右邊冒出來。 代碼實現: /*** */ packag…

創意產品 分析_使用聯合分析來發展創意

創意產品 分析Advertising finds itself in a tenacious spot these days serving two masters: creativity and data.如今,廣告業處于一個頑強的位置,服務于兩個大師:創造力和數據。 On the one hand, it values creativity; and it’s not…

leetcode 劍指 Offer 05. 替換空格

請實現一個函數,把字符串 s 中的每個空格替換成"%20"。 示例 1: 輸入:s “We are happy.” 輸出:“We%20are%20happy.” 解題思路 一次遍歷,檢查空格,然后替換 代碼 class Solution {publ…

兩個富翁打賭_打賭您無法解決這個Google面試問題。

兩個富翁打賭by Kevin Ghadyani通過凱文加迪亞尼(Kevin Ghadyani) 打賭您無法解決這個Google面試問題。 (Bet you can’t solve this Google interview question.) 將棘手的問題分解為小塊。 (Breaking tough problems into small pieces.) I wanted to see someone else’s t…

vue.js 安裝

寫 一個小小的安裝步驟 踩坑過來的 點擊.然后安裝cnpm.再接著使用文章說明繼續安裝 # 全局安裝 vue-cli $ cnpm install --global vue-cli # 創建一個基于 webpack 模板的新項目 $ vue init webpack my-project這時候一路空格 選項.當遇到第一個讓你敲 Y/N 的時候 選擇Y …

Swift 的函數和閉包

函數的關鍵字是 func ,函數定義的格式是: func funcName(para:paraType) -> returnType{// code } 復制代碼函數的參數標簽 其中參數的那部分的詳細結構是用小括號括起來,參數名,冒號,參數類型: (number…

pandas之表格樣式

在juoyter notebook中直接通過df輸出DataFrame時&#xff0c;顯示的樣式為表格樣式&#xff0c;通過sytle可對表格的樣式做一些定制&#xff0c;類似excel的條件格式。 df pd.DataFrame(np.random.rand(5,4),columns[A,B,C,D]) s df.style print(s,type(s)) #<pandas.io.f…

多層感知機 深度神經網絡_使用深度神經網絡和合同感知損失的能源產量預測...

多層感知機 深度神經網絡in collaboration with Hsu Chung Chuan, Lin Min Htoo, and Quah Jia Yong.與許忠傳&#xff0c;林敏濤和華佳勇合作。 1. Introduction1.簡介 Since the early 1990s, several countries, mostly in the European Union and North America, had sta…

ajax跨域

//遠程的地址1.通過header頭實現ajax跨域PHP文件的代碼$origin isset($_SERVER[HTTP_ORIGIN])? $_SERVER[HTTP_ORIGIN] : ; $allow_origin array(http://www.example.com, http://www.example2.com);if(in_array($origin, $allow_origin)){ header(Access-Control-Allow-Ori…

java線程并發庫之--線程同步工具CountDownLatch用法

CountDownLatch&#xff0c;一個同步輔助類&#xff0c;在完成一組正在其他線程中執行的操作之前&#xff0c;它允許一個或多個線程一直等待。 主要方法 public CountDownLatch(int count); public void countDown(); public void await() throws InterruptedException 構造方法…

leetcode 766. 托普利茨矩陣

給你一個 m x n 的矩陣 matrix 。如果這個矩陣是托普利茨矩陣&#xff0c;返回 true &#xff1b;否則&#xff0c;返回 false 。 如果矩陣上每一條由左上到右下的對角線上的元素都相同&#xff0c;那么這個矩陣是 托普利茨矩陣 。 輸入&#xff1a;matrix [[1,2,3,4],[5,1,…

藍牙調試工具如何使用_使用此有價值的工具改進您的藍牙項目:第2部分!

藍牙調試工具如何使用This post is originally from www.jaredwolff.com. 這篇文章最初來自www.jaredwolff.com。 This is Part 2 of configuring your own Bluetooth Low Energy Service using a Nordic NRF52 series processor. If you haven’t seen Part 1 go back and ch…