這篇文章主要是咱們團隊在使用Cocos Creator過程當中的一些關於部署方面的實踐總結,標題黨了一回,嚴格來講,應該是《快看漫畫遊戲研發團隊使用Cocos Creator構建部署最佳實踐》,對於其餘團隊可能並非。javascript
之因此寫這篇文章,一是我剛開始接觸Cocos Creator的時候,發現構建部署方面的一些問題,針對性寫了3篇優化的方案,隨着對Cocos Creator瞭解的深刻,我發現了一些更好的替代方法,二是由於咱們團隊隨着業務發展,又到了缺人的時候,出來刷刷臉,發點招聘廣告:Cocos Creator工程師快到碗裏來。css
不過你不用擔憂,本文不會只是炒炒冷飯,此次涉及的內容覆蓋了構建部署的整個環節,若是你恰好把代碼寫好了,你應該看看本文,它會告訴你怎麼把你的代碼漂亮的部署到線上,而且這裏涉及的代碼你均可以經過github查看。涉及知識點以下:html
因爲咱們遊戲採用的是1.6版本,因此還保留了md5版本號的優化,新的1.7版本已經比較完美支持md5的功能,但因爲沒有在實踐中使用,因此仍是基於1.6版本作一次總結,本質是同樣的。前端
本篇咱們會基於Cocos Creator的官方示例作分析,我在原demo的基礎上增長了部署的腳本,部署到又拍雲和騰訊雲。爲了展現自定義loading頁面的功能,我把這個遊戲的loading頁面改了,若是有問題,麻煩官方聯繫我下架。java
這個需求官方實際上是有提供解決方案的,官方文檔-「定製項目構建模板」的功能就能夠實現這個需求,多是文檔描述得不太清楚,我當時並無把這個功能跟「自定義加載首頁」聯繫起來。node
因爲這個構建模板功能,咱們就能夠不用gulp插件輕鬆實現自定義首頁HTML,CSS,JS的功能了。怎麼實現能夠訪問本文的項目地址查看。git
自定義loading頁面效果:github
經過gulp工具,在部署以前自動化處理一遍圖片壓縮流程,在無損壓縮的狀況下,既能保證圖片的輸出質量還能減小體積。有團隊會手動採用tinypng或者其餘壓縮工具提早壓縮,這樣作也是能夠的,但流程很差把控,原則上能自動化處理的儘可能讓機器來作,人是會累的但機器不會,也不會出錯。web
var imagemin = require("gulp-imagemin"); gulp.task("imagemin", function (cb) { gulp.src(["./build/web-mobile/**/*.png"]) .pipe(imagemin([ imagemin.gifsicle({interlaced: true}), imagemin.jpegtran({progressive: true}), imagemin.optipng({optimizationLevel: 5}) ])) .pipe(gulp.dest("./build/web-mobile/")) .on("end", cb); });`
經過gulp-htmlmin插件,把首屏的js,css文件合併到首頁html文件,能有效減小網絡不穩定狀況下進入遊戲白屏的時間。chrome
var htmlmin = require("gulp-htmlmin"); gulp.task("htmlmin", ["imagemin"], function (cb) { gulp.src("./build/web-mobile/*.html") .pipe(fileInline()) .pipe(htmlmin({ collapseWhitespace: true, removeComments: true, minifyCSS: true })) .pipe(gulp.dest("./build/web-mobile/") .on("end", cb)); });
經過合併操做,首屏loading頁面只須要加載index.html文件,在304狀況下白屏時間只有142ms!
Cocos Creator引擎build後會對代碼進行壓縮優化,但經過強大的chrome工具格式化代碼後,仍是能輕鬆閱讀代碼的總體邏輯,在競爭激烈的遊戲行業,代碼保護力度是不足夠的。因爲代碼暴露在前端,H5遊戲不存在加密可言,但咱們能夠作一些工做,增長遊戲被破解盜竊的難度。
gulp-javascript-obfuscator插件能夠對代碼進行可讀性混淆,禁止開啓chrome調試,域名綁定等功能,能很大程度保護本身的代碼,這個插件還有其餘很強大的功能,有興趣能夠訪問github瞭解。但我不建議開啓太多功能,畢竟對性能仍是有必定影響。
var javascriptObfuscator = require("gulp-javascript-obfuscator"); gulp.task("obfuscator", ["htmlmin"], function (cb) { gulp.src(["./build/web-mobile/project.js"]) .pipe(javascriptObfuscator({ compact: true, domainLock: [".zz-game.com"], mangle: true, rotateStringArray: true, selfDefending: true, stringArray: true, target: "browser" })) .pipe(gulp.dest("./build/web-mobile") .on("end", cb)); });
我採用了最輕量的混淆方案,混淆先後對比:
混淆前:
TabCtrl: [function(t, e, i) { "use strict"; cc._RF.push(e, "62208XJq9ZC2oNDeQGcbCab", "TabCtrl"), cc.Class({ extends: cc.Component, properties: { idx: 0, icon: cc.Sprite, arrow: cc.Node, anim: cc.Animation }, init: function(t) { this.sidebar = t.sidebar, this.idx = t.idx, this.icon.spriteFrame = t.iconSF, this.node.on("touchstart", this.onPressed.bind(this), this.node), this.arrow.scale = cc.p(0, 0) } }), cc._RF.pop() } , {}] }, {}, ["ItemList", "ItemTemplate", "BackPackUI", "ButtonScaler", "ChargeUI", "EnergyCounter", "HeroSlot", "HomeUI", "PanelTransition", "ShopUI", "SubBtnsUI", "MainMenu", "MenuSidebar", "TabCtrl"]);
混淆後:
'l': [function(b, a, c) { 'use strict'; cc[_0xc008('0x12')][_0xc008('0x13')](a, _0xc008('0x98'), 'l'), cc['T']({ 'S': cc['U'], 'O': { 'idx': 0x0, 'icon': cc[_0xc008('0x3e')], 'arrow': cc['Node'], 'anim': cc['Animation'] }, '_': function(a) { this[_0xc008('0x68')] = a[_0xc008('0x68')], this['idx'] = a[_0xc008('0x7b')], this[_0xc008('0x66')][_0xc008('0x47')] = a[_0xc008('0x65')], this[_0xc008('0x1b')]['on'](_0xc008('0x99'), this[_0xc008('0x9a')][_0xc008('0x5e')](this), this[_0xc008('0x1b')]), this[_0xc008('0x9b')][_0xc008('0x9c')] = cc['p'](0x0, 0x0); } }), cc[_0xc008('0x12')][_0xc008('0x20')](); } , {}] }, {}, ['i', 'd', 'f', 'c', 'j', 'b', 'h', 'n', 'a', 'm', 'g', 'k', 'e', 'l']);
在不影響性能的前提下,稍微作一些代碼保護,仍是不錯的。若是你想讓代碼更噁心一點也是能夠的:
a.DFsJp; cc[a[_0xc91c('0x43a')](_0x490d30, a[_0xc91c('0x43b')])][a[_0xc91c('0x43c')](_0x490d30, _0xc91c('0xe5'))](b, a[_0xc91c('0x43c')](_0x490d30, a['\x68\x6d\x41\x4c\x54']), '\x6c'), cc['\x54']({ 'S': cc['\x55'], 'O': { 'idx': 0x0, 'icon': cc[_0x490d30(_0xc91c('0x249'))], 'arrow': cc['\x4e\x6f\x64\x65'], 'anim': cc[a[_0xc91c('0x43d')]] }, '_': function(b) { this[a[_0xc91c('0x43e')](_0x490d30, _0xc91c('0x31c'))] = b[a[_0xc91c('0x43e')](_0x490d30, '\x30\x78\x36\x38')], this[a[_0xc91c('0x43f')]] = b[_0x490d30(a[_0xc91c('0x440')])], this[_0x490d30(a[_0xc91c('0x441')])][_0x490d30(a['\x6b\x77\x71\x63\x72'])] = b[_0x490d30(a[_0xc91c('0x442')])], this[_0x490d30(_0xc91c('0x1c0'))]['\x6f\x6e'](a[_0xc91c('0x43e')](_0x490d30, a[_0xc91c('0x443')]), this[a['\x45\x79\x7a\x47\x44'](_0x490d30, a['\x6a\x64\x44\x61\x6e'])][_0x490d30(_0xc91c('0x2e0'))](this), this[a[_0xc91c('0x444')](_0x490d30, _0xc91c('0x1c0'))]), this[a[_0xc91c('0x445')](_0x490d30, _0xc91c('0x446'))][a[_0xc91c('0x445')](_0x490d30, a[_0xc91c('0x447')])] = cc['\x70'](0x0, 0x0);
開啓debugProtection功能:
打開chrome調試工具就會觸發無限循環的dubugger,讓chrome調試工具沒法使用,增大破解難度。爲了方便你們查看學習demo,線上版本我關閉了這個選項。
開啓disableConsoleOutput功能:
禁止console.log功能,不少混淆代碼,經過斷點+console.log,能夠方便把翻譯後的代碼輸出,開啓disableConsoleOutput,一樣增長調試難度。爲了把咱們的廣告無處不在,我一樣把它關了。JavaScript obfuscator還有其餘不錯的功能,這裏再也不展開。
版本號的方案跟以前的文章基本一致,這個流程在1.7版本應該能夠忽略了。
gulp.task("resRev", ["obfuscator"], function (cb) { gulp.src(["./build/web-mobile/**/*.js", "./build/web-mobile/*.png"]) .pipe(rev()) .pipe(gulp.dest("./build/web-mobile/")) .pipe(rev.manifest()) .pipe(gulp.dest("./build/web-mobile/") .on("end", cb)); }); gulp.task("default", ["resRev"], function (cb) { del(["./build/web-mobile/src"]); gulp.src(["./build/web-mobile/*.json", "./build/web-mobile/index.html"]) .pipe(revCollector()) .pipe(gulp.dest("./build/web-mobile/")); gulp.src(["./build/web-mobile/*.json", "./build/web-mobile/main*.js"]) .pipe(revCollector({ replaceReved: true })) .pipe(gulp.dest("./build/web-mobile/") .on("end", cb)); });
經過md5+強緩存,第二次加載基本是毫秒級,瞬開。
116個請求的頁面,只須要109ms就能渲染出loading頁面,徹底加載全部資源只須要1.25s:
最後是把代碼部署到cdn,如今的雲服務都提供cdn分發的功能,經過簡單配置,我相信你能折騰出來的,因此再也不贅述。
這裏主要作不一樣方案的演示,我部署了兩個方案:直接回源和cdn分發。
首次訪問
在Wifi網絡下,回源方案耗時6-10s,cdn分發方案耗時3-6s。
第二次訪問
因爲增長了強緩存,不管是cdn仍是回源,第二次訪問時間都在1-2s之間。
這個項目自己存在先天不足,例如圖片沒有合併,致使首次請求有116個,加載速度確定會受影響。但經過cdn緩存方案,也能基本保證快速加載。
又拍cdn方案:
騰訊回源方案:
代碼我已經部署到了又拍雲和騰訊雲,你們能夠點擊訪問感覺加載速度。
cdn是比較好的優化首次訪問網絡速度的方案,但cdn也不是必然比源站快,你們測試時發現回源更快也沒必要驚訝,本質上cdn節點就是距離你更近的代理服務器,但也有不少狀況致使cdn緩慢,因此部署後還要經過工具多測試各個cdn節點的情況。
遊戲優化確定不只僅這幾條,有不少優化要根據實際狀況實際分析。但這6點實踐,應該能夠解決論壇常常提到的緩存刷新,加載速度等部署相關的問題。
資源md5+cdn+強緩存 能解決80%H5遊戲加載速度的問題,特別是第二次訪問,2秒打開輕輕鬆鬆,基本已經成爲web前端優化的工業標準方案。但如今不少線上的H5遊戲還有不少走url參數+時間戳/md5的老方案,這種方案有不少弊端。但願經過本文,你們都能在本身的遊戲內把資源md5+cdn+強緩存的方案貫徹執行起來。其實很簡單,特別是Cocos Creator1.7版本後就更方便了。H5遊戲的優點就是即點即玩,若是這點都作不到,就沒什麼優點了。
說了這麼多,你可能以爲實踐起來很麻煩,業務太多沒時間搞這些。
不要緊,本文買一送一,既然你看到這裏,說明你也是有緣之人,我把代碼倉庫也贈送給你,例子源碼我放在了github cocos-fly上,有須要你們能夠上去下載。
把gulpfile.js和releash.sh扒下來,只須要執行命令:sh releash
,就能夠一鍵構建出可發佈的代碼。
線上示例+源碼+教程一條龍,還不趕忙引入本身的項目?。