iT邦幫忙

2024 iThome 鐵人賽

DAY 9
0

在前幾篇文章中,我們探討了模組化設計如何增強應用的靈活性與可維護性,同時介紹了如何優化元件重繪和狀態管理。使用 console.log 來檢查元件的重繪情況,是我們常用的方法,但這種方式在應用規模擴大時會顯得不足。今天,我們將深入探討如何透過自訂日誌系統,精確控制日誌輸出,進而提升 React 應用的效率。

為什麼需要自訂日誌?

在追蹤 React 元件重繪次數時,console.log 是一個直觀且簡單的方式,但當應用變得更複雜時,這種方法的缺點逐漸浮現:

  1. 無法分類與過濾console.log 缺乏日誌等級分類,所有訊息混在一起,讓開發者難以迅速定位錯誤或重要訊息。
  2. 缺乏靈活性:要手動插入 console.log 並沒有太多控制方式,無法根據環境動態調整日誌策略。
  3. 性能影響:過量的 console.log 在生產環境中會拖慢應用性能,並可能洩露不必要的調試訊息。

自訂日誌系統能通過日誌級別分類和動態控制來解決這些問題。它能讓你在開發時只啟用必要的日誌,避免不必要的訊息干擾,提升開發效率;同時在生產環境中過濾掉冗餘的日誌,確保應用性能不受影響。

實際演練:自訂日誌系統

Step 1:定義日誌等級

首先,我們定義幾個常用的日誌等級,並使用常量來避免硬編碼:

// src/utils/log.js
export const logLevel = {
    ERROR: 0,
    WARN: 1,
    INFO: 2,
    DEBUG: 3,
};

Step 2:新增配置檔 config.js

接著,我們創建一個配置檔案config.js,來動態控制日誌等級與日誌啟用狀態。

// src/utils/config.js
import { logLevel } from '@/utils/log';

const config = {
    logLevel: logLevel.DEBUG,  // 日誌級別
    featureFlags: {
        enableLogging: process.env.NODE_ENV !== 'production', // 根據這個配置決定是否啟用日誌
    }
};

export default config;

Step 3:封裝日誌函數

我們實作一個封裝好的日誌函數,根據日誌等級與設定動態控制輸出,並應用不同樣式以提升辨識度。

// src/utils/log.js
import config from '@/utils/config';

// ...其他實作

export const log = (level, message) => {    // 檢查是否啟用了日誌功能
    if (!config.featureFlags.enableLogging) {
        return;
    }

    // 檢查當前的日誌等級,只有當前設定的等級及以上的日誌才會輸出
    if (level <= config.logLevel) {
        if (level === logLevel.ERROR) {
            console.error(message)
        } else if (level === logLevel.WARN) {
            console.warn(message)
        } else if (level === logLevel.DEBUG) {
            console.debug(`%cDebug:  ${message}`, 'color: blue;')
        } else {
            console.log(`%cInfo: ${message}`, 'color: green;');
        }
    }
};

這樣的封裝讓我們可以靈活控制日誌輸出,根據不同的環境動態調整,並且不同級別的日誌會有不同的樣式,便於辨識與處理。

Step 4:在元件內使用log

在實際應用中,自訂日誌系統可以集成到 React 元件中,以更靈活和高效的方式追蹤元件的重繪和其他狀態變更。相比單純的 console.log,這種方式能精確控制日誌輸出,並根據需求動態調整調試的深度。

import { log, logLevel } from '@/utils/log';

// 使用封裝的日誌工具,並使用 logLevel 常量來傳遞日誌等級
log(logLevel.DEBUG, 'App rendered: ' + ready);

在這裡,我們僅在需要進行深入調試時啟用 DEBUG 級別的日誌,避免在元件每次重繪時輸出過多不必要的信息。這樣不僅能確保調試的有效性,還能防止控制台被冗餘日誌淹沒,從而提高應用的可維護性和性能。自訂日誌系統讓你在開發和調試過程中更靈活地管理日誌輸出,專注於真正需要關注的訊息。

Step 5:控制 i18n debug 日誌

我們可以將這套日誌系統應用到 i18n 的日誌控制上。i18n 的 debug 模式通常會在開發時輸出大量日誌,這會干擾其他重要日誌。因此,我們可以根據日誌等級與環境動態控制其輸出。

i18n
  .use(initReactI18next)
  .init({
    debug: config.featureFlags.enableLogging && config.logLevel === logLevel.DEBUG,
    interpolation: {
      escapeValue: false,
    },
  });

這樣,我們確保了只有在開發環境且設定為 DEBUG 級別時,i18n 才會輸出日誌,避免在生產環境中洩漏不必要的訊息。

Step 6:日誌系統執行結果

我們在元件和 i18n 中應用了自訂日誌系統,並根據開發環境和日誌等級控制輸出。以下是這套系統的實際執行結果,展示了如何在元件重繪時精準控制日誌輸出:

Day09

當應用中的元件進行重繪時,日誌系統會根據所設置的日誌等級(如 DEBUG)輸出相應的訊息。這樣可以避免控制台中充斥過多無關的訊息,並確保在需要時記錄重要的狀態變更。

透過這樣的日誌系統,開發者可以靈活控制日誌的深度與範圍,有效提升應用的可維護性和性能,特別是在多語言或大型應用中。

結語

在本文中,我們展示了如何透過自訂日誌系統克服 console.log 的限制,尤其是在應用變得更為複雜時,這套系統能讓我們靈活控制日誌輸出,並提升應用效能。隨著專案規模的擴大,這種系統化的日誌管理方式對性能的影響尤為關鍵。

你是否曾經遇到過應用資源過大導致性能下降的情況?了解如何透過動態加載來解決這些問題,進一步提升應用的加載速度。

在下一篇文章中,我們將深入探討 Lazy Loading 技術,特別是如何利用它來解決資源過大的問題,例如大字體的懶加載。這不僅能提升應用的效能,也能改善用戶的整體體驗。

此外,我們已將完整的程式碼實作與更多練習題上傳至 GitHub,鼓勵大家前往查看,並回顧文章中的概念,挑戰更進階的優化練習。

👉 前往 GitHub 的 v0.9.0-smarter-logging 查看完整程式碼


流光館Luma<∕> ✨ 期待與你繼續探索更多技術知識!



上一篇
Day 8 :優化 Context 重繪,提升 React 性能
下一篇
Day 10 : Lazy Loading 優化 React 大文件加載
系列文
從PM到前端開發:我的React作品集之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言