摘要:你可以使用這個技術在構建時間生成。谷歌實際上是在年開始抓取素材的,這個算法現在已經可以完美地工作了。閉包在無處不不在,并且你可能一直使用到它,即使你還沒有注意到。但是你在方法中使用閉包時,它確實是不好的。
原文:5 common practices that you can stop doing in React
從下面這點來說,很難說React是這個星球上最受歡迎的庫之一。很多人對React感興趣,新的開發者之所以傾向于使用這個框架的原因是因為它的UI優先方法。雖然這些年React和它的整個生態已經比較成熟,但是在某些情況下你仍然會這樣問自己:“正確的做法到底是什么?”
這是一個好問題--并不總是有一個通用的“正確”的做事方式。事實上,正如你所知,最佳實踐并不總是那么的適用。長遠來看,其中的某些寫法可能會影響性能,可讀性,并導致效率低下。
在本文中,我將描述在React開發中5種被普遍接受的寫法,但是實際上你是可以避免這樣做的。當然,我將解釋為什么我認為這些做法是可以避免的,并且我會建議你用其他的寫法來完成相同的事情。
從一開始就優化ReactReact的開發人員在如何使React更快投入了大量的精力,每次迭代新的優化方法又會被添加進去。在我看來,你不應該花費時間優化這些東西,除非你發現了真正的性能影響。
為什么?
React相比其它的前端平臺更容易擴展,因為你不必重寫某個模塊來加快應用的速度。導致性能問題的罪魁禍首通常是React使用更新虛擬DOM的reconciliation過程。
讓我們看一下React是如何處理下面的事情的。在每個render()中,React生成了一個由UI元素組成的樹——子節點是實際的DOM元素。當state或者props更新的時候,React需要使用最小的改變次數來生成一個新的樹,并保持可預測性。
想象一下,你看到的樹是這個樣子的:
想象一下,你的應用接收到新的數據,下列的節點需要被更新:
React通常會重新渲染整個子樹,而不是像這樣僅僅渲染相關節點:
當頂層組件的state發生改變的時候,它的子元素都會重新渲染。這是默認的行為,在小型應用中不需要擔心。隨著應用的逐漸擴展,您應該考慮使用Chrome Profiling工具來測量實際性能。這個工具將為你提供在不必要的渲染上所浪費時間的精確數據。如果這些數據很重要,你可以通過向你的組件中添加shouldComponentUpdate鉤子來優化你的渲染時間。
這個鉤子在重新渲染開始之前將被觸發,默認返回true:
shouldComponentUpdate(nextProps, nextState) { return true; }
當返回true時,React的diff算法接管并重新渲染整個子樹。你能避免這樣的情況發生,通過在shouldComponentUpdate中添加比較邏輯,并且僅當相關的props發生改變的時候更新邏輯。
shouldComponentUpdate(nextProps, nextState) { if (this.props.color !== nextProps.color) { return true; } if (this.state.count !== nextState.count) { return true; } return false; }
除了color/count,其它任何props/state改變,這個組件都不會更新。
除此之外,還有一些開發人員通常忽略的non-React優化技巧,但它們會影響應用程序的性能。
我將在下面列舉一些可以避免的習慣和解決方案:
未優化的圖片--如果你的應用中有很多動態圖片,你需要在處理圖片時考慮你的選項。較大的圖片可能會給用戶一種應用很慢的印象。在將圖片推入服務器之前壓縮圖片,或者使用動態圖片處理解決方案來替代。我個人喜歡Cloudinary來優化react圖片因為它有它自己的react庫,但是你也可以使用Amazon S3或者Firebase。
未壓縮的構建文件--Gzipping構建文件(bundle.js)可以有效的減少文件大小。你需要修改webserver的配置文件。Webpack有一個gzip壓縮插件,叫做compression-webpack-plugin。你可以使用這個技術在構建時間生成bundle.js.gz。
服務端渲染的SEO雖然單頁面應用非常棒,但是他們仍然存在兩個問題。
當應用首次加載的時候,瀏覽器中沒有JavaScript緩存。如果應用很大,首次加載應用的時間將會很慢。
由于應用程序是在客戶端進行渲染,搜索引擎使用的web爬蟲程序將無法索引JavaScript生成的內容。搜索引擎將看到你的應用是空白的,然后排名很差。
這就是服務端渲染技術派上用處的地方。在SSR中,JavaScript內容最初是由服務器渲染的。在首次渲染后,客戶端的腳本接管,并像一個正常的SPA應用運行。由于你需要使用Node/Express服務,因此在以傳統SSR進行構建時復雜度和花費更高。
如果你是為了搜索引擎優化、谷歌索引和沒有任何問題地抓取JavaScript內容,那么有一個好消息。谷歌實際上是在2016年開始抓取JavaScript素材的,這個算法現在已經可以完美地工作了。
以下是2015年10月Webmaster博客的節選。
今天,只要你不阻止Googlebot抓取你的JavaScript或CSS文件,我們就能像現代瀏覽器一樣渲染和理解你的網頁。為了反映這一改進,我們最近更新了我們的技術站長指南,建議不要禁止Googlebot抓取你網站的CSS或JS文件。
如果你使用服務器端渲染,是因為你擔心你的谷歌頁面排名,那么你不需要使用SSR。它曾經是過去的事,但現在不是了。
然而,如果你正在改善首次渲染速度,那么你應該嘗試使用像Next.js這樣的庫來實現更加簡單的SSR。Next將節省你在設置Node/Express 服務所花費的時間。
Inline styles和CSS imports在使用React做開發時,我曾親自嘗試過多種不同的樣式理念,為了能找到一種新的引入樣式到React組件的方式。在React組件中使用已經存在多年的傳統的CSS-in-CSS 方法。你的樣式表全部樣放在一個樣式表目錄,然后你可以將所需要的CSS導入到你的組件中。
然而,當你使用這些組件的時候,樣式表不再清晰明了。React鼓勵你以組件化的方式來思考你的應用,然而樣式表則強迫你以文檔的角度來思考。
目前有多種方法將CSS和JS代碼合并到一個文件中。內聯樣式可能是其中最流行的。
const divStyle = { margin: "40px", border: "5px solid pink" }; const pStyle = { fontSize: "15px", textAlign: "center" }; const TextBox = () => (); export default TextBox;Yeah!
你不需要再導入CSS,但是這會犧牲可讀性和可維護性。除了這樣做,內聯樣式不支持媒體查詢,偽元素以及樣式回退。當然,有一些技巧可以讓你解決上述問題,但是使用起來卻并不方便。
這就是CSS-in-JSS派上用處的地方,內聯樣式并不完全是CSS-in-JSS。下面的代碼演示了使用styled-components的概念。
import styled from "styled-components"; const Text = styled.div` color: white, background: black `This is CSS-in-JS
在瀏覽器中看上去是這樣的:
This is CSS-in-JS
新的標簽被添加到了頂層的DOM中,不像內聯樣式,實際的CSS樣式在這里生成。所以,任何能在CSS運行的東西,在樣式組件中也能工作。此外,這個技術還增強了CSS,改善了可讀性并且適用到組件的架構中。使用styled-components 庫,你還可以得到SASS的支持。
嵌套的條件運算符條件運算符在React中很常用。它是我用來創建狀態語句的go-to操作符,在render()方法中得到了很好的應用。例如,在下列中它們幫助你以內聯的方式渲染元素,我使用它來顯示登入狀態。
render() { const isLoggedIn = this.state.isLoggedIn; return (The user is {isLoggedIn ? "currently" : "not"} logged in.); }
然而,當你一次又一次的嵌套條件運算符,它們可能變的丑陋并且難以閱讀。
int median(int a, int b, int c) { return (a如你所見,速記符號更加的簡潔,但是它們往往會使代碼看起混亂。想象一下如果在你的結構中有12個或者更多嵌套的條件運算符。這比你所認為的要常發生。一旦開始使用條件運算符,就很容易繼續嵌套它,最后,您會發現需要一種更好的技術來處理狀態渲染。
但好的方面是你有很多其它的選擇。你可以使用增強JSX控制語句的babel插件,用來擴展JSX以包含用于條件語句和循環的組件。
// before transformationTruth // after transformation { test ? Truth : null }這里有另外一個流行的技術叫做iify(IIFE--立即執行函數表達式)。它是一個在聲明之后會立即執行的匿名函數。
(function() { // Do something? } )()為了使匿名函數成為函數表達式,我們將函數封裝在一對括號中。這個模式在JavaScript中很流行,原因有很多。但是在React里,我們可以把所有if/else語句放到函數中,然后返回我們想要渲染的內容。
這里有一個例子演示我們怎樣在React中使用IFFE。
{ (() => { if (this.props.status === "PENDING") { return (); } else { return (); })() }IIFE可能對性能有所影響,但是在大多數情況下不會有太大的影響。這里有更多的方法來運行React中的條件語句,并且我們已經在用于React中狀態渲染的8個方法中有所說明。
在React中的閉包閉包是一個獲取外部函數變量和參數的內部函數。閉包在JavaScript無處不不在,并且你可能一直使用到它,即使你還沒有注意到。
class SayHi extends Component { render () { return () { } } }但是你在render()方法中使用閉包時,它確實是不好的。每當SayHi組件重新渲染,新的匿名會被重新創建并傳入到Button組件中。雖然porps沒有改變,但是 將被強制重新渲染。正如前面所言,重復的渲染會直接帶來性能的損耗。
因此,使用類方法來代替閉包。類方法可讀性更高并且更容易調試。
class SayHi extends Component { showHiMessage = this.showMessage("Hi") render () { return () { } } }結論當一個平臺逐漸擴大,每天都會出現新的模式。一些模式幫助你改善整個工作流程。而其它的一些方式則會有明顯的副作用。當副作用影響應用的性能的時候或者可讀性時,最好是尋找替代方案。在本文中,我介紹了一些因為它們的缺點,你可以在React中避免的做法。
您對React的看法和最佳做法是什么?在評論中分享它們。(想看評論直接去原文看吧)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/97076.html
摘要:為了使用它們,您可以向組件添加一個屬性,該屬性的值是一個回調函數,它將接收底層的元素或組件的已掛接實例,作為其第一個參數。通常最好使用另一個生命周期方法,而不是依賴這個回調函數,但是很高興知道它存在。 React 常見的面試題 (在 React 里面,你可以知道也可以不知道的事, 但是你會發現他們確實很有用) 根據記錄,問這些問題可能不是深入了解他們在使用 React 方面的經驗的最...
摘要:在中由于業務的需要我們往往要在諸多的頁面間,組件之間做一些參數的傳遞與管理在這里我總結了幾大經過驗證,穩定好用的方式給大家導航傳值推薦指數適用范圍相鄰頁面間傳值兼容性原理為頁面的上掛載了對象可用來做路由跳轉,在做頁面跳轉時可以攜帶參數回調方 在React Native 中由于業務的需要, 我們往往要在諸多的頁面間,組件之間做一些參數的傳遞與管理, 在這里我總結了幾大經過驗證,穩定好用的...
摘要:中只有的作用域是動態作用域的五種綁定初學時,會想當然認為遵循某一條規律,就像物理學那樣,然而并不是。的綁定分為五種情況,這五種情況之間毫無規律可言。以至指向更加撲朔迷離。 this 到底指向哪里 以下如果沒提及,則為嚴格模式。 js中作用域有兩種: 詞法作用域 動態作用域 詞法作用域 詞法作用域指在書寫代碼時就被確定的作用域。看如下代碼 var value = 1; ...
摘要:數據結構和算法樹快速排序,堆排序,插入排序其實八大排序算法都應該了解一致性算法,一致性算法的應用的內存結構。如何存儲一個的。八大排序算法一定要手敲一遍快排,堆排尤其重要。面試是一個雙向選擇的過程,不要抱著畏懼的心態去面試,不利于自己的發揮。 前言 16年畢業到現在也近兩年了,最近面試了阿里集團(菜鳥網絡,螞蟻金服),網易,滴滴,點我達,最終收到點我達,網易offer,螞蟻金服二面掛掉,...
閱讀 1354·2023-04-25 15:21
閱讀 2687·2021-11-24 10:23
閱讀 3409·2021-10-11 10:59
閱讀 3261·2021-09-03 10:28
閱讀 1739·2019-08-26 13:45
閱讀 2332·2019-08-26 12:11
閱讀 930·2019-08-26 12:00
閱讀 1718·2019-08-26 10:44