項目優(yōu)化再會requirejs

requirejs好久不見奥吩。

技術(shù)不存在過時一說,合適就好构拳。

RequireJS就是一個工具庫咆爽,它的模塊管理遵守[AMD規(guī)范],通過define方法置森,將代碼定義為模塊斗埂;通過require方法,實現(xiàn)代碼的模塊加載凫海。

最近因為一個老的項目要做優(yōu)化呛凶,該項目用requirejs做的模塊加載,說起來
這個項目架子還是甚為奇行贪。

MVC------------M和C用的是backbone,V選擇了React,而且還引入了 JSX漾稀。
代碼中使用了很多的第三方庫,另外所有的UI公共組件都是單一的jsx文件,jsx文件是一個define定義的AMD模塊(但是內(nèi)部使用了React.createElement,沒看到j(luò)sx的語法)建瘫。

經(jīng)過分析崭捍,整體上目前上的優(yōu)化手段有

1, 所有的同步ajax優(yōu)化為異步---代碼中竟然很多使用了(無特殊情況)同步的ajax請求

2啰脚, 首頁資源加載方式優(yōu)化----(首頁document.write阻塞的方式殷蛇,加載一些資源文件)

3, 全局加載資源優(yōu)化橄浓,對冗余資源去冗

4粒梦, 靜態(tài)資源分域伺服提供加載,優(yōu)化加載性能.

5贮配, 前后端分離

6谍倦, 靜態(tài)資源開啟gizp壓縮優(yōu)化,調(diào)解最小文件大小為適當(dāng)值泪勒。

以上的手段優(yōu)化后昼蛀,在其中一個復(fù)雜的多表單共存的頁面宴猾,該頁面在第一次打開時拉取.jsx得請求數(shù)竟然到達(dá)100多個,嚴(yán)重影響該頁面性能叼旋。

經(jīng)過分析仇哆,還記得前文我們說的每個UI組件都是一個jsx文件,在當(dāng)前這個復(fù)雜的頁面夫植,基本上80%以上的組件都會用上兽间,所以該頁面打開時订雾,會通過XHR去獲取所有的jsx文件,理解AMD模塊的化,應(yīng)該理解帐姻,必須 在jsx文件獲取后靠抑,才會執(zhí)行回調(diào)函數(shù)的邏輯篮奄。因此改頁面所需要的jsx必須要適當(dāng)?shù)暮喜ⅰ?/p>

define(["react","jsx!js/component",,"jsx!js/multi"],function(React,Component,Multi){
  //code
   require(["jsx!js/component1",,"jsx!js/multi2"],function(Component1,Component2){
        //code
           ....
   })
   ....
})

那怎么合并呢商叹?

肯定不是簡單的把文件合起來就好,必須做好他的依賴管理饿凛,否則當(dāng)組件間存在依賴時狞玛,就會出問題,找不到某個模塊報undefined錯誤涧窒。

因此回過頭心肪,我們再一起看看requirejs

模塊定義

無依賴的模塊

define(function () {
    return {
        method1: function() {},
        method2: function() {},
    };
});

有依賴的模塊

define(['module1', 'module2'], function(m1, m2) {
   ...
});

模塊調(diào)用

1.require(['foo', 'bar'], function ( foo, bar ) {
        foo.doSomething();
});

2. define內(nèi)注入require
define(function ( require ) {
    var isReady = false, foobar;
 
    require(['foo', 'bar'], function (foo, bar) {
        isReady = true;
        foobar = foo() + bar();
    });
 
    return {
        isReady: isReady,
        foobar: foobar
    };
});

3. 異步
define(['lib/Deferred'], function( Deferred ){
    var defer = new Deferred(); 
    require(['lib/templates/?index.html','lib/data/?stats'],
        function( template, data ){
            defer.resolve({ template: template, data:data });
        }
    );
    return defer.promise();
});

錯誤處理

requirejs.config({
    enforceDefine: true,
    paths: {
        jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min'
    }
});

//Later
require(['jquery'], function ($) {
}, function (err) {
   
    var failedId = err.requireModules && err.requireModules[0];
    if (failedId === 'jquery') {
     
        requirejs.undef(failedId);

    
        requirejs.config({
            paths: {
                jquery: 'local/jquery'
            }
        });

        
        require(['jquery'], function () {});
    } else {
       
    }
});

配置

require.config({
    paths: {
        "backbone": "vendor/backbone",
        "underscore": "vendor/underscore"
    },
    shim: {
        "backbone": {
            deps: [ "underscore" ],
            exports: "Backbone"
        },
        "underscore": {
            exports: "_"
        }
    }
});

看到這里,該文件合并了吧纠吴,對~~~~
r.js出場了

npm install -g requirejs
node r.js -o <build.js>

build.js文件內(nèi)容

({
    appDir: './',
    baseUrl: './js',
    dir: './dist',
    modules: [
        {
            name: 'main'
        }
    ],
    fileExclusionRegExp: /^(r|build)\.js$/,
    optimizeCss: 'standard',
    removeCombined: true,
    paths: {
        jquery: 'lib/jquery',
        underscore: 'lib/underscore',
        backbone: 'lib/backbone/backbone',
        backboneLocalstorage: 'lib/backbone/backbone.localStorage',
        text: 'lib/require/text'
    },
    shim: {
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: [
                'underscore',
                'jquery'
            ],
            exports: 'Backbone'
        },
        backboneLocalstorage: {
            deps: ['backbone'],
            exports: 'Store'
        }
    }
})

appDir:項目目錄硬鞍,相對于參數(shù)文件的位置。

baseUrl:js文件的位置呜象。

dir:輸出目錄膳凝。

modules:一個包含對象的數(shù)組,每個對象就是一個要被優(yōu)化的模塊恭陡。

fileExclusionRegExp:凡是匹配這個正則表達(dá)式的文件名蹬音,都不會被拷貝到輸出目錄。

optimizeCss: 自動壓縮CSS文件休玩,可取的值包括“none”, “standard”, 
“standard.keepLines”, “standard.keepComments”,
 “standard.keepComments.keepLines”著淆。

removeCombined:如果為true,合并后的原文件將不保留在輸出目錄中拴疤。

paths:各個模塊的相對路徑永部,可以省略js后綴名。

shim:配置依賴性關(guān)系呐矾。如果不是AMD模式定義的苔埋,就用shim指定模塊的依賴

generateSourceMaps:是否要生成source map文件。

一個完整的文件例子

最終本項目的的build.js如下

({
    appDir:'./',
    baseUrl: 'static',
    dir: "build",

    mainConfigFile:'./static/config.js',

    findNestedDependencies: true,
    removeCombined:true,
    generateSourceMaps:true,
    modules: [
        {
            name: "main"
        },
        {
            name: "admin"
        }
        
    ]
})

node r.js -o build.js

補(bǔ)充
因為沒有找到方法蜒犯,用r.js去處理jsx文件组橄,所以后來就把jsx文件全部改為js(因為里面并沒有使用 jsx語法荞膘,其實質(zhì)就是js),最終使得可以通過r.js處理玉工。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羽资,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子遵班,更是在濱河造成了極大的恐慌屠升,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狭郑,死亡現(xiàn)場離奇詭異腹暖,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)愿阐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門微服,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缨历,你說我怎么就攤上這事〔诼螅” “怎么了辛孵?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赡磅。 經(jīng)常有香客問我魄缚,道長,這世上最難降的妖魔是什么焚廊? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任冶匹,我火速辦了婚禮,結(jié)果婚禮上咆瘟,老公的妹妹穿的比我還像新娘嚼隘。我一直安慰自己,他們只是感情好袒餐,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布飞蛹。 她就那樣靜靜地躺著,像睡著了一般灸眼。 火紅的嫁衣襯著肌膚如雪卧檐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天焰宣,我揣著相機(jī)與錄音霉囚,去河邊找鬼。 笑死匕积,一個胖子當(dāng)著我的面吹牛盈罐,可吹牛的內(nèi)容都是我干的逻澳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼暖呕,長吁一口氣:“原來是場噩夢啊……” “哼斜做!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起湾揽,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瓤逼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后库物,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體霸旗,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年戚揭,在試婚紗的時候發(fā)現(xiàn)自己被綠了诱告。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡民晒,死狀恐怖精居,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情潜必,我是刑警寧澤靴姿,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站磁滚,受9級特大地震影響佛吓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜垂攘,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一维雇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晒他,春花似錦吱型、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掂名,卻和暖如春据沈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背饺蔑。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工锌介, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓孔祸,卻偏偏與公主長得像隆敢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子崔慧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 最近在學(xué)習(xí) Webpack,網(wǎng)上大多數(shù)入門教程都是基于 Webpack 1.x 版本的,我學(xué)習(xí) Webpack 的...
    My_Oh_My閱讀 8,185評論 40 247
  • GitChat技術(shù)雜談 前言 本文較長拂蝎,為了節(jié)省你的閱讀時間,在文前列寫作思路如下: 什么是 webpack惶室,它要...
    蕭玄辭閱讀 12,697評論 7 110
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,180評論 25 707
  • 性能優(yōu)化方向分類 請求數(shù)量: 合并腳本和樣式表温自, CSS Sprites, 拆分初始化負(fù)載皇钞, 劃分主域(使用“查找...
    Www劉閱讀 1,770評論 3 8
  • 如果 有陽光 陰穢就少 如果 有溫暖 寒冷就少 如果 有正義 邪惡會少 如果 如果 那么 那么 一定 一定 反之 ...
    旖旎i閱讀 88評論 2 8