在特定解析度下video.js會不斷觸發捲軸

這篇是 troubleshoot 的紀錄desu

最近在寫公司直播系統的前端,遇到有 user 回應他的畫面會一直「跳動」,
後來 PM 也遇到有傳錄影來,發現是 scroll 不斷出現、消失,像是下面這樣:

後來發現其實就是 scroll 會不斷出現、消失,代表有東西不斷影響網頁長度

不過到底是什麼呢?
還請了設計師來幫忙看

發現是 video.js 產生的 DOM 有兩處不斷被更新:
(vjs-progress-holder、vjs-text-track-display)

接著打開 Performance tab 錄製在跳動期間執行的動作

大致上可以看到是有頻率的在執行程式,後來仔細看大致上有兩個很常發生的操作:

  • 計算影片剩餘時間、並更新到 DOM 中
  • removeChild() 然後再 appendChild()

尤其後者看起來就效能不友善阿😂

後來是找方法關掉 progress bar、text track display 才暫時緩解這問題
不過加上 .vjs-liveui 這個 class 好像也可以

為頻繁執行的GraphQL API加上Update Lock

我有一個 GraphQL Query,他做的事情很單純:根據ID去撈出對應紀錄的欄位

query {
 getProjectStatus(id: ID!)
}

因為這支 Query 會頻繁、大量的被拉取,所以需要做 Cache。

那麼 node 有 node-cache 這個套件可以做記憶體快取,而且它可以指定 ttl(時間一過自動清除cache),
每次 request 進來除非無法從 cache 找到資料才讀取 DB

不過既然說了頻繁、大量,那麼如果在 cache 過期瞬間,有大量 request 進來,DB不就爆了嗎?
看起來為此是務必要引入 lock 機制

然後單純 lock 是不夠的,
如果大量 request 都排隊等著 acquire lock,他們就需要等很久才回應…
那麼能不能達成像 nginx proxy cache lock + background update 高速且低負載的效果呢?

可以的,
關於詳細的程式碼,我覺得可以參考 David Barral 寫的 Synchronize cache updates in Node.js with a Mutex

也可以參考下面我小調整後的程式碼,調整部份是 L18-L22


題外話,
雖然說心裡有想把這類 API 用 Restful API 改寫,
搭配 Nginx proxy cache lock + background update

只是還要多開一台小 node server,有點懶阿~

JS Callback轉成Promise

Promise + async/await 很好用,但現在還有很多 JS library 是以 event + callback 為基礎的
比如說 PM2 的 API 都像是這樣:

想把他轉成 Promise 也不是太難,因為 new Promise() 的時候有 resolve、reject 分別用來表示這兩種狀況:

  • resolve(variable):正常執行,variable代表要 return 的變數
  • reject(error):發生錯誤,error代表要 throw 的錯誤


直接來看程式碼吧
(因為這段程式碼是示範用,沒測試過)

Vuex動態註冊module

最近公司在開發的一個專案在開發完核心功能之後,上頭似乎對這個專案有了些想法,開始提出進一步的需求。

也因為逐漸增加的需求,從本來不需要Vuex、到引入Vuex;再到Vuex單一個store已經好幾百行;(實現各個需求的state, mutations, actions都放在一個store裡面)

再到發現有 store 可以被重複利用,於是使用 registerModule 做動態註冊,還用 namespace 機制存取剛剛註冊的 module

今天正是想紀錄一下這個有趣的機制還有workaround🤭

Read More »

事件API專武:Beacon API

經典使用場景是用來**蒐集事件並傳送到後端伺服器**
因為只是要蒐集事件,所以其實直接往後端傳即可,根本不用在乎後端回傳什麼
這樣就跟一般AJAX差很多了

Example use cases of the Beacon API are logging activity and sending analytics data to the server.

尤其是在**網頁要關掉那一刻**傳出的事件,用原本的AJAX是包準傳不出去的
為什麼?
因為瀏覽器不會理會那些在網頁關閉瞬間要求的AJAX,但Beacon API送出去的可以

如何使用

必須要考慮支援程度的問題

其實是老生常談了,想用比較潮的API就是該死
IE根本跟樂高一樣

偵測支不支援的方式如下

if (navigator.sendBeacon) {
  // support
} else {
  // not supported
}

example

如果要單純的API範例可以去Using the Beacon API這邊看
我個人覺得Beacon必須要有Ajax做備援方案拉
所以底下的寫法會比較兼容一點

比如說我要傳送前端的事件給後端…

可以運作的範例可以參考這裡