摘要:你可以使用这个技术在构建时间生成。谷歌实际上是在年开始抓取素材的,这个算法现在已经可以完美地工作了。闭包在无处不不在,并且你可能一直使用到它,即使你还没有注意到。但是你在方法中使用闭包时,它确实是不好的。
原文: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的看法和最佳做法是什么?在评论中分享它们。(想看评论直接去原文看吧)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/97076.html
摘要:为了使用它们,您可以向组件添加一个属性,该属性的值是一个回调函数,它将接收底层的元素或组件的已挂接实例,作为其第一个参数。通常最好使用另一个生命周期方法,而不是依赖这个回调函数,但是很高兴知道它存在。 React 常见的面试题 (在 React 里面,你可以知道也可以不知道的事, 但是你会发现他们确实很有用) 根据记录,问这些问题可能不是深入了解他们在使用 React 方面的经验的最...
摘要:在中由于业务的需要我们往往要在诸多的页面间,组件之间做一些参数的传递与管理在这里我总结了几大经过验证,稳定好用的方式给大家导航传值推荐指数适用范围相邻页面间传值兼容性原理为页面的上挂载了对象可用来做路由跳转,在做页面跳转时可以携带参数回调方 在React Native 中由于业务的需要, 我们往往要在诸多的页面间,组件之间做一些参数的传递与管理, 在这里我总结了几大经过验证,稳定好用的...
摘要:中只有的作用域是动态作用域的五种绑定初学时,会想当然认为遵循某一条规律,就像物理学那样,然而并不是。的绑定分为五种情况,这五种情况之间毫无规律可言。以至指向更加扑朔迷离。 this 到底指向哪里 以下如果没提及,则为严格模式。 js中作用域有两种: 词法作用域 动态作用域 词法作用域 词法作用域指在书写代码时就被确定的作用域。看如下代码 var value = 1; ...
摘要:数据结构和算法树快速排序,堆排序,插入排序其实八大排序算法都应该了解一致性算法,一致性算法的应用的内存结构。如何存储一个的。八大排序算法一定要手敲一遍快排,堆排尤其重要。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。 前言 16年毕业到现在也近两年了,最近面试了阿里集团(菜鸟网络,蚂蚁金服),网易,滴滴,点我达,最终收到点我达,网易offer,蚂蚁金服二面挂掉,...
阅读 1220·2023-04-25 15:21
阅读 2619·2021-11-24 10:23
阅读 3361·2021-10-11 10:59
阅读 3202·2021-09-03 10:28
阅读 1697·2019-08-26 13:45
阅读 2269·2019-08-26 12:11
阅读 887·2019-08-26 12:00
阅读 1670·2019-08-26 10:44