You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
/ ... /
coryhouse / reactjsconsulting / Issues #77 /
Clear Command Palette
Tip:
Type # to search pull requests
Type ? for help and tips
Tip:
Type # to search issues
Type ? for help and tips
Tip:
Type # to search discussions
Type ? for help and tips
Tip:
Type ! to search projects
Type ? for help and tips
Tip:
Type @ to search teams
Type ? for help and tips
Tip:
Type @ to search people and organizations
Type ? for help and tips
Tip:
Type > to activate command mode
Type ? for help and tips
Tip:
Go to your accessibility settings to change your keyboard shortcuts
Type ? for help and tips
Tip:
Type author:@me to search your content
Type ? for help and tips
Tip:
Type is:pr to filter to pull requests
Type ? for help and tips
Tip:
Type is:issue to filter to issues
Type ? for help and tips
Tip:
Type is:project to filter to projects
Type ? for help and tips
Tip:
Type is:open to filter to open content
Type ? for help and tips
We’ve encountered an error and some results aren't available at this time. Type a new search or try again later.
No results matched your search
Top result
Commands
Type > to filter
Global Commands
Type > to filter
This Page
Files
Pages
Access Policies
Organizations
Repositories
Issues, pull requests, and discussions
Type # to filter
Teams
Users
Projects
Projects (classic)
Modes
Use filters in issues, pull requests, discussions, and projects
Search for issues and pull requests#Search for issues, pull requests, discussions, and projects#Search for organizations, repositories, and users@Search for projects!Search for files/Activate command mode>Search your issues, pull requests, and discussions# author:@meSearch your issues, pull requests, and discussions# author:@meFilter to pull requests# is:prFilter to issues# is:issueFilter to discussions# is:discussionFilter to projects# is:projectFilter to open issues, pull requests, and discussions# is:open
Analyze performance via the React dev tools.
通过 React 开发工具分析性能。
Use React dev tools "Highlight Updates" to see what's re-rendering. Then be strategic.
使用 React 开发工具 "突出显示更新 "来查看重新渲染的内容。然后采取策略。
Ask: why is this component re-rendering? 问:为什么这个组件要重新渲染?
Ask: Could I avoid passing the prop that's causing it to re-render? Could it access this data via Context instead to avoid passing it through intermediate components that don't need it? 问:我能否避免传递导致重新渲染的道具?是否可以通过 "上下文 "访问这些数据,以避免通过不需要这些数据的中间组件?
Use console.time like this, against the prod build, to measure slowness and compare to a before and after to determine if useMemo is a net win: console.time('filter array'); const visibleTodos = getFilteredTodos(todos, filter); console.timeEnd('filter array'); 像这样使用 console.time ,与原型构建对比,测量速度慢的程度,并与之前和之后进行比较,以确定 useMemo 是否净赢: console.time('filter array'); const visibleTodos = getFilteredTodos(todos, filter); console.timeEnd('filter array');
functionExpensiveTree(){letnow=performance.now();while(performance.now()-now<100){// Artificial delay -- do nothing for 100ms}return<p>I am a very slow component tree.</p>;}
Consider uncontrolled components for large, expensive forms. In other words, Handle state in each input. Here is my approach which was loosely inspired by Kent's Fast forms blog post - he provides an (unfortunately contrived, incomplete, and buggy) example, but the core idea is sound. For uncontrolled forms, also consider via react-hookform 对于大型、昂贵的表格,应考虑使用不受控制的组件。换句话说,在每个输入中处理状态。以下是我的方法,灵感来源于 Kent 的快速表单博文--他提供了一个例子(不幸的是,这个例子是臆造的、不完整的、有漏洞的),但核心思想是正确的。对于不受控制的表单,也可以考虑使用 react-hookform
Statically render if possible (Easy via Next.js, Gatsby)
Consider server rendering to avoid slow network waterfalls (easy via Remix / Next.js)
Prefetch / render-as-you-fetch (React's "default" is fetch as you render since the render triggers a fetch via useEffect). React-query's prefetching is a simple way to render as you fetch. Remix also does this by default since nested routes declare data dependencies and run in parallel on the server. My tweet on this
Consider using million's block virtual DOM instead if there is a lot of static content with little dynamic content. Million diffs state instead of DOM, which is fast if there's a little state, but a LOT of DOM.
Context
Minimize context usage - Consider component composition instead (composing components that accept children, so props "Lifted" / composed at a higher level in the tree). Dan calls this lift content up.
Implement client-side routing via React Router (or you frameworks built-in alternative, such as Next.js)
Keys
Assure keys are assigned, and stable over time. Their values should not change based on array order or edits to the data.
Reuse keys to avoid needless renders for items that frequently appear/disappear in the viewport.
Consider using the array’s index as key for dynamic lists with stateless items, where items are replaced with the new ones - paginated lists, search and autocomplete results and the like. This will improve the list’s performance because the entire thing doesn't have to re-render. The component instances are reused. Demo and blog post
State
Keep state as local as possible. Start by declaring state in the component that uses it. Lift as needed.
Store data that doesn't need to render in refs
Consider useReducer over useState so you can pass dispatch down instead of callbacks (avoids needless renders)
Avoid deep cloning. To avoid, only clone the subobjects that have changed. Or perhaps better yet, avoid nesting objects in state since doing so can lead to needless renders. Instead, "flatten" state by creating separate pieces of state.
Use useTransition for low priority updates (reduces jank) - Demo
Use useLayoutEffect to avoid a Flash of unstyled content when you need to read and manipulate the DOM before the user sees it - Demo
Memoization / Identity
Memoize expensive operations via useMemo
Avoid needless renders via React.memo
Consider wrapping functions passed to children in useCallback to avoid needless renders in children
Prefer pure functions (which can be extracted from the component) over useCallback when possible
Props
Pass the minimal amount of data to each component (remember, components re-render when props change)
Pass primitives (strings, numbers...) to child components to assist with diffing. Avoid passing arrow funcs and objects on props when performance is a concern since it leads to needless re-renders of child components.
useDeferredValue if it's a low priority update and you can't use useTransition because you don't control the value coming in (coming from third party or via a prop you can't control). Another demo
Component composition / Children
Put content that renders frequently in a separate component to minimize the amount that's rendered
Embrace reusable components. Each reuse of a reusable component is nearly free.
Compose higher level components out of lower level components.
Create layout components to centralize reusable layout
Declare functions that need not be in the React component outside the component. This way they're not reallocated on every render.
Declare static values outside the component so they're not reallocated on every render.
Design
Use pagination, sorting, filtering, pages, tabs, accordions, modals, etc to avoid displaying too much data at the same time.
Use tools like react-window to handle large lists by only rendering what's currently visible.
Consider implementing optimistic updates when the API is slow (immediately update the UI even though the API call is still in progress behind the scenes)
Bundle optimization
Split the bundle via React.lazy or use loadable-components. Not merely pages. Consider splitting components too. Remember that Next.js automatically bundle splits.
Check what's in your bundle via webpack-bundle-analyzer
Third party libraries
Avoid named imports when importing third party libraries / components (doing so can bloat the bundle by importing the entire lib) For example, avoid import { Tab } from "x". Prefer import Tab from "x/Tab" when possible.
Prefer native HTML inputs over fancy components that simulate native behaviors
Use Partytown to load heavy third party libraries via a separate web worker thread
Styling
Consider Tailwind to minimize style bundle size
Consider CSS modules over CSS-in-JS to avoid a runtime
Framework
Consider Gatsby or Astrobuild to compile components into static HTML
42+ ways to make your React app faster ⚛️:
让 React 应用程序更快的 42+ 种方法 ⚛️:
Performance Testing 性能测试
检查核心网络生命体征,如 INP
使用 https://million.dev/lint
通过 React 开发工具分析性能。
使用 React 开发工具 "突出显示更新 "来查看重新渲染的内容。然后采取策略。
问:为什么这个组件要重新渲染?
问:我能否避免传递导致重新渲染的道具?是否可以通过 "上下文 "访问这些数据,以避免通过不需要这些数据的中间组件?
启用每个组件渲染的原因。
学习使用 React 剖析器,并阅读火焰图:黄色 = 花费更多时间。蓝色 = 耗时较少。灰色 = 本次提交期间未渲染。( 源代码)
console.time
like this, against the prod build, to measure slowness and compare to a before and after to determine ifuseMemo
is a net win:console.time('filter array'); const visibleTodos = getFilteredTodos(todos, filter); console.timeEnd('filter array');
像这样使用
console.time
,与原型构建对比,测量速度慢的程度,并与之前和之后进行比较,以确定useMemo
是否净赢:console.time('filter array'); const visibleTodos = getFilteredTodos(todos, filter); console.timeEnd('filter array');
使用 https://github.com/welldone-software/why-did-you-render
使用 Chrome 浏览器的 CPU 和网络减速功能
小贴士以 JSON 格式存储大型模拟数据集/配置对象。解析速度会快 80%。
使用以下选项之一创建/模拟大型数据集/慢速组件
Generate a simple fake dataset in a loop.
循环生成一个简单的假数据集。
Generate a large fake dataset using tools like Faker, Chance, etc.
使用 Faker、Chance 等工具生成一个大型假数据集。
Simulate a slow component via a loop:
通过循环模拟慢速分量
Forms 表格
将长表格分割成不同步骤
对于大型、昂贵的表格,应考虑使用不受控制的组件。换句话说,在每个输入中处理状态。以下是我的方法,灵感来源于 Kent 的快速表单博文--他提供了一个例子(不幸的是,这个例子是臆造的、不完整的、有漏洞的),但核心思想是正确的。对于不受控制的表单,也可以考虑使用 react-hookform
HTTP 超文本传输协定
通过 react-query/swr/Apollo 等缓存 HTTP 请求。
提升状态,避免重复呼叫
使用 Promise.all 并行调用
使用 useOnScreen 等工具,在折叠下方懒加载内容
简化 HTTP 请求--只获取必要的数据
使用 setQueryData 预填充详情页缓存。现在,详细页面会立即加载。
Rendering
useEffect
). React-query's prefetching is a simple way to render as you fetch. Remix also does this by default since nested routes declare data dependencies and run in parallel on the server. My tweet on thisContext
Routing
Keys
key
for dynamic lists with stateless items, where items are replaced with the new ones - paginated lists, search and autocomplete results and the like. This will improve the list’s performance because the entire thing doesn't have to re-render. The component instances are reused. Demo and blog postState
useTransition
for low priority updates (reduces jank) - DemouseLayoutEffect
to avoid a Flash of unstyled content when you need to read and manipulate the DOM before the user sees it - DemoMemoization / Identity
Props
useTransition
because you don't control the value coming in (coming from third party or via a prop you can't control). Another demoComponent composition / Children
children
don’t re-render since they are just props. Note: don't pass a function as a child, since it'll still re-render because the func will be recreated on each renderDesign
Bundle optimization
Third party libraries
import { Tab } from "x"
. Preferimport Tab from "x/Tab"
when possible.Styling
Framework
More examples
https://piyushsinha.tech/optimizing-performance-in-react-apps-i
https://piyushsinha.tech/optimizing-performance-in-react-apps-ii
The text was updated successfully, but these errors were encountered: