国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

深圳快速seo排名優(yōu)化關鍵詞優(yōu)化排名工具

深圳快速seo排名優(yōu)化,關鍵詞優(yōu)化排名工具,影視自助建站,做網(wǎng)站職員工資背景 雙十一大促時,客戶客服那邊反饋商品信息加載卡頓,在不斷有訂單咨詢時,甚至出現(xiàn)了商品信息一直處于加載狀態(tài)的情況,顯然,在這種高峰期接待客戶時,是沒法進行正常的接待工作的。 起初,頁面一…

背景

雙十一大促時,客戶客服那邊反饋商品信息加載卡頓,在不斷有訂單咨詢時,甚至出現(xiàn)了商品信息一直處于加載狀態(tài)的情況,顯然,在這種高峰期接待客戶時,是沒法進行正常的接待工作的。
起初,頁面一直處于加載狀態(tài),初步認為是后端接口返回太慢導致,后經(jīng)過后端日志排查,發(fā)現(xiàn)接口返回很快,根本不會造成頁面一直處于加載狀態(tài),甚至出現(xiàn)卡死的狀態(tài)。后經(jīng)過不斷排查,發(fā)現(xiàn)是客戶端性能問題導致。

優(yōu)化前

咨詢訂單時,只咨詢一條訂單,用時需要3秒左右,當連續(xù)咨詢5、6條訂單時,用時甚至達到了一分多鐘,僅僅5、6條訂單竟然用時這么久,那么在持續(xù)不斷有訂單咨詢時,頁面就會出現(xiàn)一直加載,甚至卡死的狀態(tài),明顯存在很大的性能問題。
在這里插入圖片描述

在這里插入圖片描述

利用performance工具可以分析主線程的Event Loop,圖中標出的Main就是主線程。
主線程是不斷執(zhí)行 Event Loop 的,可以看到有很多個 Task(宏任務),當主線程中的任務過多時,會導致主線程長時間被占用,無法及時響應用戶的交互操作,從而影響用戶體驗。這種情況下,頁面可能會出現(xiàn)卡頓、延遲響應等問題。

優(yōu)化后

當只咨詢一條訂單時,用時需要1秒時間,連續(xù)咨詢5、6條訂單,用時優(yōu)化到只需要3秒時間,并且頁面流暢,對于用戶體驗上得到了明顯的提升。
在這里插入圖片描述
在這里插入圖片描述

可以看出long task 減少了很多。
那么,如何來優(yōu)化呢?請看下面的內(nèi)容。

優(yōu)化點

在合適的時機進行組件渲染

在排查代碼的過程中發(fā)現(xiàn),很多本不該當前狀態(tài)渲染的組件,都渲染出來了,顯然這是不合理的。過多的組件渲染會占用大量的內(nèi)存,并且也會增加頁面的渲染時間,自然,響應性能就會變得很差,用戶與頁面的交互就會變得遲緩。
而商品信息加載部分最常見的不必要的組件渲染表現(xiàn)在使用Modal彈窗時,我們都知道當visible為true時,會彈出彈窗相應的頁面內(nèi)容,但是當visible為false時,其實是不希望渲染Modal彈窗中的內(nèi)容的,這會帶來額外的性能開銷。

下面是一些示例:

-  ...
-  <Modal
-   ...
-   visible={editVisible}
-   ...>
-  ...
-  </Modal>
-  ...
+  {editVisible && (
+     <GoodsAttributeModal
+      editVisible
+      ...
+     />
+  )}
// 把Modal彈窗作為一個單獨組件提取出去,并且只有當editVisible為true時才渲染組件

第一段代碼中,使用了visible={editVisible}來控制Modal組件的顯示與隱藏。當editVisible為true時,Modal組件會被渲染出來,否則不會被渲染。

第二段代碼中,使用了條件渲染的方式,即通過{editVisible && …}來判斷是否渲染Modal組件。當editVisible為true時,Modal組件會被渲染出來,否則不會被渲染。

這兩種方式的主要區(qū)別在于組件的渲染時機。在第一種方式中,Modal組件在每次渲染時都會被創(chuàng)建和銷毀,而在第二種方式中,只有在editVisible為true時才會創(chuàng)建和渲染Modal組件。

使用條件渲染的方式可以提高性能,特別是在組件層級較深或渲染頻繁的情況下。因為只有在需要顯示Modal組件時才會進行渲染,避免了不必要的組件創(chuàng)建和銷毀,減少了內(nèi)存消耗和渲染時間。

總結(jié)起來,使用條件渲染的方式可以根據(jù)需要動態(tài)地控制組件的顯示與隱藏,提高性能和用戶體驗。

使用useCallback、useMemo、React.memo提升性能

下面是一些示例:
useCallback

-  renderContent = (content, searchKey) => {
-   if(content) {
-     const contentWithBr = content.replace(/\?/g, '<br>').replace(/\n/g, '<br>')
-      const regex = new RegExp(`(${searchKey})`, 'gi'); // 創(chuàng)建正則表達式,忽略大小寫匹配
-      const matches = content.match(regex) || []; // 匹配結(jié)果數(shù)組
-      return (
-        <React.Fragment>
-          {contentWithBr.split('<br>').map((text, index) => (
-            <React.Fragment key={index}>
-              {index > 0 && <br />}
-              {text.split(regex).map((subText, subIndex) => {
-                // console.log('subText',subText,matches)
-                return (
-                  <React.Fragment key={subIndex}>
-                    {matches.includes(subText) ? (
-                      <span style={{ color: '#FF8800' }}>{subText}</span>
-                    ) : (
-                      subText
-                    )}
-                  </React.Fragment>
-                )
-              })}
-            </React.Fragment>
-          ))}
-        </React.Fragment>
-      )
-    } else {
-      return '-'
-    }
-  }+  const renderContent = useCallback((content, searchKey) => {
+    if (content) {
+      const contentWithBr = content.replace(/\?/g, '<br>').replace(/\n/g, '<br>')
+      const regex = new RegExp(`(${searchKey})`, 'gi') // 創(chuàng)建正則表達式,忽略大小寫匹配
+      const matches = content.match(regex) || [] // 匹配結(jié)果數(shù)組
+      return (
+        <React.Fragment>
+          {contentWithBr.split('<br>').map((text, index) => (
+            <React.Fragment key={index}>
+              {index > 0 && <br />}
+              {text.split(regex).map((subText, subIndex) => {
+                //console.log('subText',subText,matches)
+                return (
+                  <React.Fragment key={subIndex}>
+                    {matches.includes(subText) ? (
+                      <span style={{ color: '#FF8800' }}>{subText}</span>
+                    ) : (
+                      subText
+                    )}
+                  </React.Fragment>
+                )
+              })}
+            </React.Fragment>
+          ))}
+        </React.Fragment>
+      )
+    } else {
+      return '-'
+    }
+  }, [])

上面的代碼使用了React的useCallback鉤子函數(shù)來定義了一個名為renderContent的函數(shù)。useCallback的作用是用來緩存函數(shù),以便在依賴項不變的情況下避免函數(shù)的重新創(chuàng)建。

使用useCallback的好處是可以優(yōu)化性能,特別是在父組件重新渲染時,避免不必要的函數(shù)重新創(chuàng)建。當依賴項數(shù)組為空時,useCallback會在組件的初始渲染時創(chuàng)建函數(shù),并在后續(xù)的渲染中重復使用同一個函數(shù)。

而沒有使用useCallback的情況下,每次組件重新渲染時都會創(chuàng)建一個新的renderContent函數(shù),即使函數(shù)的實現(xiàn)邏輯完全相同。這可能會導致性能問題,特別是在組件層級較深或渲染頻繁的情況下。

因此,使用useCallback可以提高組件的性能,避免不必要的函數(shù)創(chuàng)建和內(nèi)存消耗。但需要注意的是,只有在確實需要緩存函數(shù)并且依賴項不變的情況下才使用useCallback,否則可能會導致不必要的優(yōu)化和錯誤。

useMemo

-  const tooltip = (
-    <div>
-      <h2>
-        <span className={styles.title}>{title}</span>
-        {
-          !window.isVisibleGoods && (
-            <span>
-              {renderKnowledgeModal({
-                label: '編輯',
-                record: item,
-               platGoodsId: plat_goods_id,
-                classification_id: classificationId,
-              })}
-              <a
-                className={styles.delete}
-                onClick={() => handleDeleteKnowledage(item, classificationId)}
-              >
-                刪除
-              </a>
-            </span>
-          )
-        }        
-      </h2>
-      <div className={styles.img_block}>{images}</div>
-      <div
-        className={classnames(styles.context, styles.tooltipsContext)}
-        dangerouslySetInnerHTML={{ __html: ParseBrow.parse(context) }}
-      />
-    </div>
-  )
+ const tooltip = useMemo(
+    () => (
+      <div>
+        <h2>
+          <span className={styles.title}>{title}</span>
+          {!isVisibleGoods && (
+            <span>
+              {renderKnowledgeModal({
+                label: '編輯',
+                record: item,
+                platGoodsId: plat_goods_id,
+                classification_id: classificationId,
+              })}
+              <a
+                className={styles.delete}
+                onClick={() => handleDeleteKnowledage(item, classificationId)}
+              >
+                刪除
+             </a>
+            </span>
+          )}
+        </h2>
+        <div className={styles.img_block}>{images}</div>
+        <div
+          className={classnames(styles.context, styles.tooltipsContext)}
+          dangerouslySetInnerHTML={{ __html: ParseBrow.parse(context) }}
+        />
+      </div>
+    ),
+    [
+      title,
+      renderKnowledgeModal,
+      item,
+      plat_goods_id,
+      classificationId,
+      images,
+      context,
+      handleDeleteKnowledage,
+      isVisibleGoods,
+    ]
+  )

在上面的代碼中,使用了useMemo來緩存了一個變量tooltip的計算結(jié)果。這個計算結(jié)果是一個React元素,包含了一些子元素和事件處理函數(shù)等。通過將tooltip作為依賴數(shù)組的一部分,當依賴數(shù)組中的值發(fā)生變化時,useMemo會重新計算tooltip的值;如果依賴數(shù)組中的值沒有發(fā)生變化,則直接返回上一次緩存的tooltip的值。

這樣做的好處是,當依賴數(shù)組中的值沒有發(fā)生變化時,可以避免重復計算tooltip的值,提高組件的性能。而如果依賴數(shù)組中的值發(fā)生變化,useMemo會重新計算tooltip的值,確保tooltip的值是最新的。

相比之下,如果不使用useMemo,每次組件重新渲染時都會重新計算tooltip的值,即使依賴數(shù)組中的值沒有發(fā)生變化,這樣會造成不必要的性能損耗。

總結(jié)起來,使用useMemo可以優(yōu)化組件的性能,避免不必要的計算。但是需要注意的是,只有在計算的成本比較高時才需要使用useMemo,否則可能會帶來額外的開銷

React.memo

-  export default Item
+  import { isEqual } from 'lodash'
+  export default React.memo(Item, isEqual)

export default Item 直接導出組件,每次父組件重新渲染都會重新渲染 Item 組件;
而 export default React.memo(Item, isEqual) 使用 React.memo 進行包裹,并傳入自定義的比較函數(shù) isEqual,只有在 props 發(fā)生變化且通過 isEqual 函數(shù)比較不相等時才會重新渲染 Item 組件。
注意:自定義的比較函數(shù) isEqual 用于比較兩個 props 是否相等。如果不傳入比較函數(shù),則默認使用淺比較(即 Object.is)來比較 props。如果傳入了比較函數(shù),則會使用該函數(shù)來比較 props。

props解構(gòu)變量時的默認值

在這里插入圖片描述

在這段代碼中,KnowledgeTab是一個使用了React.memo進行優(yōu)化的組件。React.memo是一個高階組件,用于對組件進行淺層比較,以確定是否需要重新渲染組件。當組件的props沒有發(fā)生變化時,React.memo會返回之前渲染的結(jié)果,從而避免不必要的重新渲染。

在KnowledgeTab組件中,knowledge_list是一個從props中解構(gòu)出來的屬性。而const knowledge_list_default = useMemo(() => [], [])是使用useMemo鉤子函數(shù)創(chuàng)建的一個空數(shù)組。這樣做的目的是為了在組件的初始渲染時,給knowledge_list一個默認值,以避免在解構(gòu)時出現(xiàn)undefined的情況。

如果直接使用knowledge_list=[]來給knowledge_list賦值,會破壞React.memo的優(yōu)化。因為每次父組件重新渲染時,knowledge_list都會被重新創(chuàng)建,即使它的值沒有發(fā)生變化。這樣會導致KnowledgeTab組件的props發(fā)生變化,從而觸發(fā)不必要的重新渲染。

而使用useMemo創(chuàng)建一個空數(shù)組作為默認值,可以保證在父組件重新渲染時,knowledge_list_default的引用不會發(fā)生變化,從而避免不必要的重新渲染。這樣就能夠保持React.memo的優(yōu)化效果,只有在knowledge_list的值真正發(fā)生變化時才會重新渲染KnowledgeTab組件。

所以,總結(jié)起來就是默認值如果傳給子組件,父組件每一次更新都會導致子組件更新,導致子組件的React.memo失效

拆分為狀態(tài)自治的獨立組件

當一個組件的代碼變得復雜或包含大量的子組件時,可以考慮將其中的一部分代碼抽取為一個獨立的子組件。這樣做的好處是可以將復雜的邏輯拆分為多個小組件,提高代碼的可讀性和可維護性。
同時,抽取組件也可以配合使用React.memo進行優(yōu)化。
下面是一個抽取獨立組件的例子
在這里插入圖片描述

import React, { memo } from 'react'
import { Tooltip } from 'antd'
import classNames from 'classnames'
import Item from './item'
import styles from '../../index.less'interface Item {name: stringid: string
}
interface CategoryProps {item: ItemactiveKey: stringonClickItem: () => void
}
const Category: React.FC<CategoryProps> = props => {const { item, activeKey, onClickItem } = propsconst { name, id } = itemreturn (<Tooltiptitle={name}placement="topRight"align={{offset: [0, 5],}}><spankey={id}className={classNames(styles.tab_item, {[styles.active_item]: activeKey === id,})}onClick={onClickItem}>{name}</span></Tooltip>)
}export default memo(Category)
http://aloenet.com.cn/news/45284.html

相關文章:

  • 工業(yè)和信息化部官網(wǎng)合肥seo網(wǎng)站排名
  • 嘉興網(wǎng)站制作網(wǎng)站建設網(wǎng)站推廣的主要方式
  • 自助下單網(wǎng)站鐵力seo
  • 武漢網(wǎng)站建設招聘客服珠海優(yōu)化seo
  • 軟件班級網(wǎng)站建設今日騰訊新聞最新消息
  • 深圳網(wǎng)站建設公司佰達推客平臺
  • 優(yōu)化型網(wǎng)站建設廈門網(wǎng)站優(yōu)化
  • 百度怎樣做網(wǎng)站寧波seo排名方案優(yōu)化公司
  • 一個虛擬主機可以做兩個網(wǎng)站吧發(fā)布信息的免費平臺有哪些
  • 電腦網(wǎng)站策劃書交換鏈接營銷成功案例
  • 請別人做網(wǎng)站如何交付產(chǎn)品軟文
  • 國外有沒有網(wǎng)站是做潘多拉的貴州seo技術培訓
  • 榮耀手機價格表大全一覽泉州seo外包
  • 微信鏈圖片轉(zhuǎn)換wordpress鹽城seo優(yōu)化
  • 做公司網(wǎng)站的尺寸一般是多大零基礎學seo要多久
  • 網(wǎng)站滾動圖片效果怎么做seo排名策略
  • 做團購網(wǎng)站商品從哪里找長沙網(wǎng)絡營銷哪家平臺專業(yè)
  • 學校網(wǎng)站建設主體怎么學做電商然后自己創(chuàng)業(yè)
  • 神馬網(wǎng)站可以做兼職狼雨的seo教程
  • 深圳市中心在哪里最繁華優(yōu)化大師免費版
  • 口碑好的網(wǎng)站開發(fā)公司電話網(wǎng)站設計公司網(wǎng)站制作
  • 旅游網(wǎng)站建設模板下載aso優(yōu)化的主要內(nèi)容
  • 百度地圖導航下載安裝站長工具seo綜合查詢可以訪問
  • 直播網(wǎng)站怎么做啊北京優(yōu)化互聯(lián)網(wǎng)公司
  • wordpress會員時間網(wǎng)站優(yōu)化排名哪家好
  • 下沙做網(wǎng)站的公司上海優(yōu)化網(wǎng)站方法
  • 手機網(wǎng)站頁面設計如何做好一個品牌推廣
  • 網(wǎng)站換域名要怎么做每日新聞快報
  • 深圳代做網(wǎng)站谷歌瀏覽器 免費下載
  • 購物網(wǎng)站建設流程百度app客服人工電話