近幾個月我一直都在處理公司廣告平臺前端展示的程式碼。幾個月下來見證著廣告前端工程從無到有、從無規律到模組化、從技術架構到業務邏輯,收穫頗豐,故此記錄一下我與廣告的點點滴滴。
一、事件起因:
我所在的房產網站有兩條大的業務線(業務線甲、業務線乙 代替),分別由兩個大的團隊管理,基本沒有交集。之前兩條業務線都是用的廣告方案相同(本文用老程式碼代替)。2015年初,由於這套老程式碼由於維護成本過高、與頁面耦合高、並且稍一改動頻頻出bug等問題。廣告組和業務線甲共同商議、打算在業務線甲首頁改版之後,重構這套前端展示用的程式碼(本文中稱為ad甲.js)並先由首頁試用ad甲.js。
二、原來的老程式碼是什麼樣的?為什麼要重構它?
廣告在頁面上展示是分廣告型別的,每個型別對應多個廣告位(例項)。我們通常是在頁面布碼(預設隱藏),頁面載入後再用js動態載入。那麼老程式碼是怎麼做的呢?老程式碼中把向個廣告位(id)中加入廣告的行為封閉成多了立即執行函式,每個例項單獨處理,沒有類的概念。如果有相同的廣告型別,就ctrl CV ;多人維護程式碼風格迥異;依賴頁面中引入的類庫。簡單來說,就是以廣告位為單位的多個js片段。那麼這樣的程式碼怎麼使用呢?後臺同學根據頁面廣告位的使用,將這些廣告位分別打包成多個js檔案,分別引用。對於一些可變的資料。就將js通過script標籤吐到頁面上,並通過PHP變數的方式修改展示用的資料。
顯然,這樣的結構對於前端同學來說是很頭疼的,pv統計要分別copy到每個例項的js片段中、無法統一修改公用的部分、沒有可複用的邏輯、大量使用with和eval函式、不僅js依賴頁面環境,而且沒有邏輯性、複用性、和可讀性和統一性。看來老程式碼的重構是很難避免了。
三、臨危受命、時間緊、任務重。
時間只有一個多月。在leader的指導下,我開始了這段程式碼的重構,也就是從這一刻起我與廣告結下了不解之緣。
當然重構的不僅僅是前端程式碼。後端的邏輯也要變。原先的後臺不僅要給js碎片打包,還要負責吐在頁面中的廣告資料。這樣維護業務線甲的後端就和廣告的後端耦合在了一起。新的架構中業務線甲的後端只負責頁面相關的邏輯。而廣告組的後端只提供一個能訪問到對應於頁面的Ajax介面。前端也變成一個專門處理廣告渲染的js檔案。
當然在這麼短的時間下重構的程式碼雖說解決了不少的問題,但仍然有很多的不足之處,下一篇文章會詳細說明。
四、前端程式碼重構之後的結構
1、單一的js檔案
重構之後將原有的多個js片段改為一個js檔案,業務線甲的每個頁面只要引用同一個js檔案就可以了。在加上一些config語句。這樣js負責根據config中的變數判斷是哪個城市以及哪個頁面,並根據這些向後臺獲取廣告資料。廣告的渲染與廣告資料解耦。使得資料與顯示分離。每個頁面對js的引用方式變得統一。
2、jsonp非同步獲取資料
在頁面的config語句中獲取頁面的特徵引數,非同步的獲取廣告資料。當然這少不了廣告組提供的ajax的介面。考慮到業務線甲和廣告業務的伺服器存在跨域的問題。我們採用jsonp的方式從廣告的後端獲取資料。通過1、2這兩個步驟,廣告的後端和業務線甲的後端就解耦了。
3、模組管理
使用requireJS和 對應的r.js打包,一些通用的工具函式也抽象成工具箱模組。將每個廣告的型別分別定義成對應的模組。模組間也有了繼承關係,我可以在父類處理一些統一的東西(比如pv統計),也可以在子類加入一些特性化的東西。
4、對頁面的js庫的依賴。
既然使用了requireJS,那麼不妨將所需的依賴加入到工程,一同打包。就不需要每個頁面都判斷一遍了。比如jquery和underscore,相信我會經常用到裡面強大的API。但不見得業務線甲上每個宿主頁面都有這些東西並且是我想要的版本。
5、複用老程式碼中的特型邏輯
老程式碼中還是有很多的特性處理邏輯可以複用,由於時間比較緊,完全的重構也很有風險。我們可以拿來複用一部分,並封裝成AMD風格的模組。
總結下來我們這一次還只是程式碼結構上的重構,很多的廣告展示上的程式碼並沒有完全修改,一開始提出的問題被一一解決。但是基本的結構有了,剩下的就一步一步來吧。
五、這條路還在繼續
就這樣,在短短一個多月的時間裡我們的ad甲.js重構完成了。但是它仍有一些的問題需要不斷地完善。目前也只是在首頁加入ad甲.js,後期就要在業務線甲的全站對接未知的宿主頁面環境以及各個頁面帶來的歷史性的佈局合理性問題,將不斷的考驗著我和我的廣告前端程式碼。我與廣告的故事還沒結束。