Taiming
  • NEW!
    NEW!  Connect Ideas Across Notes
    Save time and share insights. With Paragraph Citation, you can quote others’ work with source info built in. If someone cites your note, you’ll see a card showing where it’s used—bringing notes closer together.
    Got it
      • Create new note
      • Create a note from template
        • Sharing URL Link copied
        • /edit
        • View mode
          • Edit mode
          • View mode
          • Book mode
          • Slide mode
          Edit mode View mode Book mode Slide mode
        • Customize slides
        • Note Permission
        • Read
          • Only me
          • Signed-in users
          • Everyone
          Only me Signed-in users Everyone
        • Write
          • Only me
          • Signed-in users
          • Everyone
          Only me Signed-in users Everyone
        • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invite by email
        Invitee

        This note has no invitees

      • Publish Note

        Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

        Your note will be visible on your profile and discoverable by anyone.
        Your note is now live.
        This note is visible on your profile and discoverable online.
        Everyone on the web can find and read all notes of this public team.

        Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Explore these features while you wait
        Complete general settings
        Bookmark and like published notes
        Write a few more notes
        Complete general settings
        Write a few more notes
        See published notes
        Unpublish note
        Please check the box to agree to the Community Guidelines.
        View profile
      • Commenting
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
        • Everyone
      • Suggest edit
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
      • Emoji Reply
      • Enable
      • Versions and GitHub Sync
      • Note settings
      • Note Insights New
      • Engagement control
      • Make a copy
      • Transfer ownership
      • Delete this note
      • Save as template
      • Insert from template
      • Import from
        • Dropbox
        • Google Drive
        • Gist
        • Clipboard
      • Export to
        • Dropbox
        • Google Drive
        • Gist
      • Download
        • Markdown
        • HTML
        • Raw HTML
    Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
    Create Create new note Create a note from template
    Menu
    Options
    Engagement control Make a copy Transfer ownership Delete this note
    Import from
    Dropbox Google Drive Gist Clipboard
    Export to
    Dropbox Google Drive Gist
    Download
    Markdown HTML Raw HTML
    Back
    Sharing URL Link copied
    /edit
    View mode
    • Edit mode
    • View mode
    • Book mode
    • Slide mode
    Edit mode View mode Book mode Slide mode
    Customize slides
    Note Permission
    Read
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Write
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # 2022-10-19 MI DMP GUI Refactor/Rebuilding Report by Taiming ###### tags: `GroundHog` ## 前言 DMP GUI 歷經幾任不同的 RD 開發後,累積了不少的已淘汰掉的 code,但仍存在/被引用在不同段落之中。這會導致接手 GUI 的前端工程師很難追蹤 bug,且很容易發生改 A 錯 B 的情形,不僅加大 QA 跟前端 RD 的 loading,亦拖累開發速度。為了導正這件事,DMP Team 決議暫停開發新功能,並且直接重做一個新的 GUI Project 來替代掉原本的舊 GUI Project。 ==從介面上,當然也能夠很明顯看出差異性。但事實上,背後做的調校是更多的,本次報告主要希望能夠凸顯舊 GUI 的問題,以及轉換到新 GUI 之後得到的好處及轉變。== ## 介面調整 ![](https://i.imgur.com/RsR0jlr.png) ![](https://i.imgur.com/Hdkn488.png) ## 程式碼行數/檔案數分析 ```shell= cloc --exclude-list-file=.clocignore . ``` **舊 GUI: dmp-gui** ![](https://i.imgur.com/sSKNTju.png) **新 GUI: dmp-gui-front-end** ![](https://i.imgur.com/yXLsrm3.png) ### 小結 在擁有同樣的功能,甚至更好的功能的前提下,程式碼行數減少,以及檔案數量減少,代表: - `有效減少使用者必須傳輸的資料量`,從而減少了使用者載入應用程式/站點所需的時間。這對於使用低頻寬連線的使用者而言尤其重要。 - `可讀性也能有效提升`(ex: 原本了解一個功能需要讀 500行,現在瞭解同樣的功能只需要讀 200 行。其中舊 GUI 最大的一個檔案有破千行)。 - `可維護性提升`,原本要維護 76 萬行程式碼,現在只要維護 2 萬行。 統計: - 程式碼行數: - 減少為原本的 1/36 - 減少了 97.22% - 檔案數量: - 減少為原本的 1/33.6 - 減少了 97% - 註解數量: - 減少為原本的 1/636 - 減少了 99.8% - 空白行數量: - 減少為原本的 1/94.68 - 減少了 98.9% 並且,使用 Typescript,因為多增加了型別檢查,理應當程式碼要變多,但是整體上程式碼還是減少,所以理論上減少的程式碼是更多的。 --- ## 版本升級 - node v10 --> v14 - 由於 `semantic-ui` 套件大量使用,造成過往 node 一直無法升級。現在完全棄用 `semantic-ui`,因此能夠無痛升級。未來也能無痛升到 v16。 - react v16.8.4 --> v18.2.0 - react17 是一個過渡版本,為了 react18 做鋪路。 - react18 是最新穩定的版本。 --- ## 檔案結構優化 **舊 GUI:** 如同四個室友住在一起,後來三個都搬出去了,剩下自己留下來,但是房間裡面還有許多前室友的遺留物。你不知道該怎麼整理他,該留?該丟?而且有些是跟其他室友共用的東西,有些是不確定是什麼東西的東西,不知道丟了會不會出問題。 ![](https://i.imgur.com/SmHYMsU.png) - 在前端裡面有 backend 的 code. ex: backend-core/ - 有許多檔案結構的設計,看起來是以前為了跟 DSP 共用而設計(以前 DMP & DSP 在同一包)。 ex: - frontend-hooks - frontend-model - frontend-queries - frontend-xxx ![](https://i.imgur.com/WenZZRW.png) **以前 DSP 與 DMP 同一包的證據:** ![](https://i.imgur.com/PBNajJi.png) ![](https://i.imgur.com/gEFepZm.png) ![](https://i.imgur.com/vUEHYvb.png) ![](https://i.imgur.com/yeIZC25.png) **檔案結構沒有分類** - 沒有區分頁面元件與共用元件 - 檔案結構沒有分層,全部攤平在同一層,所以要找 code 很難找 - ex: 如同抽屜打開來,書本、咖啡杯、文具、便當、襪子、零食、充電線全部塞在一起,沒有分類。 ![](https://i.imgur.com/akTOuJY.png) **新 GUI:** 解決上述問題,檔案區分清楚,檔案結構與頁面結構完美對應。從檔案結構即可理解頁面邏輯: ![](https://i.imgur.com/SJvXW7E.png) ### 小結 - 移除不必要的檔案(ex: DSPxxx, xxxDSP) - 過去結構設計以 DSP&DMP 共用為考量,因此檔案結構在 DSP&DMP 獨立之後難以理解。這部份在新 GUI 完全解決。 - 檔案分類清楚(ex: pages, components, hooks, constants, configs, routes, types, utils...)。原本是散落在各個資料夾當中。 - 檔案結構與頁面結構完美對應。從檔案結構即可理解頁面邏輯。因此能夠增加開發速度與減少除錯時間 - 個人實測:過往平均找到一個頁面上的元件所在的檔案需要十分鐘,甚至常常需要半小時以上。現在在一分鐘內(甚至秒等級)就能夠鎖定頁面上的原始碼。提升的速度至少 10 倍以上。 --- ## 關於檔案搜尋 可讀的 class name。DOM 結構變得語意化,可理解。 過往,在頁面上的一個 button,要找他所在的 file 真的比登天還難。因為線索很少,雷同的地方又很多。 ![](https://i.imgur.com/a3qDYC2.png) 由於過往在不同環境會需要不同的 webpack 打包,因此產生出許多檔案,讓鎖定程式碼這件事情變得很困擾: ![](https://i.imgur.com/Rkgqw4W.png) ![](https://i.imgur.com/Dn1R5Vp.png) ![](https://i.imgur.com/WzIL3pX.png) ### 小結 屏棄過往複雜的打包方式,讓程式碼變得乾淨,大大降低鎖定程式碼所需要的時間。 - 個人實測:過往平均找到一個頁面上的元件所在的檔案需要十分鐘,甚至常常需要半小時以上。現在在一分鐘內(甚至秒等級)就能夠鎖定頁面上的原始碼。提升的速度至少 10 倍以上。 --- ## 套件的整理 舊 GUI 當中,安裝許多過時的、重覆的、沒有用到的、不必要的套件,但因為程式碼的相依性以及複雜度,造成無法乾淨的移除。在新 GUI 當中大大改善這邊的功能。 **UI library 好多套:** - antd - semantic-ui (目前安裝的也太過老舊) - @ghtinc/react (Groundhog 自己的) - MUI <--- 差點要裝了 **utility library 裝兩套:** - lodash - Ramda - 可以將 ramda 想成 functional programming 的 lodash,他們的 API 有許多相似性,差別在於 ramda 本身有 FP 的功能,任何的 API 只要你沒有傳入參數,ramda 就會自動做 curry,這提供了相當大的彈性。 - https://medium.com/d-d-mag/淺析幾個-ramda-當中的-api-c399a3f73c68 **使用不再維護的套件:** - moment (MomentJs recently announced that the library is now deprecated.) - 已經被棄用 - 因為太肥大而被人詬病 - 跟 antd 相依 - luxon - 同樣是處理時間的套件 - A powerful, modern, and friendly wrapper for JavaScript dates and times. https://momentjs.com/docs/#/-project-status/ ``` moment - 327KB, but also needs moment-timezone (185KB) Total: 513KB day.js - 2KB, but also needs the utc and timezone plugins (4KB), and all locales (26 KB) Total: ~32KB ``` https://terodox.tech/migrating-away-from-momentjs-part1/ **使用沒有必要的套件:** ex: 已經用 graphql,就沒有必要再用 redux, redux-thunk, reselect...。 ### 小結 - packge.json 從 199 行減少為 97 行。 - 其中安裝的套件數量從 167 個減少為 59個。減少為原本的 1/2.8,將近 1/3。 --- ## 大幅減少環境變數 舊 GUI 的環境變數太氾濫,甚至有些重複的功能卻不同命名,或者有些不需要放到環境變數裡面,這次新 GUI 將環境變數統一並縮減。使用到相關的環境變數的程式碼也調整完畢。 舊 GUI: ```yml= dmp_gui: image: repository: "{{ DOCKER_REGISTRY }}/ghtinc/dmp-gui" tag: DMPv2.1.35 env: - NODE_ENV=production - PRODUCT=indosat - WEB_PORT=4040 - LANGUAGE=en - DATE_FORMAT=dd-LLL-yy - DATE_HOUR_FORMAT=dd-LLL-yy HH:mm - LOCATION=[-4.67,109.94] - LABEL_INDEX_AGE=1 - LABEL_INDEX_GENDER=2 # graphql api - DMP_GUI_BACKEND_URL=https://data-ads.indosatooredoo.com - AUDIENCE_ID_TYPES=ifa,gid,brgid,im3 - CUSTOM_IMAGE_TYPE=indosat - CUSTOM_HTML_TITLE=indosat ``` 新 GUI: ```yml= dmp_gui_frontend: image: repository: "{{ DOCKER_REGISTRY }}/.../dmp_gui_frontend" tag: v0.1.28 env: - REACT_APP_PRODUCT=indosat # graphql api - REACT_APP_DMP_GUI_BACKEND_URL=https://data-ads.indosatooredoo.com ``` --- <!-- ## Bug 發現數量 12/22~10/6 old gui high bugs: 24 8/25~10/19 new gui high bugs: 13 12/07-10/7(304 天) old gui bugs: 149 8/25~10/19(55 天) new gui bugs: 44 --> ## 程式碼優化/移除壞味道(Bad Smell) 舊 GUI: - eslint/prettier 形同虛設 - 許多沒有被用到的引入 ![](https://i.imgur.com/xvVyps3.png) **過於複雜的 React 生命週期,useEffect 連續技......** - 程式執行的流程難以預測 - 參數的結果難以預測 - 造成很難修正 bug(修這個壞那個),也很難增加功能。 ![](https://i.imgur.com/WRq4IQK.png) ![](https://i.imgur.com/64XZgIJ.png) ![](https://i.imgur.com/VNJYwyi.png) ![](https://i.imgur.com/svY0rzr.png) ![](https://i.imgur.com/wbAtQX8.png) ![](https://i.imgur.com/eUKdsJg.png) **使用 React Hooks 取代 class component(React16.8 以前的寫法)** - class components 程式碼較為冗長 - class components 需要撰寫 JS 當中最令人難以理解和頭痛的 `this` - class components 編譯速度沒有 functional components 快(少了繼承 class 轉成 ES5) - funtional components 可以避免生命週期方法的調用,減少人為錯誤的發生。 ![](https://i.imgur.com/8J6TdgE.png) **一言不合就 reload** - 創建資料 - 更新資料 - 刪除資料 - 換頁 - 切換 advertiser - 有東西不預期壞掉了 其實我們只需要針對更新的「區塊」作更新就好了,但是舊 GUI 就算只有小區塊的更新,也會「整個頁面刷新」,因此效能和使用者體驗很差。 ![](https://i.imgur.com/qDaVE02.png) **避免使用非主流語法** 屏棄使用 pipeline operator 模式 - 會增加專案的學習門檻。 - 沒有明顯感受到好處,反而增加理解程式碼的困難度。 - 專案會需要特別為了支援特別的語法做更多的設定。 - 而且此語法只有在這個專案適用,同樣的程式碼移到別的專案上就不能執行。 - ES6 已經很強大,並且很通用。 ![](https://i.imgur.com/tJkqUQa.png) ![](https://i.imgur.com/Nyn0Qze.png) ![](https://i.imgur.com/ea4IxqC.png) **統一 style 的寫法** - 舊 GUI 處理 style 有各種寫法 - ex: `*.css, *.scss, *.less, object css, styled-components...etc.` - 新 GUI 全站統一使用 styled-components. ### 小結 - 使用 Typescript 達到 90% 以上(舊 GUI 的 Typescript 為 6.3%)。詳如檔案分析圖。 - 許多js的錯誤往往是在runtime時才報錯,有了typescript,我們能夠在編譯時期就發現錯誤。 - 增加可讀性:有了型別之後,我們能更好得理解程式碼,進而提升整體的閱讀速度。 - 減少難以預測的生命週期觸發 - 重新調校 eslint/prettier - 屏棄 class components,全面使用 functional components + React Hooks - 參數命名優化 - 可讀性優化 - 命名一致性優化(Agency vs Brand, Visualization vs Project...etc) - 減少一個檔案內程式碼的行數,大部分一個檔案在 250 行內。 - 移除沒有使用到的引入 - 修正錯誤的程式邏輯 - ex: 一言不合就 reload - 避免使用非主流語法 ## 總結 - 大幅度減少專案的大小,以及清除不需要的程式碼 - 程式碼行數:減少為原本的 1/36 - 檔案數量:減少為原本的 1/33.6 - 版本升級,增加專案的支援度、安全性 - node v10 --> v14 - react v16.8.4 --> v18.2.0 - 相依性套件也會跟著升級 - 檔案結構優化 - 有條理、可理解的檔案結構 - 大幅改善鎖定 root cause 的時間,實測至少 10 倍。 - DOM 結構變得語意化,可理解。 - 大幅改善鎖定 root cause 的時間,實測至少 10 倍。 - 套件的整理 - 移除重覆、沒有被使用到、不必要的套件 - 安裝的套件數量從 167 個減少為 59個。減少為原本的 1/2.8,將近 1/3 - 大幅減少亂用而氾濫的環境變數 - 程式碼優化/移除壞味道(Bad Smell) - 使用 Typescript 達到 90% 以上(舊 GUI 的 Typescript 為 6.3%)。 - 許多js的錯誤往往是在runtime時才報錯,有了typescript,我們能夠在編譯時期就發現錯誤。 - 增加可讀性:有了型別之後,我們能更好得理解程式碼,進而提升整體的閱讀速度。 - 統一 style 的寫法 - 舊 GUI 處理 style 有各種寫法 - ex: `*.css, *.scss, *.less, object css, styled-components...etc`. - 新 GUI 全站統一使用 styled-components. - 減少難以預測的生命週期觸發 - 重新調校 eslint/prettier - 屏棄 class components,全面使用 functional components + React Hooks - 參數命名優化 - 可讀性優化 - 大量的錯字修正 - 命名一致性優化(Agency vs Brand, Visualization vs Project...etc) - 原本畫面上的文字、程式碼、API 參數,是同一個東西,但命名都不一樣,因此很難理解、很難追蹤。 - 錯誤的參數命名 - ex: 明明是 label,卻命名成 category 或 type 或 tag。明明是 category,卻命名成 label。 - 減少一個檔案內程式碼的行數,大部分一個檔案在 250 行內。 - 移除沒有使用到的引入 - 修正錯誤的程式邏輯 - ex: 一言不合就 reload - 避免使用非主流語法 ## Ref: Spec: https://hackmd.io/@Taiming/By7-E9t55 Kader suggestion: https://hackmd.io/@acEKxk9GRZCnOXjvxEOGfQ/Hy1KI_rbs

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully