一、日常問題
1)CDN 異常
5 月中旬,發現影像異常的上報量比平時多了 10 多倍,日常 300 多,現在 4000 多。
但是看不到異常的錯誤碼,不能確定是域名問題還是服務問題。還特地檢視了錯誤分佈的時間段,但並沒有看出說明規律。
本來以為是證書的問題,因為正好那幾天證書到期了,但是證書更新後,異常量並沒有降低。
為了縮小範圍,特地去檢視了幾個上報量比較大的使用者。
再反查 IP 區域,發現都是臺灣那邊的網路。
將這些資訊整理後給到運維,讓他去查,但效果並不理想,並沒有查出問題,主要還是因為客戶端並沒有類似的上報。
所以我的問題沒有被引起重視,但是在 5 月 24 號時,公司的一款 APP 也上報了相同的問題。
這次提工單給 CDN 廠商,將問題修復,三天後異常消失。
2)MongoDB 最佳化
公司之前在 MongoDB 中儲存了大量日誌類的資料,這些資料已經過時,現在是冗餘資料。
於是用程式碼列出 5 張比較大的表,分別佔用 207G、61G、9G、6G 和 5G。
其中最大那個表的資料已經同步給另一個資料分析組,所以裡面的資料可以刪除,我就只保留一個月的資料量。
從這張表中刪除 834036294 條資料,持續時間 8 個多小時,減少 196G,並且做了一個定時任務,準點清理。
在釋放另外 4 張冗餘表之前,特地做了備份,執行釋放命令後,也減少了 80G 容量。
MongoDB 從 287G 直接降低到了 11G,並且未來也會維持在這個資料量。運維說每個月至少能省個兩三百的費用。
3)強快取
強快取是前端最佳化的常用手段,本次最佳化會對HTML、JavaScript 和 CSS 檔案進行強快取。
為了破壞 HTML 檔案的強快取,我用短鏈包住原始 URL 地址,在跳轉時給 URL 自動帶上一個時間戳引數。
https://www.xxx.com/xxx.html?ts=1717469228483
如此操作後,我就能保證 HTML 檔案是最新的,我的目的就是快取另外兩個檔案,以完成加速。
這次配強快取也比較謹慎,先在測試環境除錯。但很奇怪,有些資源能進快取,而有些卻不行。
後面發現是與 CDN 有關,於是就先關閉了 CDN,直接走閘道器轉發。
一開始就快取 30 分鐘,試驗 1 天,然後再快取 8 小時,試驗一天。
最後將強快取增加到 3 天,1 秒內白屏佔比從 92.04% 提升至 95.32%,1 秒內首屏佔比從 79.71% 提升至 88.03%
首屏的效能提升比較明顯,就是將之前 2 秒內的那批使用者提升到了 1 秒內。
二、工作最佳化
1)暗黑模式
最近在瀏覽抖音開源的元件庫時,看到個暗黑模式,看設定比較簡單,於是就想在自己的管理後臺也實現一個。
我們的後臺元件庫用的是 Ant Design 4.X 版本,官方文件顯示,也是支援暗黑模式的。
框架同樣基於阿里出品的 Umi3,在定製主題一欄的文件中,正好有 Umi3 使用暗黑主題的配置。
官方提供了 3 種配置方式,第一種是在 .umirc.ts 或 config/config.ts 加一個引數。
// .umirc.ts or config/config.ts export default { antd: { dark: true, // 開啟暗色主題 }, },
第二種是在全域性樣式中增加暗黑模式的 antd.dark.less 或 antd.dark.css 檔案。
@import '~antd/dist/antd.dark.less'; // 引入官方提供的暗色 less 樣式入口檔案
第三種是在 webpack.config.js 中使用 less-loader,按需引入。
module.exports = { rules: [{ test: /\.less$/, use: [{ loader: 'style-loader', }, { loader: 'css-loader', // translates CSS into CommonJS }, { loader: 'less-loader', // compiles Less to CSS + options: { + lessOptions: { // 如果使用less-loader@5,請移除 lessOptions 這一級直接配置選項。 + modifyVars: getThemeVariables({ + dark: true, // 開啟暗黑模式 + }), + javascriptEnabled: true, + }, + }, }], }], };
我想要的效果是可以開啟和關閉暗黑模式,讓使用者有更大的選擇權,採用了第二種方法。
但我是動態的引入 CSS 檔案,當按鈕開啟時,才將 CSS 檔案載入進來,關閉時再移除。
{ dark ? ( <> <link rel="stylesheet" href="//www.xxx.com/css/antd.dark.css" /> </> ) : null } <div className="layout" data-dark={dark}></div>
其中 dark 是一個內部狀態,宣告在函式元件的頂部。
const [dark, setDark] = useState(false);
在某些元素中,還會自定義該屬性值,為了在暗黑模式時重置背景或字型顏色等樣式。
.layout[data-dark=true] { .main { background-color: rgb(20, 20, 20); } .mainPer{ background-color: rgb(20, 20, 20); } .content{ background-color: rgb(20, 20, 20); } }
在改變模式的時候,會同時將狀態值快取到 localStorage 中,使用者再次進去就不用再選擇了。
localStorage.setItem('xxxx_dark', checked);
官方給的暗黑樣式,也會有些遺漏之處,需要自己在檔案中補充。
.ant-legacy-form-item-label > label { color: #FFF } .has-error .ant-input, .has-error .ant-input:hover { background-color: transparent; }
2)Ant Design Pro
最近公司有一個新的業務線,需要做一個單獨的小程式,後臺管理要求單獨做一套。
一開始先去找那些有前後端的開源專案,公司服務端使用的是 Go,那就去找這個語言的開源專案。
找到的開源專案並不盡如意,可控性和便捷性並不能那麼容易的平衡。
最後決定各自分別維護前端和後端,我們自己去找一套新的框架,他們自己設計後臺基礎介面。
我們最終選擇了 Ant Design Pro,因為我們之前的框架基於 Umi3 + And4,所以換成 Pro 後,上手成本可以低很多。
對於我們來說,就是升級而不是替換,並且 Pro 的封裝也比較完善,對於我們的日常開發綽綽有餘,於是開始著手整理。
因為原始的框架並不能完全滿足我們之前的需求,需要做些調整,期間還踩了不少坑。
例如 Umi Max 廢棄了 document.mjs 模板檔案、useRequest() 響應預設讀取的是 JSON 結構的 data 欄位。
框架預設並不提供視覺化的許可權管理,需要我自己設計,那正好用來熟悉這個框架。
總之,前前後後花了一週時間才初步整理完成。
介面規範這次也做了完善,例如所有的介面除了登入之外,都需要有身份憑證。
Authorization: Bearer XXXXX
由於是我們先行,自己還定義好了相關的介面文件以供服務端參考,格式如下面的登入介面。
// 請求 { username: '', password: '' } // 響應 { code: 0, data: { token: 'Bear UUUU', access: 'admin' }, msg: '登入正常' }
介面的 JSON 欄位(如下所示),這次也一定要明確好,不能出現多種格式。許可權的設計規則,也要與後端約定好。
{ code: 0, msg: '查詢列表正常', data: [], //或{} }
若是列表介面,在請求引數中需加上當前頁碼和每頁數量,在響應中需加上另外 3 個欄位。
// 請求 { pageSize: 10, // 每頁顯示 current: 1, // 當前頁碼 } // 響應 { total: 100, pageSize: 20, current: 1, }
Pro 全程使用 TypeScript 語法,一開始寫起來還會有點不習慣,需要慢慢適應。
使用新框架不僅僅是解決業務,也是一個學習的過程,學習設計思想、學習技術細節、學習各種規範。
雖然上手有成本,但最終來看利大於弊。