资讯专栏INFORMATION COLUMN

在React中你可以停止使用这五种常见写法

idisfkj / 2973人阅读

摘要:你可以使用这个技术在构建时间生成。谷歌实际上是在年开始抓取素材的,这个算法现在已经可以完美地工作了。闭包在无处不不在,并且你可能一直使用到它,即使你还没有注意到。但是你在方法中使用闭包时,它确实是不好的。

原文:5 common practices that you can stop doing in React

从下面这点来说,很难说React是这个星球上最受欢迎的库之一。很多人对React感兴趣,新的开发者之所以倾向于使用这个框架的原因是因为它的UI优先方法。虽然这些年React和它的整个生态已经比较成熟,但是在某些情况下你仍然会这样问自己:“正确的做法到底是什么?”

这是一个好问题--并不总是有一个通用的“正确”的做事方式。事实上,正如你所知,最佳实践并不总是那么的适用。长远来看,其中的某些写法可能会影响性能,可读性,并导致效率低下。

在本文中,我将描述在React开发中5种被普遍接受的写法,但是实际上你是可以避免这样做的。当然,我将解释为什么我认为这些做法是可以避免的,并且我会建议你用其他的写法来完成相同的事情。

从一开始就优化React

React的开发人员在如何使React更快投入了大量的精力,每次迭代新的优化方法又会被添加进去。在我看来,你不应该花费时间优化这些东西,除非你发现了真正的性能影响。

为什么?

React相比其它的前端平台更容易扩展,因为你不必重写某个模块来加快应用的速度。导致性能问题的罪魁祸首通常是React使用更新虚拟DOMreconciliation过程。

让我们看一下React是如何处理下面的事情的。在每个render()中,React生成了一个由UI元素组成的树——子节点是实际的DOM元素。当state或者props更新的时候,React需要使用最小的改变次数来生成一个新的树,并保持可预测性。

想象一下,你看到的树是这个样子的:

想象一下,你的应用接收到新的数据,下列的节点需要被更新:

React通常会重新渲染整个子树,而不是像这样仅仅渲染相关节点:

当顶层组件的state发生改变的时候,它的子元素都会重新渲染。这是默认的行为,在小型应用中不需要担心。随着应用的逐渐扩展,您应该考虑使用Chrome Profiling工具来测量实际性能。这个工具将为你提供在不必要的渲染上所浪费时间的精确数据。如果这些数据很重要,你可以通过向你的组件中添加shouldComponentUpdate钩子来优化你的渲染时间。

这个钩子在重新渲染开始之前将被触发,默认返回true:

shouldComponentUpdate(nextProps, nextState) {
  return true;
}

当返回true时,Reactdiff算法接管并重新渲染整个子树。你能避免这样的情况发生,通过在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这样的库来实现更加简单的SSRNext将节省你在设置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 = () => (
  

Yeah!

); export default TextBox;

你不需要再导入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

新的