現(xiàn)在Web富應(yīng)用越來越多, 越來越多網(wǎng)站朝單頁面發(fā)展, 所有功能模塊都在一個頁面中創(chuàng)建. 作為一個合格的前端, 所負責的模塊一定是邏輯跟UI分離的, 通常的做法就是頁面代碼編寫成模板, 然后往模板填充數(shù)據(jù)并輸出到頁面上. 關(guān)于前端模板的介紹和使用我就不說了, 不了解的可以先看看這篇文章(http://www.css88.com/archives/4564), 這里討論下使用模板引擎引入的另外一個問題(也不是Bug啦~) — 頁面模板代碼放哪?
呼~~總算到正題了(- -||). 說回來, 頁面模板的代碼到底要放哪呢?
話說很久很久以前, 我也是把模板寫在js里面的, 然后需要修改的時候就崩潰了~ 在一堆字符串里面找到想要改動的地方就像是在一坨黃色的屎里面找個金戒指(惡…). 過了不久學(xué)乖了, 把模板像寫html那樣換行和縮進, 就跟下面一樣.
1 2 3 4 5 | var html = '\ <div id="container">\ <div>...</div>\ <div>...</div>\ </div>' |
然后代價是 — 要給會混淆的引號轉(zhuǎn)義以及每行末尾都要一個反斜杠! oh~天啊, 我可是程序員啊, 為什么要做這種重復(fù)無趣的工作!
于是很久很久以前的以后, 我又學(xué)乖了一次, 咱這次把模板寫在html頁面里面, 放到一個特殊的script標簽內(nèi), 用到的時候根據(jù)id找到這個script, 讀取innerHTML拿來用. 哇, 簡直是perfect!~~吼吼~~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /** * shot of getElementById * @param {String} id */ this .get = function (id){ return document.getElementById(id); } var templateList = {}; /** * 獲取頁面的一個 html 模板 * @param {String} tmplId 模板的 dom id */ this .getTemplate = function (tmplId){ var tmpl = templateList[tmplId]; if (!tmpl){ var tmplNode = this .get(tmplId); tmpl = tmplNode.innerHTML; tmplNode.parentNode.removeChild(tmplNode); templateList[tmplId] = tmpl; //緩存起來, 避免再次查找dom } if (!tmpl){ throw new Error( 'no such template. [id="' + tmplId + '"]' ); } return tmpl; } |
從此, 模板和頁面過著幸??鞓返纳睢缓笾钡接幸惶臁?/p>
A: 為什么打開頁面的那個菊花轉(zhuǎn)那么久!
我:…
然后就如五雷轟頂般的醒悟, 由于是單頁面, 模板都堆積到頁面, 大大增加了首頁的大小, 沒什么邏輯的頁面竟然有37KB(gzip前). 更因為js/css/images等都放到了多臺cdn, 讀取速度快而且可以設(shè)置和利用瀏覽器cache. 而html頁面則只放在一臺web server, 而且因為版本迭代比較快, 不能給html設(shè)置緩存策略(那樣會導(dǎo)致用戶那里不能及時更新).
王子和公主就這樣被硬生生拆散了~T_T
如果現(xiàn)在要我把模板都改成js變量, 放到j(luò)s文件里, 我一定死給他看, 哼~
然而, 只是, 可是, 但是, 加載速度還是得優(yōu)化啊. 既然開發(fā)的時候要方便, 發(fā)布之后要速度, 那發(fā)布前用腳本把模板抽取到j(luò)s文件中不就結(jié)了? 頓時感覺柳暗花明又一村呀~~呼啦啦啦~~
抽取的步驟為:
至于抽取用什么語言寫都沒所謂啦, 僅僅是正則和文件操作, 推薦用nodejs, 真是太方便了. 不過大部分機器都木有裝, 需要自己裝. 有些環(huán)境不能隨便裝新程序, 那也可以用python寫個, 花半個鐘現(xiàn)學(xué)現(xiàn)用就夠了. 附上個NodeJs版的.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | var fs = require( 'fs' ); var inputHtmlFile = './index.html' ; var outputHtmlFile = './out/index.html' ; var inputJsFile = './js/mb.templates.js' var outputJsFile = './out/js/mb.templates.js' ; var content = fs.readFileSync(inputHtmlFile).toString(); var regex = /<script\s*id= "(\w+)" \s*type= "text\/plain" \s*>([\s\S]*?)<\/script>/ig; var result = {}; content = content.replace(regex, function (m, $1, $2){ result[$1] = $2.replace(/\n|\r/g, '' ); return '' ; }); fs.writeFileSync(outputHtmlFile, content); content = fs.readFileSync(inputJsFile).toString(); var templateStr = JSON.stringify(result); content = content.replace( '{%HtmlTemplates%}' , templateStr); fs.writeFileSync(outputJsFile, content); |
經(jīng)過這么一搞, 把模板代碼抽出來之后, 首頁的大小立馬從37KB降到1.7KB. 雖然是個小技巧, 也足以成大謀. 那感覺, 可是跟漲薪一樣爽哇~~