沒(méi)有一點(diǎn)點(diǎn)防備奥帘,也沒(méi)有一絲顧慮,2017年的一半就這么飛過(guò)去了……
“回頭看看舅桩,是不是離夢(mèng)想又更遠(yuǎn)了呢酱虎?”
“滾!”
前端
其實(shí)這個(gè)上半年過(guò)得蠻刺激的擂涛,挑戰(zhàn)了一個(gè)自己以前沒(méi)什么工程經(jīng)驗(yàn)的領(lǐng)域——網(wǎng)站前端读串。
我們公司每年會(huì)填一份年終總結(jié)表,里面會(huì)問(wèn)到之后一年你想在哪方面提升自己。在去年年初寫(xiě)前年的總結(jié)時(shí)爹土,我給自己的目標(biāo)就是學(xué)習(xí)前端甥雕。不過(guò)后來(lái)由于項(xiàng)目分工,我還是主要做著后端的工作胀茵。
那時(shí)我們大部分時(shí)候的網(wǎng)站開(kāi)發(fā)主要還是兩種比較傳統(tǒng)的方式:一是后端HTML模板社露,二是后端API和前端jQuery+AJAX。直到今年年初琼娘,在農(nóng)歷年前時(shí)峭弟,我們要做一個(gè)交互比較多的網(wǎng)站,而且很可能會(huì)先上一部分功能脱拼,再根據(jù)用戶反饋?zhàn)稣{(diào)整和擴(kuò)展以后瞒瘸,才定第二版的細(xì)節(jié)。開(kāi)完那個(gè)網(wǎng)站的需求討論會(huì)后熄浓,我認(rèn)真考慮了一下情臭,覺(jué)得后端HTML模板的方式很難滿足這個(gè)網(wǎng)站的交互性,而如果用純天然原生態(tài)的jQuery+AJAX赌蔑,發(fā)布第一個(gè)版本可能還不太難俯在,但要在這個(gè)版本上再調(diào)整和維護(hù),就可能非常麻煩了——畢竟在重后端的團(tuán)隊(duì)娃惯,想把前端的工程化做好跷乐,并非一朝一夕的事情。
面對(duì)這種有一定挑戰(zhàn)的項(xiàng)目趾浅,我經(jīng)常表現(xiàn)得不(ai)夠(gao)成(shi)熟(qing)愕提。糾結(jié)了一會(huì)兒,我跟原型設(shè)計(jì)師說(shuō)皿哨,我會(huì)把一個(gè)最基本的線框原型先用Vue劃出來(lái)浅侨,然后她再到相應(yīng)的組件里填CSS。
撲通~成功給自己挖了一個(gè)新坑证膨。
其實(shí)早在14年底的時(shí)候仗颈,我就已經(jīng)注意到了Vue這個(gè)輕巧的前端框架。當(dāng)然那時(shí)的Vue還是一副“簡(jiǎn)易版Angular 1”的樣子椎例,不過(guò)那正是吸引我的地方——我在以前的實(shí)習(xí)用過(guò)一小陣子Angular 1,當(dāng)時(shí)經(jīng)驗(yàn)和認(rèn)識(shí)比現(xiàn)在還淺得多请祖,除了Controller以外寫(xiě)得真是一臉懵逼订歪,用起來(lái)和帶命名空間的DOM操作也沒(méi)有兩樣∷敛叮基礎(chǔ)都用不明白的框架還怎么深入學(xué)習(xí)刷晋?學(xué)得不深入還怎么在組內(nèi)推廣?和Angular的一身武裝相反,Vue總有一種T恤短褲眼虱,分分鐘就能搞懂并上手的感覺(jué)喻奥。不過(guò)我做為一個(gè)沒(méi)什么前端經(jīng)驗(yàn)的小菜雞,之前一直沒(méi)折騰出超過(guò)hello world級(jí)別的小demo捏悬。
這下好了撞蚕,把自己逼上梁山——直接用一個(gè)工作上相對(duì)有挑戰(zhàn)的項(xiàng)目,來(lái)在第一手的實(shí)踐中學(xué)習(xí)新姿勢(shì)——不成功便成仁过牙,啊不對(duì)甥厦,便走人。在用vue-cli把項(xiàng)目架子搭好之后寇钉,對(duì)著文檔強(qiáng)改硬擼了幾下刀疙,還真把最基本的線框UI畫(huà)好了。接下來(lái)就要考慮狀態(tài)管理了——這還真是個(gè)糾結(jié)了好一陣子的決定:是就用最直覺(jué)的vuex呢扫倡?還是設(shè)計(jì)一下加上rxjs這樣的高端貨谦秧?這個(gè)問(wèn)題我糾結(jié)了快一天,終于先把rxjs放下了撵溃,畢竟項(xiàng)目也是有死線的疚鲤,不能無(wú)止境地調(diào)研新玩具。
不記得從入手到有基本功能花了多久征懈,反正這個(gè)網(wǎng)站倒飭倒飭還真按時(shí)上線了∈В現(xiàn)在回頭再看,深刻的感受有四點(diǎn):
- 拖延癥患者拿公司項(xiàng)目來(lái)逼自己學(xué)習(xí)卖哎,起效真是飛快鬼悠。之前我在業(yè)余時(shí)間下過(guò)多少次決心想把Vue學(xué)起來(lái),全都默默地?zé)o疾而終(哪門(mén)子無(wú)疾亏娜,拖延癥不是疾是什么焕窝?!)
- 這種事情不能多干维贺,玩脫了就慘了它掂。當(dāng)時(shí)我也是冒了挺大的風(fēng)險(xiǎn),在沒(méi)有老司機(jī)帶路的情況下強(qiáng)行瞎倒騰溯泣。如果項(xiàng)目沒(méi)法按時(shí)上線虐秋,對(duì)我自己和對(duì)我們組都有很大的傷害。我也為此在遇到一些困難的時(shí)候擔(dān)心過(guò)垃沦。
- 當(dāng)然上不了線是最嚴(yán)重的結(jié)果客给,但是除此之外我當(dāng)時(shí)還有另一層考慮,就是這個(gè)項(xiàng)目如果寫(xiě)完了肢簿,真要推廣起Vue的應(yīng)用靶剑,可能會(huì)有小童鞋在做新項(xiàng)目的時(shí)候蜻拨,翻這個(gè)項(xiàng)目的代碼找參考實(shí)現(xiàn)。所以我在實(shí)現(xiàn)功能和代碼設(shè)計(jì)上時(shí)常會(huì)陷入一種平衡的糾結(jié)——是試出個(gè)方案就草草了事桩引?還是多想一想有沒(méi)有更好點(diǎn)的實(shí)踐缎讼,來(lái)給之后的童鞋多一些線索和方向?
- 沒(méi)有部門(mén)和小組對(duì)技術(shù)選型的開(kāi)放坑匠,就沒(méi)有搞事情的余地血崭,沒(méi)有搞事情的余地,就難有技術(shù)上的成長(zhǎng)笛辟。
在這次試水以后功氨,我在三月開(kāi)始安利大家用Vue來(lái)做工程化的前端。組里的小童鞋們對(duì)Vue的學(xué)習(xí)情況都不錯(cuò)手幢,新的需求和功能基本上都可以正常實(shí)現(xiàn)和交付捷凄。除了三月底四月初做的一個(gè)新網(wǎng)站,需要用一個(gè)vue-router guard來(lái)實(shí)現(xiàn)一個(gè)稍微難搞些的轉(zhuǎn)頁(yè)效果以外围来,其他的都順利解決了跺涤。哦對(duì)了,四月還被安排去臺(tái)灣出了個(gè)差监透,和做原型的設(shè)計(jì)師同事一起交流了一下桶错,也算是入職以來(lái)的一次解鎖吧。
有個(gè)獨(dú)立于上面這一大坨東西的事情胀蛮,也需要特別記錄一下院刁。最近的一個(gè)網(wǎng)站要用Canvas來(lái)畫(huà)泡泡。根據(jù)Codepen上一個(gè)demo做出來(lái)的第一版粪狼,占了我50%的CPU退腥,泡泡又各種鋸齒,簡(jiǎn)直跪得雙膝出血……后來(lái)找了一個(gè)上海分公司的React老司機(jī)幫我調(diào)整Canvas性能再榄。他大手一揮狡刘,甩回給我一個(gè)泡泡均勻綿密,CPU占用不到15%的版本困鸥,直接收走我的膝蓋嗅蔬。從他那里學(xué)到了Canvas的離屏渲染,實(shí)在是太漲姿勢(shì)了疾就。一方面要感謝一下老司機(jī)帶路澜术,一方面自己也要多打怪多升級(jí)啊。
還有一個(gè)值得小提一下的事情猬腰。有一個(gè)歷史遺留網(wǎng)站瘪板,之前沒(méi)有很好的工程設(shè)計(jì),現(xiàn)在前端要加新功能了漆诽。我嘗試著用MVC的思路寫(xiě)了一個(gè)完全獨(dú)立的模塊侮攀,純閉包無(wú)原型也無(wú)Class,用Axios取后端數(shù)據(jù)和模板文件厢拭,用Lodash來(lái)編譯模板兰英,把這個(gè)純粹基于DOM操作的舊系統(tǒng)擴(kuò)展給吭哧吭哧送上了線,也算個(gè)有趣的設(shè)計(jì)模式練習(xí)供鸠。
后端
之前對(duì)OpenResty就一直很有興趣畦贸,尤其是它的性能。繼去年用它寫(xiě)了一個(gè)簡(jiǎn)單的服務(wù)做調(diào)研以后楞捂,我對(duì)它的開(kāi)發(fā)體驗(yàn)也非常滿意薄坏。在Nginx里用OpenResty寫(xiě)服務(wù),其實(shí)和Flask有很多相同點(diǎn)寨闹,都是以URL為入口找相應(yīng)的handler(或者說(shuō)視圖函數(shù))胶坠,也都通過(guò)一些特定的“魔法”來(lái)封裝一個(gè)請(qǐng)求生命周期會(huì)需要的功能,如Flask里有request
這個(gè)線程安全的“全局”變量繁堡,而OpenResty里則把所有相關(guān)的接口都掛在ngx
這個(gè)對(duì)象上沈善。
今年初把前端的框架技術(shù)選型定下來(lái)并玩爽了以后,就開(kāi)始著手重寫(xiě)我們和游戲?qū)拥姆?wù)椭蹄。之前我們把游戲的API或者DB調(diào)用闻牡,用Django封裝了一層統(tǒng)一的API,做一定程度的業(yè)務(wù)邏輯隔離和訪問(wèn)控制∩兀現(xiàn)在這層API在訪問(wèn)量大的時(shí)候會(huì)有一定抖動(dòng)罩润,而且開(kāi)發(fā)的準(zhǔn)備步驟很復(fù)雜,文檔也相對(duì)欠缺翼馆。我在去年年底的時(shí)候就盤(pán)算著割以,找個(gè)機(jī)會(huì)把這個(gè)服務(wù)用OpenResty做一個(gè)統(tǒng)一的網(wǎng)關(guān),然后在內(nèi)部再轉(zhuǎn)發(fā)到不同游戲的“微服務(wù)”上游写妥,這些游戲相關(guān)的“微服務(wù)”可以用OpenResty來(lái)實(shí)現(xiàn)拳球,也可以用Python來(lái)實(shí)現(xiàn),依庫(kù)的完備程度和服務(wù)的性能需求而定珍特。
我花了近一周的時(shí)間祝峻,用Nginx的共享內(nèi)存做存儲(chǔ)和全局任務(wù)鎖,搞出了一個(gè)兼容舊數(shù)據(jù)庫(kù)設(shè)計(jì)的認(rèn)證網(wǎng)關(guān)扎筒。經(jīng)過(guò)初步的測(cè)試莱找,開(kāi)發(fā)筆記本上的一個(gè)Docker容器就可以達(dá)到目前線上兩臺(tái)物理機(jī)的性能,果然異步大法好啊嗜桌,還少了一層DB的IO奥溺。然后又用了一周多的時(shí)間,把一個(gè)游戲的大部分API用OpenResty實(shí)現(xiàn)了一遍骨宠,在這過(guò)程中通過(guò)各種嘗試和反復(fù)重構(gòu)浮定,根據(jù)我們這部分API基本是做上游API和數(shù)據(jù)庫(kù)的封裝和轉(zhuǎn)發(fā)這一特點(diǎn)相满,初步制定了一套非常簡(jiǎn)單的API文檔和測(cè)試接口規(guī)范,并用一個(gè)很小的工具模塊封裝起來(lái)桦卒。不過(guò)這些重寫(xiě)的API只定好了測(cè)試接口立美,測(cè)試用例還沒(méi)來(lái)得及跟上,就又雙叒叕有新的前端任務(wù)殺過(guò)來(lái)了方灾。我準(zhǔn)備等測(cè)試得完整了以后再把新的API部署上線建蹄。
技術(shù)不太相關(guān)的其他
受到蔡學(xué)鏞在微博的推薦,今年年初我終于把約翰薯黍的《軟技能》給看完了裕偿,從中明白了不少道理——很重要的一條就是洞慎,程序員其實(shí)也是一個(gè)銷(xiāo)售工種——我們賣(mài)的是服務(wù),無(wú)效的交流要排斥嘿棘,但是沒(méi)有必要排斥交流本身劲腿。所以我在上個(gè)月給一個(gè)童鞋做項(xiàng)目需求接口,一起把一個(gè)在去年就有計(jì)劃蔫巩,但是因?yàn)椴块T(mén)間的交流問(wèn)題而一直擱淺著的項(xiàng)目谆棱,一點(diǎn)一點(diǎn)地調(diào)通并實(shí)現(xiàn)了。從這件事情中圆仔,我也認(rèn)識(shí)并實(shí)踐到了不少跨部門(mén)交流合作的溝通方式垃瞧。
另外一方面,從最近一年搞的這些亂七八糟的事情來(lái)看坪郭,我覺(jué)得我有時(shí)在和小童鞋的合作中不是很有威望个从。組長(zhǎng)大人跟我說(shuō),應(yīng)該是我和小童鞋們關(guān)系太好歪沃,不容易豎立威信嗦锐;另外一個(gè)老員工跟我說(shuō),應(yīng)該是我給小童鞋太大的壓力沪曙,以至于有時(shí)起了反作用——我想可能他們都對(duì)奕污,人總是更注重關(guān)系好的朋友對(duì)自己的看法,也就更容易感覺(jué)到這樣的朋友對(duì)自己的壓力液走。最近讀到的一句話可以記下來(lái)慢慢參悟一下:世界上最傻的事碳默,就是對(duì)年輕人掏心掏肺講道理。不過(guò)明明對(duì)項(xiàng)目的交付來(lái)說(shuō)缘眶,組長(zhǎng)和老員工是要對(duì)質(zhì)量負(fù)責(zé)的嘱根,不講道理的話難道發(fā)火和用強(qiáng)權(quán)不成?不懂啊不懂(喂巷懈,說(shuō)得你自己這只小菜雞就很老一樣啊你個(gè)傻X)
展望
呼……不知不覺(jué)居然寫(xiě)了這么多(我果然是個(gè)嘴炮選手案檬恪),該給下半年定些目標(biāo)了顶燕。
現(xiàn)在我們已經(jīng)入手了一個(gè)前端的框架凑保,對(duì)團(tuán)隊(duì)來(lái)說(shuō)冈爹,最重要的就是大家的CSS水平也要跟上捂蕴,這樣團(tuán)隊(duì)的前端綜合實(shí)力才不會(huì)被制約。所以接下來(lái)一個(gè)很重要的任務(wù)就是要提高自己的CSS技巧敛滋,引入一定的CSS規(guī)范蚁署,讓網(wǎng)站靜態(tài)原型的工程質(zhì)量能在保證外觀的基礎(chǔ)上,對(duì)后期的JS+API對(duì)接更友好回懦。然后在此基礎(chǔ)上調(diào)研一些常見(jiàn)UI組件的實(shí)現(xiàn)方式,并把可復(fù)用的UI組件文檔化、系統(tǒng)化地管理起來(lái)癌蓖,方便大家的隨時(shí)引用。
另一方面就是繼續(xù)提高網(wǎng)頁(yè)的交互性了婚肆。這里有三塊內(nèi)容:一是我希望能多了解一些SVG的API租副,特別是如何用Snap這個(gè)庫(kù)來(lái)讓SVG的控制更有效,然后用SVG來(lái)到達(dá)更好的網(wǎng)頁(yè)效果较性;二是我覺(jué)得我們現(xiàn)在的webpack項(xiàng)目構(gòu)建流程以后還可以再加上圖片的壓縮和雪碧化用僧,這個(gè)可以抽時(shí)間來(lái)調(diào)研一下下,提高網(wǎng)站的加載效率赞咙,也省下開(kāi)發(fā)和設(shè)計(jì)師同事的時(shí)間责循;三就是進(jìn)一步調(diào)整網(wǎng)站靜態(tài)資源的緩存策略,還有Nginx的配置細(xì)節(jié)攀操,讓網(wǎng)站的響應(yīng)更快——這點(diǎn)感覺(jué)可以多從屈光宇大牛的博客里學(xué)習(xí)學(xué)習(xí)院仿。
說(shuō)到Nginx,我們的Relay API也需要找個(gè)空閑些的時(shí)間來(lái)把集成測(cè)試用例完善好速和,再把新的服務(wù)部署起來(lái)歹垫。畢竟這個(gè)是我們部門(mén)最基礎(chǔ)的服務(wù),而且OpenResty也是我近幾年最想深入了解的技術(shù)颠放。
昨晚看到一個(gè)很符合我三觀的Ted演講排惨,就以它為結(jié)束好了(習(xí)慣用Markdown寫(xiě)文章沒(méi)法直接插入視頻)——在奔三的這十年中期,不求活得通達(dá)明白碰凶,但求過(guò)得認(rèn)真無(wú)悔暮芭。