Thứ Tư, 10 tháng 12, 2014

Tối ưu tốc độ tải trang bằng việc nén các file resources JS và CSS sử dụng Gruntjs

 

09/06/2013 | Đăng bởi Trần Mạnh | 0 bình luận
Tiếp theo của phần 3 trong series Nhập môn Nodejs trên Hanoijs, chúng ta sẽ tiếp tục tìm hiểu về khái niệm module và việc tổ chức code trong nodejs.
Phần lớn lập trình viên đều quen thuộc với khái niệm tổ chức code trong ứng dụng của mình. Việc tổ chức code 1 cách logic sẽ cho chúng ta khả năng sử dụng lại những code mà ta đã viết. Chúng ta thông thường sẽ tách và nhóm những đoạn code lặp lại hoặc được sử dụng lại một cách thường xuyên thành các function, nhiều function xử lý chung 1 logic nào đó chúng ta lại tổ chức thành các class. Các class và function đó được tổ chức vào các file và đặt vào thư mục như lib hoặc classes... Còn các code thông thường thì có thể sẽ được tổ chức vào thư mục application hoặc một thư mục bất kỳ nào khác tuỳ vào project của chúng ta.
1. Tổ chức và sử dụng lại các hàm chức năng
Khi chúng ta thực hiện một ứng dụng nào đó, của bất kỳ ngôn ngữ nào, thường sẽ có những thời điểm mà code của chúng ta viết tất cả trong 1 file.Điều này sẽ dẫn đến việc rất khó để kiểm soát được code của chúng ta nếu xảy ra lỗi. Vì thế, thay vì tống hết đống code đó trong 1 file, chúng ta hãy xem lại xem những phần code nào có thể tách ra và chuyển chúng sang một file khác.
Đối với 1 số ngôn ngữ thực thi như PHP hay Ruby, chúng ta thường dùng khái niệm include file để tổ chức ứng dụng của chúng ta. Phần lớn việc include có nghĩa là các code xử lý trong file include sẽ thực thi ở phạm vi Global.Điều này có nghĩa là bất kỳ biến hay hàm nào chúng ta khai báo trước đó sẽ có khả năng bị ghi đè (overwrite) bởi code trong các file include đó.
Giả sử với PHP, ứng dụng của bạn có một phương thức thực hiện việc đổi tỷ giá đồng USD như sau:
function changeVNDToUSD($number, $rate = 20000) {
  $number = (int) $number;

  if ($rate > 0)
     return round($number / $rate, 2);
  else return 0;
}

include 'currency_helper.php';
Sau đó bạn include 1 file giả sử là currency_helper.php ngay dưới phương thức changeVNDToUSD mà trong file currency_helper.php bạn lại khái báo 1 phương thức cũng tên changeVNDToUSD, bạn sẽ nhận được lỗi: Fatal error: Cannot redeclare changeVNDToUSD.
Để tránh điều này, trong PHP chúng ta có thể dùng namespaces, với Ruby là modules. Đối với Nodejs, nó cung cấp cho chúng ta hệ thống module cực kỳ mạnh mẽ, ta có thể tách code và require code mà không lo bị xung đột với các code mà ta đã viết trước đó. Một khi muốn sử dụng 1 phương thức hay một đoạn code nào đó ở phạm vi Global, chúng ta cần phải thông qua đối tượng là exports hoặc module.exports. Và đây chính là cách mà chúng ta tạo module trong nodejs.
2. Tạo module trong nodejs
currency_helper.js
var df_rate = 20000;

function changeVNDToUSD(number, rate) {
  var rate = rate || df_rate;
  if (rate > 0)
     return Math.round(number / rate, 2);
  else return 0;
}

exports.changeVNDToUSD = changeVNDToUSD;
// C2: module.exports = changeVNDToUSD;
app.js
var currency = require('./currency_helper'); // File currency_helper.js cùng thư mục với app.js
console.log(currency.changeVNDToUSD(200000)); // $10
// C2: console.log(currency(200000)); // $10
Hãy chú ý đến phần comment ở cuối file currency_helper.js, nếu chúng ta sử dụng exports.changeVNDToUSD = changeVNDToUSD thì ở fileapp.js chúng ta phải gọi phương thức thông qua đối tượng currencycurrency.changeVNDToUSD. Còn nếu chúng ta sử dụng C2, gán trực tiếp phương thức changeVNDToUSD với đối tượng module.exports thì ở file app.js ta sẽ gọi trực tiếp phương thức khi require: currency(200000). Ngoài ra chúng ta có thể sử dụng phương thức changeVNDToUSD một lần bằng cách require('./currency_helper.js').changeVNDToUSD(200000) mà không cần phải khai báo.
3. Exports nhiều phương thức
Như đã đề cập ở trên, trong nodejs chỉ những phương thức nào được gán với đối tượng exports thì chúng ta mới có thể sử dụng được ở các module khác. Các phương thức khác trong cùng file sẽ được coi là các private method
currency_helper.js
var df_usd_rate = 20000;
var df_eu_rate = 40000;

function changeVNDToUSD(number, rate) {
  var rate = rate || df_usd_rate;
  if (rate > 0)
     return Math.round(number / rate, 2);
  else return 0;
}

function changeVNDToEU(number, rate) {
  var rate = rate || df_eu_rate;
  if (rate > 0)
     return Math.round(number / rate, 2);
  else return 0;
}

function changeUSDToVND(number, rate) {
  var rate = rate || df_eu_rate;
  return Math.round(number * rate, 2);
}

exports.changeVNDToUSD = changeVNDToUSD;
exports.changeVNDToEU = changeVNDToEU;
Giả sử trong file currency_helper.js ta có 3 phương thức như trên. Nếu ta chỉ exports 2 phương thức là changeVNDToUSDchangeVNDToEU thìở các module khác ta chỉ có thể sử dụng 2 phương thức này, còn phương thức changeUSDToVND là phương thức private của currency_helper.js
app.js
var currency = require('./currency_helper'); // Lưu ý là k cần phần mở rộng .js
console.log(currency.changeVNDToUSD(1200000)); // $60
console.log(currency.changeVNDToEU(1200000)); // 30 euro
console.log(currency.changeUSDToVND(20)); // TypeError: Object #<Object> has no method 'changeUSDToVND'
Như vậy là đến thời điểm này, chúng ta đã có thể hiểu được cách tổ chức, phân tách code sử dụng module trong node, cách tạo 1 module và require module của ta trong các module khác. Nhưng nếu chỉ có thế thì làm sao nói hệ thống module trong node là mạnh mẽ được? Nếu bạn còn nghi ngờ điều này, xin chào mừng bạn đến với thế giới của module trong node: NPM
4. NPM: Thế giới của các module
Nghe giới thiệu có vẻ mỹ miều thế nhưng thực ra npm là 1 package manager của Node. Ta có thể sử dụng nó để cài cắm các module package khác của tất cả mọi lập trình viên trên thế giới mà đã được publish trên NPM. Hoặc chúng ta cũng có thể publish những module package mà chính ta viết cho cộng đồng sử dụng.
Cài đặt 1 npm module
Trong /Desktop/my_project
Mở terminal (Với Windows bạn có thể sử dụng PowerShell) và gõ lệnh sau:
$npm install request
NPM sẽ thực hiện tìm kiếm và nếu tìm thấy nó sẽ download về thư mục node_modules trong my_project cho chúng ta. Trong trường hợp này npm sẽ clone 1github repo từ https://github.com/mikeal/request
request module sẽ được đặt trong /Desktop/my_project/node_modules/request
Trong file /Desktop/my_project/app.js, ta sẽ load module request vào bằng dòng code sau:
var request = require('request');
Lưu ý là trong require, chúng ta chỉ cần đặt tên giống với tên thư mục trong node_modules là được.
Ta có thể cài đặt 1 module ở phạm vi global bằng cách thêm tham số -g đằng sau lệnh npm install
$npm install coffee-script -g
Tuy nhiên, những module là global thì ta không thể require chúng trong ứng dụng của chúng ta. Hãy lưu ý đến phần này.
Ngoài cách cài đặt từng module sử dụng lệnh npm install chúng ta còn có 1 cách khác cũng rất tiện lợi đó là định nghĩa các module cần thiết cho ứng dụng của chúng ta trong file package.json
{
    "name": "My App",
    "version": "1",
    "dependencies": {
       "connect": "1.8.7",
       "request": "lastest"
    }
}
Lưu ý là file package.json cần phải được đặt ở root của ứng dụng của chúng ta. Thực hiện cài đặt các npm module bằng lệnh npm install. Npm sẽ tự động đọc file json và tải về các gói đã được định nghĩa trong file.
Tổng kết
Chúng ta đã đi qua 4 phần của series về Nodejs trên hanoijs. Nếu bạn vẫn chưa đọc các phần khác của series thì truy cập vào Nhập môn Nodejs để theo dõi. Tuy mọi thứ từ lúc bắt đầu đến giờ vẫn chỉ là những khái niệm ở mức low level nhưng hanoijs hy vọng bạn đã có 1 cái nhìn cơ bản nhất về các nội dung trên nodejs. Phần tiếp theo của series, hanoijs sẽ cùng các bạn tìm hiểu 1 web framework chạy trên node có tên là Expressjs. Happy coding!!


Sưu tầm: http://hanoijs.org/bai-viet/blog/toi-uu-toc-do-tai-trang-bang-viec-nen-cac-file-resources-js-va-css-su-dung-gruntjs/37