2015-11-20 4 views
9

मेरे पास jQuery, रिएक्ट और सॉकेटियो पर निर्भरताओं के साथ "मध्यम" टाइपस्क्रिप्ट एप्लिकेशन (जैसा कि मामूली नहीं है, लेकिन एंटरप्राइज़-स्तर या तो कई हजार लाइनें नहीं है) अन्य छोटे पुस्तकालयों।ब्राउजरिफ़ + के साथ प्रदर्शन समस्या + देखें + Tsify + Gulp

मेरे वर्तमान gulpfile यह है:

var gulp = require("gulp"), 
    $ = require("gulp-load-plugins")(), 
    _ = require("lodash"), 
    tsify = require("tsify"), 
    browserify = require("browserify"), 
    source = require("vinyl-source-stream"), 
    debowerify = require("debowerify"), 
    watchify = require("watchify"), 
    lr = require("tiny-lr"), 
    buffer = require("vinyl-buffer"); 

var lrServer = lr(); 

var config = { 
    scripts: { 
     base: __dirname + "/Resources/Scripts", 
     main: "Application.ts", 
     output: "App.js" 
    }, 

    styles: { 
     base: __dirname + "/Resources/Styles", 
     sheets: ["Application.less", "Preload.less"], 
     autoprefixer: ["last 2 version", "safari 5", "ie 8", "ie 9", "opera 12.1", "ios 6", "android 4"] 
    }, 

    publicPath: __dirname + "/wwwroot" 
}; 

function printError(err) { 
    $.util.log($.util.colors.red.bold(err.type + " " + err.name + ":"), $.util.colors.white(err.message)); 
    this.emit("end"); 
} 

function buildScripts(watch, debug) { 
    var bundler = browserify({ 
      basedir: config.scripts.base, 
      debug: false, 
      entries: [config.scripts.base + "/" + config.scripts.main], 
      cache: {}, 
      packageCache: {} 
     }) 
     .plugin(tsify, { 
      module: "commonjs", 
      target: "es5", 
      jsx: "react" 
     }) 
     .transform(debowerify); 

    function build() { 
     return bundler.bundle() 
      .on("error", printError) 
      .pipe(source(config.scripts.output)) 
      .pipe($.if(!debug, buffer())) 
      .pipe($.if(!debug, $.uglify())) 
      .pipe(gulp.dest(config.publicPath + "/" + "scripts")); 
    } 

    if (!watch) 
     return build(); 

    bundler 
     .plugin(watchify) 
     .on("update", function() { 
      $.util.log($.util.colors.grey("Building scripts...")); 
      build(); 
     }) 
     .on("time", function (timeMs) { 
      $.util.log(
       $.util.colors.grey("Finished"), 
       $.util.colors.cyan("'dev.scripts.watch' after"), 
       $.util.colors.magenta(timeMs.toLocaleString() + " ms")); 
     }); 

    return build(); 
} 

gulp.task("prod.scripts", function() { 
    return buildScripts(false, false); 
}); 

gulp.task("dev.scripts", function() { 
    return buildScripts(false, true); 
}); 

gulp.task("dev.scripts.watch", function() { 
    return buildScripts(true, true); 
}); 

gulp.task("prod.styles", function() { 
    return gulp 
     .src(_.map(config.styles.sheets, function (sheet) { return config.styles.base + "/" + sheet; })) 
     .pipe($.less()) 
     .on("error", printError) 
     .pipe($.autoprefixer(config.styles.autoprefixer)) 
     .pipe($.uglifycss()) 
     .pipe(gulp.dest(config.publicPath + "/styles/")); 
}); 

gulp.task("dev.styles", function() { 
    return gulp 
     .src(_.map(config.styles.sheets, function (sheet) { return config.styles.base + "/" + sheet; })) 
     .pipe($.sourcemaps.init()) 
     .pipe($.less()) 
     .on("error", printError) 
     .pipe($.autoprefixer(config.styles.autoprefixer)) 
     .pipe($.sourcemaps.write()) 
     .pipe(gulp.dest(config.publicPath + "/styles/")); 
}); 

gulp.task("dev.styles.watch", ["dev.styles"], function() { 
    return gulp.watch(config.styles.base + "/**/*.{css,less}", ["dev.styles"]); 
}); 

gulp.task("dev.watch", ["dev.scripts.watch", "dev.styles.watch"], function() { 
    lrServer.listen(35729); 

    gulp.watch(config.publicPath + "/styles/**").on("change", function(file) { 
     lrServer.changed({ body: { files: [file.path] } }); 
    }); 
}); 

gulp.task("dev", ["dev.styles", "dev.scripts"]); 
gulp.task("prod", ["prod.styles", "prod.scripts"]); 

सब कुछ काम करता है के रूप में उम्मीद, हालांकि, निर्माण के समय जब घड़ी कार्य का उपयोग कर कई सेकंड ले रहे हैं। अजीब चीज यह है कि मेरा कार्य रिपोर्ट करता है कि स्क्रिप्ट का पुन: संकलन 500ms से कम ("टाइम" ईवेंट पर ईवेंट हैंडलर) में होता है, फिर भी अगर मैं अपने सिर में गिनती करता हूं तो यह तीन से चार सेकंड तक खत्म नहीं होता है ।

ध्यान दें कि मैंने अपने मौजूदा टाइपस्क्रिप्ट कोड में चिपकाए जाने से पहले, मैं jQuery, प्रतिक्रिया, क्षण और अन्य पुस्तकालयों को लोड/बंडल कर रहा था जो मैं बहुत तेज़ी से उपयोग कर रहा था। इस वजह से, मुझे नहीं लगता कि एक अलग विक्रेता बंडल का उपयोग कुछ भी तेज होगा। साथ ही, स्रोतमैप लिखना भी प्रदर्शन को प्रभावित नहीं करता है।

ब्राउज़र ब्राउज़र पर स्विच करने से पहले, मैं मॉड्यूल लोडिंग के लिए संकलन और requjs के लिए gulp-typecript का उपयोग कर रहा था। उन निर्माणों को एक सेकंड के तहत लिया गया। हालांकि, requjs अन्य कारणों से मुद्दों का कारण बन रहा था - और किसी भी तरह से, मैं एएमडी से कॉमनजेएस में जाना चाहता हूं।

अभी के लिए यह एक बहुत बड़ा चिंता का विषय नहीं है, लेकिन के रूप में परियोजना बढ़ता है यह निश्चित रूप से मेरे विकास के प्रवाह के साथ समस्याओं का कारण बन सकता है। एक परियोजना के साथ केवल इतना बड़ा, किसी भी चीज को संसाधित करने में कितना समय लगेगा?

इसके अलावा, यह विजुअल स्टूडियो के साथ भी समस्याएं पैदा कर रहा है। यह एक एएसपी.नेट 5 एप्लीकेशन है, और विजुअल स्टूडियो स्पष्ट रूप से बंडल किए गए जावास्क्रिप्ट फ़ाइल को फिर से लोड/पुनः पार्स करने पर जोर देता है, हर बार परिवर्तन के बाद 1-2 सेकंड के लिए आईडीई में अंतराल होता है: शीर्ष पर 3-4 सेकेंड में यह पुन: संकलन के लिए खुद लेता है। स्क्रिप्ट को मेरे wwwroot फ़ोल्डर में प्रस्तुत किया जा रहा है, और एएसपी.NET 5 टूलिंग के साथ स्क्रिप्ट उप-फ़ोल्डर को "बहिष्कृत" करने का कोई तरीका नहीं है।

मुझे पता है कि मुझे कहीं कुछ याद आ रहा है। एक संभावित मुद्दा यह है कि tsify reloading को लागू करने के लिए टाइपस्क्रिप्ट की "प्रोजेक्ट" सुविधा का उपयोग नहीं कर रहा है, जिससे टाइपस्क्रिप्ट कंपाइलर प्रत्येक बदलाव के लिए प्रत्येक फ़ाइल को पुन: संसाधित करने का कारण बनता है।

वैसे भी, मैं अकेला व्यक्ति नहीं हो सकता जिसने खिलौनों की परियोजनाओं से परे इन उपकरणों का उपयोग किया है, इसलिए मैं यहां पूछ रहा हूं कि किसी के पास बेहतर समाधान है; चूंकि इस मुद्दे के अलावा, सबकुछ बहुत अच्छी तरह से काम कर रहा है।

संपादित --------------------------------

ठीक है, वाला अपने ही शब्द खाने के लिए है । बिल्ड अब लगभग एक सेकंड तक नीचे आ गए हैं कि मैं अपने तीसरे पक्ष के पुस्तकालयों को अपने स्वयं के बंडल में बांट रहा हूं। यहाँ मेरी अद्यतन gulpfile (नोटिस नई dev.scripts.vendor कार्य और buildScripts समारोह में .external कॉल)

var gulp = require("gulp"), 
    $ = require("gulp-load-plugins")(), 
    _ = require("lodash"), 
    tsify = require("tsify"), 
    browserify = require("browserify"), 
    source = require("vinyl-source-stream"), 
    debowerify = require("debowerify"), 
    watchify = require("watchify"), 
    lr = require("tiny-lr"), 
    buffer = require("vinyl-buffer"); 

var lrServer = lr(); 

var config = { 
    scripts: { 
     base: __dirname + "/Resources/Scripts", 
     main: "Application.ts", 
     output: "App.js", 
     vendor: ["react", "jquery", "moment", "socket.io-client", "lodash", "react-dom"] 
    }, 

    styles: { 
     base: __dirname + "/Resources/Styles", 
     sheets: ["Application.less", "Preload.less"], 
     autoprefixer: ["last 2 version", "safari 5", "ie 8", "ie 9", "opera 12.1", "ios 6", "android 4"] 
    }, 

    publicPath: __dirname + "/wwwroot" 
}; 

function printError(err) { 
    $.util.log($.util.colors.red.bold(err.type + " " + err.name + ":"), $.util.colors.white(err.message)); 
    this.emit("end"); 
} 

function buildScripts(watch, debug) { 
    var bundler = browserify({ 
      basedir: config.scripts.base, 
      debug: false, 
      entries: [config.scripts.base + "/" + config.scripts.main], 
      cache: {}, 
      packageCache: {} 
     }) 
     .plugin(tsify, { 
      module: "commonjs", 
      target: "es5", 
      jsx: "react" 
     }); 

    if (debug) 
     bundler.external(config.scripts.vendor); 

    function build() { 
     return bundler.bundle() 
      .on("error", printError) 
      .pipe(source(config.scripts.output)) 
      .pipe($.if(!debug, buffer())) 
      .pipe($.if(!debug, $.uglify())) 
      .pipe(gulp.dest(config.publicPath + "/" + "scripts")); 
    } 

    if (!watch) 
     return build(); 

    bundler 
     .plugin(watchify) 
     .on("update", function() { 
      $.util.log($.util.colors.grey("Building scripts...")); 
      build(); 
     }) 
     .on("time", function (timeMs) { 
      $.util.log(
       $.util.colors.grey("Finished"), 
       $.util.colors.cyan("'dev.scripts.watch' after"), 
       $.util.colors.magenta(timeMs.toLocaleString() + " ms")); 
     }); 

    return build(); 
} 

gulp.task("prod.scripts", function() { 
    return buildScripts(false, false); 
}); 

gulp.task("dev.scripts", ["dev.scripts.vendor"], function() { 
    return buildScripts(false, true); 
}); 

gulp.task("dev.scripts.vendor", function() { 
    return browserify({ 
      debug: true, 
      cache: {}, 
      packageCache: {}, 
      require: config.scripts.vendor 
     }) 
     .bundle() 
     .on("error", printError) 
     .pipe(source("Vendor.js")) 
     .pipe(gulp.dest(config.publicPath + "/" + "scripts")); 
}); 

gulp.task("dev.scripts.watch", ["dev.scripts.vendor"], function() { 
    return buildScripts(true, true); 
}); 

gulp.task("prod.styles", function() { 
    return gulp 
     .src(_.map(config.styles.sheets, function (sheet) { return config.styles.base + "/" + sheet; })) 
     .pipe($.less()) 
     .on("error", printError) 
     .pipe($.autoprefixer(config.styles.autoprefixer)) 
     .pipe($.uglifycss()) 
     .pipe(gulp.dest(config.publicPath + "/styles/")); 
}); 

gulp.task("dev.styles", function() { 
    return gulp 
     .src(_.map(config.styles.sheets, function (sheet) { return config.styles.base + "/" + sheet; })) 
     .pipe($.sourcemaps.init()) 
     .pipe($.less()) 
     .on("error", printError) 
     .pipe($.autoprefixer(config.styles.autoprefixer)) 
     .pipe($.sourcemaps.write()) 
     .pipe(gulp.dest(config.publicPath + "/styles/")); 
}); 

gulp.task("dev.styles.watch", ["dev.styles"], function() { 
    return gulp.watch(config.styles.base + "/**/*.{css,less}", ["dev.styles"]); 
}); 

gulp.task("dev.watch", ["dev.scripts.watch", "dev.styles.watch"], function() { 
    lrServer.listen(35729); 

    gulp.watch(config.publicPath + "/styles/**").on("change", function(file) { 
     lrServer.changed({ body: { files: [file.path] } }); 
    }); 
}); 

gulp.task("dev", ["dev.styles", "dev.scripts"]); 
gulp.task("prod", ["prod.styles", "prod.scripts"]); 

हालांकि है, मैं अभी भी एक अजीब मुद्दा हो रही है। Sourcemaps अक्षम होने के साथ (जो अब तक गति पर प्रभाव डालता है), मेरा चालू ("समय",() => {}) कॉलबैक प्रत्येक फ़ाइल परिवर्तन के लिए 60-80ms की रिपोर्ट कर रहा है, लेकिन यह अभी भी लगभग एक सेकंड तक लटकता है । एक सेकंड यह है कि मैं इसके लिए इंतजार करने के लिए तैयार हूं, इसलिए फिर मुझे चिंता है कि जैसे ही परियोजना बढ़ती है, यह प्रतीक्षा भी बढ़ सकती है।

यह देखना दिलचस्प होगा कि इस अतिरिक्त दूसरे समय पर क्या खर्च किया जा रहा है, जब घटना कुछ छोटी रिपोर्टिंग कर रही है।शायद मैं स्रोत में खुदाई शुरू कर दूंगा क्योंकि ऐसा लगता है कि बल्ले से कोई जवाब नहीं है।

किसी अन्य समस्या यह सिर्फ एक sidenote है, लेकिन debowerify अब इसके साथ काम नहीं करता है। Debowerify + bower का उपयोग करते समय, यह अंतिम आउटपुट में आवश्यक मॉड्यूल प्रस्तुत करना जारी रखेगा, भले ही वह मॉड्यूल "बाहरी" सूची में सूचीबद्ध हो। तो वर्तमान में इस सेटअप के साथ, मैं केवल एनपीएम मॉड्यूल का उपयोग कर सकता हूं जब तक कि मैं अपने ऐप बंडल में अधिक संकलन समय जोड़ने के साथ ठीक नहीं हूं।

इसके अलावा, मैंने सीखा है कि debowerify एनपीएम मॉड्यूल को ओवरराइड करेगा, और यह bower_components की निर्देशिका सूची से अलग है, न कि आपकी बॉवर कॉन्फ़िगरेशन फ़ाइल। मैंने jQuery को एनपीएम में स्थापित किया था, और केवल बॉवर में बूटस्ट्रैप; लेकिन चूंकि बूटस्ट्रैप ने एक निर्भरता के रूप में jQuery को खींच लिया, इसलिए बीओवर jQuery मॉड्यूल को एनपीएम jQuery पर वरीयता से लोड किया जा रहा था। बस लोगों के लिए एक सिर।

+1

बस एक विचार का उपयोग करें: यह अनिवार्य रूप से एक रूपरेखा काम है। 'Var डीबग = आवश्यकता (' gulp-debug ') जोड़ने के बारे में क्या; 'और' .pipe (डीबग ({शीर्षक:' आपका संदेश: '}))' यह पता लगाने के लिए कि कौन से हिस्से धीमे हैं? मुझे आश्चर्य है कि स्रोतमैप धीमे नहीं हैं, इसने मेरे कंप्यूटर पर एक बिल्ड प्रक्रिया को धीमा कर दिया है। हम गल्प-टाइपस्क्रिप्ट का उपयोग करते हैं और प्रारंभिक संकलन में 10 सेकंड तक लगते हैं लेकिन फिर वृद्धिशील संकलन केवल 1.5 सेकंड तक होता है जो काफी आरामदायक होता है। –

+0

हमारी बड़ी परियोजना में हम एएसपी.NET 4 का उपयोग करते हैं और टाइपस्क्रिप्ट विजुअल स्टूडियो 2015 द्वारा संकलित किया जाता है। यह संकलन करने के लिए 1s तक लेता है और यह पूरी तरह से ठीक है। जैसा कि मैंने एएसपी.NET 5 के साथ खेलने की कोशिश की है, यह टाइपस्क्रिप्ट का उपयोग करते हुए यह अभी भी बहुत छोटी है। –

+0

@MartinVseticka: bundler.bundle() स्ट्रीम शुरू करता है, इसलिए मैं इससे पहले कुछ भी नहीं डाल सकता। हालांकि, ऐसा लगता है कि bundler.bundle() ऑपरेशन अतिरिक्त समय व्यतीत करने के कारण होता है। इसके अलावा, गल्प-टाइपस्क्रिप्ट * तेज है, लेकिन चूंकि मैं मॉड्यूल लोडिंग के लिए ब्राउज़र का उपयोग कर रहा हूं, इसलिए मैं इसका उपयोग नहीं कर सकता। मॉड्यूल लोडिंग के लिए आप लोग क्या उपयोग करते हैं? – nlaq

उत्तर

2

इस भूल जाओ, बस नवीनतम टीएस + webpack :)

+0

मैं सहमत हूं, मैंने पूरी तरह से वेबपैक के पक्ष में ब्राउज़र का उपयोग बंद कर दिया है। – nlaq

संबंधित मुद्दे