在協(xié)同辦公的場(chǎng)景中,Mozilla 開源的together.JS提供了非常豐富的功能基礎(chǔ)点寥,稍加修改就能滿足我們的很多需求艾疟。
上一章說了,TJS很慢敢辩,要解決這個(gè)問題就得先弄明白慢的原因是什么蔽莱?
一步步來,先從首頁(yè)加載開始责鳍。
注意:在本章需要websocket協(xié)議的相關(guān)知識(shí)碾褂,如有欠缺請(qǐng)自查百度。
3.1 首頁(yè)加載的速度優(yōu)化
我們以“tinymce”為例历葛,看看開銷大戶都有什么正塌,還是老方法,帶著問題找答案恤溶。
看著有點(diǎn)兒亂乓诽,先把這些失敗的請(qǐng)求過一遍,把無關(guān)緊要的砍掉:
- 干掉google的analytics.js咒程、ga.js 鸠天;
- 干掉tabzilla.js ;
關(guān)掉這些資源之后帐姻,效果很明顯稠集。尤其是google那幾個(gè),嚴(yán)重影響了加載時(shí)間饥瓷。索性我們把沒用的東西都拿掉剥纷,就留一個(gè)干干凈凈的編輯框,看看首頁(yè)的加載能是什么速度呢铆?
- 干掉Mozilla的Header和Footer晦鞋;
- 干掉Bootstrap、parallax和scrollspy等其他js;
- 干掉沒有的CSS悠垛;
- ……
當(dāng)我把index.hmlt 精簡(jiǎn)成上圖那樣线定,再來看看首頁(yè)的加載速度:
秒進(jìn),我們的目的達(dá)到了确买。也許首頁(yè)加載還有優(yōu)化的可能斤讥,但這不再是本文的重點(diǎn),我們解決下一個(gè)問題拇惋。
3.2 事件通知延遲的原因
在優(yōu)化之前周偎,我先介紹一下在“tinymce”這個(gè)例子中TJS的實(shí)現(xiàn)邏輯。
在together.js的背后撑帖,有這么多js的庫(kù)的支持,它們的作用都是什么呢澳眷?
備注:
為了debug方便胡嘿,要關(guān)掉git原始邏輯中的時(shí)間戳命名,方法是在together.js中注釋掉這一行钳踊。
在“tinymce”這個(gè)例子中衷敌,會(huì)用到的庫(kù)有:
- forms.js :封裝了CodeMirror 、ACE 等編輯器的交互接口拓瞪;
- session.js :業(yè)務(wù)層核心庫(kù)缴罗,定義消息規(guī)則與實(shí)現(xiàn)邏輯;
- channels.js :WebSockets 抽象接口祭埂,為session.js提供ws協(xié)議代理面氓,同時(shí)完成json的編解碼工作;
它們是如何工作的呢蛆橡?接下來我用添加一個(gè)字符為例舌界,講述他們的關(guān)系和together.js遇到的問題
- forms中的_change()方法是編輯器修改的回調(diào)接口,通過該方法能拿到編輯器中的狀態(tài)和內(nèi)容泰演;
- session中的session.send方法可以組織數(shù)據(jù)呻拌,調(diào)用channels中的_send發(fā)送websocket報(bào)文;
我們來分析一下睦焕,在上述邏輯關(guān)系中藐握,得到下面這種現(xiàn)象的原因到底是什么?
輸入一個(gè)字符垃喊,在另外一端得到響應(yīng)猾普,需要3秒以上的延遲。
- 是forms的回調(diào)慢造成的嗎缔御?不是抬闷!
- 是session組織數(shù)據(jù)太復(fù)雜造成的嗎?不是!
- 那直接的原因就是channels在封裝websocket時(shí)出了問題笤成!
3.3 事件通知延遲的優(yōu)化
TJS的模塊層次還是很清晰的评架,如果只是websocket封裝除了問題,我們只需要修改channels中的邏輯炕泳,其他內(nèi)容不變纵诞。
優(yōu)化兩個(gè)問題:
- channels都封裝了哪些接口,它內(nèi)部邏輯是什么培遵?
- 什么原因?qū)е铝搜舆t的出現(xiàn)浙芙?
TJS還是比較原始的,在_setupConnection方法中籽腕,它通過WebSocket()創(chuàng)建ws連接嗡呼,同時(shí)綁定收據(jù)收發(fā)的方法。
在這里我要聲明一下皇耗,前陣子解決這個(gè)問題的時(shí)候南窗,我并沒有找到channels內(nèi)延遲的真正原因!非常遺憾郎楼,我的解決方法是用socket.io 重寫channels模塊万伤,重寫_send和_setupConnection等方法。
最終的結(jié)果就是呜袁,把原來的3秒延遲提高到了幾十毫秒敌买,最快也幾毫秒就能得到響應(yīng)!
3.4后記
對(duì)于提速這件事阶界,有收獲也有遺憾虹钮。這些工作是在三周前就做完了。寫博客的過程也是一次回顧的過程荐操,對(duì)當(dāng)時(shí)的一些想法也有了新的認(rèn)識(shí)芜抒。這系列的文檔我會(huì)一直寫下去,預(yù)計(jì)會(huì)有五個(gè)章節(jié)托启。
對(duì)于together.js 宅倒,我的結(jié)論是:
- 這是一個(gè)非常優(yōu)秀的開源庫(kù),在協(xié)同解決方案上能給我們巨大的啟迪屯耸;
- 這是一個(gè)好用的開源庫(kù)拐迁,模塊清晰權(quán)責(zé)明確,二次修改不費(fèi)勁疗绣;
好了线召,第三章也寫完了,下一步要做的就是精簡(jiǎn)指令多矮,敬請(qǐng)期待下一章內(nèi)容缓淹!