GZIP là công nghệ nén thường được sử dụng để truyền dữ liệu một cách nhanh chóng qua Insternet. Hiện nay, GZIP là một tiêu chuẩn để nén các file trên trang web, đa số các website hiện nay hơn 99% sử dụng GZIP. Vì vậy, GZIP rất hiệu quả trong việc tăng tốc website, khi dùng GZIP bạn có thể giảm dữ liệu lên tới 70%.

Enabling the Gzip Command

Sau đây, tôi sẽ hướng dẫn các bạn bật tính năng gzip trên nginx, để bật tính năng gzip trên nginx, bạn cần thêm đoạn mã sau vào nginx.conf

gzip on;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_vary on;
gzip_types text/plain text/css text/javascript image/svg+xml image/x-icon application/javascript application/x-javascript;

Verifying Gzip Activation

Sau khi bật gzip, bước tiếp theo là chúng ta xác minh rằng nó có đang compressing các file javasctip và css được gửi đi hay không?

Điều này được thực hiện bằng cách sử dụng bất kỳ công nghệ trực tuyến nào hoặc kiểm tra phản hồi HTTP trong trình duyệt, ngoài ra có thể kiểm tra phản hồi HTTP bằng cURL như sau:

curl -H "Accept-Encoding: gzip" -I https://manhdandev.com/web/css/style.min.css?v=20211010113045

Trong phản hồi, gzip sẽ được liệt kê trong header Content-Encoding:

HTTP/1.1 200 OK
Server: nginx
Date: Sun, 17 Oct 2021 07:54:12 GMT
Content-Type: text/html; charset=UTF-8…
Vary: Accept-Encoding
Content-Encoding: gzip

gzip_comp_level

Syntax: gzip_comp_level level;
Default:	
gzip_comp_level 1;
Context: http, server, location

Bạn có thể đặt level cho các phản hồi gzip, các giá trị có thể nằm trong khoảng từ 1 đến 9. Level càng cao thì tỉ lệ nén càng cao.

Sau đây là một ví dụ về tỉ lệ nén cho các level khác nhau:

application/x-javascript - jQuery 1.8.3 (Uncompressed)

0 261.46 KiB (100.00% of original size)
1 95.01 KiB ( 36.34% of original size)
2 90.60 KiB ( 34.65% of original size)
3 87.16 KiB ( 33.36% of original size)
4 81.89 KiB ( 31.32% of original size)
5 79.33 KiB ( 30.34% of original size)
6 78.04 KiB ( 29.85% of original size)
7 77.85 KiB ( 29.78% of original size)
8 77.74 KiB ( 29.73% of original size)
9 77.75 KiB ( 29.74% of original size)

Nhiều bạn đọc đến đây, sẽ mình rằng đặt level 9 trong config nginx thì mình sẽ được tỉ lệ nén tốt nhất rồi, nhưng để đạt được điều này bạn phải hy sinh CPU của con server của mình rất nhiều để thực hiện nén cho mỗi lần request được gửi đến.

Ngoài ra, bạn có đạt được tỉ lệ nén tốt nhất mà không phải phải hy sinh CPU của con server của bạn nhiều, đó là bạn hãy sử dụng gzip_static của nginx và nén các file javascrip hay css trước bằng PHP

function gzip_static($path)
{
    if ((extension_loaded('zlib') === true) && (is_file($path) === true))
    {
        $levels = array();
        $content = file_get_contents($path);

        foreach (range(1, 9) as $level)
        {
            $levels[$level] = strlen(gzencode($content, $level));
        }

        if ((count($levels = array_filter($levels)) > 0) && (min($levels) < strlen($content)))
        {
            if (file_put_contents($path . '.gz', gzencode($content, array_search(min($levels), $levels)), LOCK_EX) !== false)
            {
                return touch($path . '.gz', filemtime($path), fileatime($path));
            }
        }
    }

    return false;
}

Điều này cho phép bạn có được khả năng nén tốt nhất có thể mà không phải hy sinh CPU cho mỗi request gửi đến server (mình chỉ thực hiện nén file một lần hay chỉ nén file khi chúng ta thay đổi nội dung file).

Cuối cùng, tôi đã sử lệnh function PHP ở trên tạo thành command trong Laravel, nếu bạn đang sử dụng dự án bằng Laravel có thể sử dụng command sau:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class GzipStatic extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'gzip_static {--path=}';

    protected $path;
    protected $level;

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Additionally, if you use the gzip_static module, you may want to pre-compress your files (in PHP)';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        if (extension_loaded('zlib') === true) {
            $this->path = public_path($this->option('path'));
            if (is_file($this->path) === true) {
                $this->gzipStatic($this->path);
            } else {
                $files      = scandir($this->path);
                $gzip_files = [];
                foreach ($files as $key => $file) {
                    if (preg_match('/(.*?).css$/i', $file) || preg_match('/(.*?).js$/i', $file)) {
                        array_push($gzip_files, $file);
                    }
                }
                foreach ($gzip_files as $key => $gzip_file) {
                    $this->gzipStatic($this->path . '/' .$gzip_file);
                }
            }
        }
    }

    public function gzipStatic($path)
    {
        $levels  = array();
        $content = file_get_contents($path);

        foreach (range(1, 9) as $level)
        {
            $levels[$level] = strlen(gzencode($content, $level));
        }

        if ((count($levels = array_filter($levels)) > 0) && (min($levels) < strlen($content)))
        {
            if (file_put_contents($path . '.gz', gzencode($content, array_search(min($levels), $levels)), LOCK_EX) !== false)
            {
                return touch($path . '.gz', filemtime($path), fileatime($path));
            }
        }
    }
}

Khi muốn tạo một file gzip trong thư mục public Laravel chỉ cần chạy lệnh sau:

php artisan gzip_static --path=

Option path có 2 dạng:

+ File: php artisan gzip_static --path=/web/style.css

+ Folder: php artisan gzip_static --path=/web/ (Khi nén thì không bao gồm thư mục con)

Cuối cùng, trong cấu hình nginx thì chỉ cần bật gzip_static on

location / {
    gzip_static on;
}

Tài liệu tham khảo:

https://docs.nginx.com/nginx/admin-guide/web-server/compression/

http://nginx.org/en/docs/http/ngx_http_gzip_module.html

https://serverfault.com/questions/253074/what-is-the-best-nginx-compression-gzip-level

CÓ THỂ BẠN QUAN TÂM

Laravel Many to Many Polymorphic Relationship

Laravel Many to Many Polymorphic Relationship

Many to many Polymorphic Relationship cũng hơi phức tạp để hiểu. Ví dụ: nếu bạn có bài post, video và tag, bạn cần kết nối với nhau theo yêu cầu là mọi bài đăng đều có nhiều tag và video cũng như vậy....

Laravel Custom Eloquent Casts

Laravel Custom Eloquent Casts

Trước đây, chúng ta bị giới hạn cast mặc định do Laravel cung cấp. Mặc dù, có một số gói thư viện có thể  giúp chúng ta custom được nhưng chúng có một nhược điểm lớn. Bởi vì, chúng ghi đề phương thức...

Integrating CKFinder with Amazon S3 in Laravel

Integrating CKFinder with Amazon S3 in Laravel

CKFinder 3 CKFinder 3 là trình quản lý tập tin được tích hợp với CKEditor 4 và CKEditor 5. Nó giúp bạn dễ dàng đưa các tập tin và hình ảnh vào nội dung của Editor một cách an toàn. Đây là một tín...

Laravel Socialite Login With Google

Laravel Socialite Login With Google

Google Google là một công cụ tìm kiếm trên internet. Nó sử dụng một thuật toán độc quyền được thiết kế để truy xuất và sắp xếp các kết quả tìm kiếm nhằm cung cấp các nguồn dữ liệu đáng tin cậy và ph...

Laravel Migration

Laravel Migration

Migration cho phép các nhà phát triển (Developer) nhanh chóng tạo ra cở sở dữ liệu của ứng dụng mà không cần vào màn hình quản lý cơ sở dữ liệu hay chạy bất kì một câu lệnh SQL nào. Trước hết, nếu...

Export CSV from SQL Server - Import into MySQL with Laravel

Export CSV from SQL Server - Import into MySQL with Laravel

Transfer Database Trong quá trình phát triển và bảo trì dự án, việc di chuyển cơ sở dữ liệu từ hệ thống này sang hệ thống khác là một nhiệm vụ khá phổ biến. Giả sử bạn cần di chuyển dữ liệu từ SQ...

Laravel customize your API Versioning Route File

Laravel customize your API Versioning Route File

Trong khuôn khổ của Laravel, các route của api được tách thành một file duy nhất, đó là file api.php nằm trong thư mục routes . Nếu chúng ta muốn thêm version vào route api thì chúng ta sẽ làm như...

Laravel Middlewares

Laravel Middlewares

Middleware cung cấp một cơ chế thuận tiện để lọc các yêu cầu HTTP gửi đến ứng dụng bạn. Nó là một lớp trung gian nằm giữa request và controller. Bạn có thể thêm các xử lý logic trước khi gửi đến contr...

Export CSV from AWS RDS - Import into MySQL with Laravel

Export CSV from AWS RDS - Import into MySQL with Laravel

Transfer Database Trong quá trình phát triển và bảo trì dự án, nhiệm vụ di chuyển cơ sở dữ liệu từ hệ thống này sang hệ thống khác là một nhiệm vụ khá là phổ biến. Chúng ta thường sẽ sử dụng câu...

ManhDanBlogs