今天看了篇有关前端应用程序性能优化的文章,文章内容写得很 ok。文章是twitter写的,内容关于 twitter lite 如何优化。
总结下来大概是这么几点:
-
学会用 chrome devtools 分析应用程序的性能
-
添加基于路由的细粒度代码拆分
-
改写造成 jank(理解为抖动)的函数
-
使用小一点的图片
-
优化 React 代码
-
充分使用 shouldComponentUpdate method(没有必要更新的就不要去更新就好了,比如 twitter 里面的 like,一点一下 like,刷新这个就够了,其他的不要去动)
-
将没有必要不着急不关键的工作丢到 componentDidMount之后
-
避免危险的dangerouslySetInnerHtml. (we get about an average of 60% savings each time we need to mount and render one of these sets of icons!)
const HeartIcon = (props) => React.createElement('svg', { ...props, dangerouslySetInnerHTML: { __html: '<g><path d="M38.723 12c-7.187 0-11.16 7.306-11.723 8.131C26.437 19.306 22.504 12 15.277 12 8.791 12 3.533 18.163 3.533 24.647 3.533 39.964 21.891 55.907 27 56c5.109-.093 23.467-16.036 23.467-31.353C50.467 18.163 45.209 12 38.723 12z"></path></g>' }, viewBox: '0 0 54 72' });
-
当挂载与卸载许多组件的时候延迟 rendering (在 React 挂载和卸载大型的组件树 花销是非常大的)
import hoistStatics from 'hoist-non-react-statics'; import React from 'react'; /** * Allows two animation frames to complete to allow other components to update * and re-render before mounting and rendering an expensive `WrappedComponent`. */ export default function deferComponentRender(WrappedComponent) { class DeferredRenderWrapper extends React.Component { constructor(props, context) { super(props, context); this.state = { shouldRender: false }; } componentDidMount() { window.requestAnimationFrame(() => { window.requestAnimationFrame(() => this.setState({ shouldRender: true })); }); } render() { return this.state.shouldRender ? <WrappedComponent {...this.props} /> : null; } } return hoistStatics(DeferredRenderWrapper, WrappedComponent); } const DeferredTimeline = deferComponentRender(HomeTimeline); render(<DeferredTimeline />);
-
-
优化 Redux
- 避免过于频繁的存储状态(输入受控是推荐的,但是输入受到控制意味着每一个按键的更新和呈现都要改变 state)。也就是说,不是所有的组件都要走 redux ,能走到 react 的组件的 state 里面的,就没必要走到 redux 里面,这样利于组件性能的优化。
- 将 actions 打包到一个 action 里面
-
预缓存资源
-
延迟 serviceworker 注册
总得来说,这些只是 twitter 团队在 twitter lite 里面的一些改进。优化 React、PWA 的方式还有很多。。。慢慢学吧。