Về mặt lý thuyết, ý tưởng custom domain, quản lý qua CDN Cloudflare để cache ảnh, nó phù hợp nhất cho các dịch vụ giới hạn băng thông như Cloudinary
Các ý tưởng trong bài, vẫn có đôi chỗ chưa hài lòng nhưng cũng được khoảng 80%-90% so với kế hoạch ban đầu
Mệt mỏi nhất vẫn là bước đưa các kích thước vào chính xác vị trí vị trí mình mong muốn, điểm này nếu bạn dùng Jetpack, thì hãng đã viết plugin, tự làm từ A -> Z cả rồi
Plugin gốc của Cloudinary sau nhiều lần cập nhập cũng rất tuyệt vời, trừ vụ họ quản lý link, ảnh chằng chịt quá, khi view code nhìn hơi rối mắt
Cloudinary khả năng nén, tối ưu hóa bằng các công nghệ liên quan tới ảnh cực kì mạnh, gần như hàng đầu thế giới
Trong tất cả các plugin, dịch vụ về ảnh mình từng dùng, Cloudinary cho ra dung lượng nhỏ nhất mà chất lượng gần như không thay đổi, tùy biến siêu nhiều, nếu thích có thể giảm dung lượng xuống rất nhỏ mà chất lượng chỉ thay đổi chút ít
Ngoài chuyện hỗ trợ định dạng AVIF rất mới, họ còn bóc tách, xem nội dung tấm ảnh, biết ảnh chụp cái gì, người, động vật hay cây cối, vật thể (khá giống google images, facebook), nên khi sử dụng các tùy chọn biến thể ảnh, nó có thể tạo thumbnail chính xác hơn tới đối tượng bạn mong muốn
Nhờ thế Cloudinary sẽ hiệu quả hơn nếu bạn làm các shop bán hàng, ảnh thumbnail sẽ hiện, zoom chính xác hơn vào chủ thể, trên các blog cơ bản kiểu thèng bibica.net, thumbnail đa phần chỉ là làm nhỏ lại tấm ảnh, các ưu điểm mạnh nhất của Cloudinary gần như không dùng tới, khá là phí :]]
Đăng kí tài khoản Cloudinary
Tạo tài khoản Cloudinary miễn phí, tại phần Account sẽ thấy Cloud Name của tài khoản (có thể ấn edit để đổi sang 1 tên dễ nhớ)
Sau đó đi tới Upload, tạo Auto upload mapping
- Folder: đặt tên gì cũng được không quan trọng
- URL prefix: điền đường dẫn tới thư mục uploads trên WordPress
Các ảnh thông thường sẽ có url là: https://bibica.net–wp-content/uploads–2023/09–2023-09-25-10-27-33.png
Sau khi tạo Auto upload mapping, Cloudinary sẽ có url là: https://res.cloudinary.com/xinclub/f_webp,q_auto,dpr_auto/img/2023-09-25-10-27-33.png
Trong đó xinclub là Cloud Name, img là Folders bạn vừa chọn, giữa 2 giá trị này là các giá trị f_webp,q_auto,dpr_auto,w_500,h_300 … để tùy biến ảnh, tùy bạn đưa vào
Việc tiếp theo là tạo các custom riêng để dùng Cloudflare làm cache, và giúp các link ngắn gọn hơn
Custom domain và cache qua Webinoly Reverse Proxy FastCgi Cache
File cấu hình như bên dưới
# REVERSE PROXY NGINX CONFIGURATION by Webinoly location / { proxy_set_header Connection ""; proxy_http_version 1.1; # WebinolyProxyCacheStart proxy_cache img_bibica_net; proxy_cache_key "$scheme$request_method$host$request_uri"; proxy_cache_valid 200 10y; proxy_cache_valid 301 302 303 307 308 404 410 451 1m; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; proxy_cache_background_update on; proxy_cache_lock on; proxy_buffer_size 16k; proxy_buffers 16 16k; set $skip_cache_img_bibica_net 0; include apps.d/img.bibica.net*site_custom_cache.conf; proxy_cache_bypass $skip_cache_img_bibica_net; proxy_no_cache $skip_cache_img_bibica_net; # WebinolyProxyCacheEnd proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300; proxy_ignore_headers Set-Cookie; proxy_intercept_errors on; #proxy_next_upstream error timeout http_500; # Upstream defined here: conf.d/upstream_proxy.conf proxy_pass https://res.cloudinary.com/xinclub/f_webp,q_auto:best/img/; } location /auto/ { proxy_set_header Connection ""; proxy_http_version 1.1; # WebinolyProxyCacheStart proxy_cache img_bibica_net; proxy_cache_key "$scheme$request_method$host$request_uri"; proxy_cache_valid 200 10y; proxy_cache_valid 301 302 303 307 308 404 410 451 1m; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; proxy_cache_background_update on; proxy_cache_lock on; proxy_buffer_size 16k; proxy_buffers 16 16k; set $skip_cache_img_bibica_net 0; include apps.d/img.bibica.net*site_custom_cache.conf; proxy_cache_bypass $skip_cache_img_bibica_net; proxy_no_cache $skip_cache_img_bibica_net; # WebinolyProxyCacheEnd proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300; proxy_ignore_headers Set-Cookie; proxy_intercept_errors on; #proxy_next_upstream error timeout http_500; # Upstream defined here: conf.d/upstream_proxy.conf proxy_pass https://res.cloudinary.com/xinclub/w_500,f_webp,q_auto:best/img/; }
Link custom là img.bibica.net
Hiện tại thì mình dùng 2 kích thước, 1 là chiều rộng 500 px cho ảnh thumbnail, còn lại là giữ nguyên kích thước gốc
- w_500 là vị trí thumbnail -> đường dẫn img/bibica.net/auto/ (chất lượng ảnh dùng auto best)
- Ở ảnh full thì giữ nguyên kích thước gốc, đường dẫn img.bibica.net (chất lượng ảnh dùng auto best)
Các tùy biến ảnh như 500,f_webp,q_auto:best, Cloud Name và Folder images đều đã được ẩn hoàn toàn, link đã ngắn gọn và sạch sẽ hết sức có thể
Từ link gốc https://bibica.net–wp-content/uploads–2023/09–2023-09-25-10-27-33.png
Trong trường hợp muốn dùng ảnh có chiều rộng tối đa 500px, thêm /auto/ vào sau domain: https://img.bibica.net/auto/2023/09/2023-09-25-10-27-33.png
Bạn có thể thêm các tùy biến ảnh khác nhau, tùy vào sở thích, mình đang dùng 2 tùy chọn là /f_webp/q_auto:best/ ảnh nén về .webp và chất lượng ảnh tốt nhất có thể, kể cả ảnh thumbnail
Nếu thích hoặc đú đởn, có thể dùng trực tiếp custom domain các link Cloudinary lên chính domain gốc bibica.net, nhìn link ảnh là hú hồn con chồn, vì cứ tưởng ảnh gốc là để trên host 😀 có điều tách ra 1 domain phụ làm link ảnh cho dễ quản lý và cấu hình, chung hết 1 domain nhìn chằng chịt lắm 😛
Set ảnh vào các vị trí phù hợp
Sử dụng Code Snippets tạo 1 file php với nội dung:
function cloudinary_photon_custom($attr, $attachment, $size) { $image_id = get_post_thumbnail_id(); $image_meta = wp_get_attachment_metadata( $image_id ); $image_path = get_attached_file( $image_id ); if ($size === 'thumbnail') { $attr['src'] = "https://img.bibica.net/auto/".$image_meta['file']; } else if ($size === 'large') { $attr['src'] = "https://img.bibica.net/w_768/".$image_meta['file']; } return $attr; } add_filter('wp_get_attachment_image_attributes', 'cloudinary_photon_custom', 999 , 3);
Đoạn code này mình làm thủ công, đó là cứ ảnh size thumbnail thì đập thẳng luôn link https://img.bibica.net/auto/ vào 😀 sau đó nối với thư mục và tên file
Nếu bạn dùng nhiều định dạng hơn thì cứ thêm vào
Khắc phục tạm lỗi trên thì ở vị trí thumbnail, featured image, để tránh việc trùng tên với các album trước đây tạo, ở vị trí đó mình set dùng ảnh medium hay 1 tên mới tùy ý chưa dùng là được
Ban đầu tính nhờ tay bạn già Vượng Nguyễn viết hộ phần này, mà thấy hắn cũng bận, nên thôi, cứ google loạn hết cả lên, xong cắt dán đủ kiểu, không hiểu sao cuối cùng cũng có chạy :]] bạn nào rành code chắc chỉ cần 5 phút là viết xong với xử lý tốt cái lỗi mình nói ở trên rồi
Lúc này, chúng ta đã xử lý cơ bản các ảnh ở các vị trí thumbnail và featured image
Về các ảnh trong nội dung bài viết có thể dùng Lucas String Replace, để tìm và thay thế các link, mình thì để tăng trải nghiệm xem bài, các ảnh bên trong nội dung bài viết, giữ nguyên ảnh gốc, nên chỉ cần đổi img.bibica.net/ sang img.bibica.net/ là xong
Xử lý cache ảnh và header trên Cloudflare
Lúc này, tình huống phát sinh là đôi khi ảnh bạn upload lên, chưa kịp cache xuống Reverse Proxy mà Cloudflare đã HIT 😀 làm status của Reverse Proxy cứ MISS
Check thì mình thấy khi là admin, xem ảnh, nó có cookie wordpress_test_cookie và wordpress_logged_in
Có thể dùng Cache Rules thêm vào để khi là admin xem ảnh, Cloudflare không cache các ảnh này
(http.host eq "img.bibica.net" and http.cookie contains "wordpress_test_cookie" and http.cookie contains "wordpress_logged_in")
Lúc này, khi bạn upload ảnh, do không bị Cloudflare cache, nên Reverse Proxy cache HIT bình thường
Khách xem bài thì sẽ thấy Reverse Proxy và Cloudflare cache HIT cùng lúc
Tiếp theo vào Transform Rules -> Modify Response Header, thêm và xóa 1 số header cho sạch sẽ 😀
Mình thêm vào 1 header là cache-control: public, max-age=31536000, immutable
Còn lại Cloudinary có header nào mình xóa hết 😀
Preload lại ảnh lần đầu
Mặc định với hình thức Auto upload mapping, ảnh khi lần đầu tiên truy cập, sẽ được kéo về thư mục Folder trong tài khoản của bạn, nó sẽ hơi chậm 1 chút, rảnh thì có thể dùng precache.sh để chạy auto, lý thuyết thì khi ảnh cf-cache-status: HIT thì ảnh cũng đã về thư mục Folder rồi, cứ để nó chạy auto ít tiếng cũng được 😛
Cloudinary <-> Cloudflare
Sau khi ảnh đã được đưa về server của Cloudinary, tạo thumbnail, nén ảnh …. từ các lần load tiếp theo, nó sẽ được Cloudflare load thẳng, nên sẽ nhanh hơn
Khi dùng trực tiếp, thỉnh thoảng mình vẫn có cảm giác, tốc độ khá chậm, có vẻ do Cloudinary dùng nhiều các công nghệ liên quan tới ảnh, đọc cả hình ảnh để xem nội dung hình ảnh, CDN thậm chí họ dùng tới 3 dịch vụ siêu to là Akamai, Fastly và cả CloudFlare
Vấn đề rất nhây, là cùng 1 IP mình đổi 3 trình duyệt, thấy ảnh radom ra 3 dịch vụ CDN luôn ….
-> tình huống này có thể giải thích lý do tại sao thi thoảng bạn thấy ảnh từ Cloudinary khá chậm, kiểu ban đầu tấm ảnh load sang CDN của Akamai, cache ở đó, khách nào được phân tới cụm Akamai thì nhanh, nhưng nếu khách bị đá sang CDN của Fastly hay CloudFlare, do chưa có cache, nên chậm
Thường sau khi dùng 2-3 ngày, để Cloudinary cache sang 3 cụm CDN thì vấn đề này ổn hơn
Có điều mình thấy xử lý đơn giản hơn, ở bước Reverse Proxy, cache lại 1 lần tại VPS của mình là được
Đi theo tuyến đường này thì Cloudinary sau khi xử lý ảnh xong, ảnh sẽ được cache vào Reverse Proxy, rồi từ Reverse Proxy đi tới Cloudflare
Trên Cloudinary bạn chỉ tốn Credit cho Storage, Transformations, 1 ít cho Bandwidth nên lý thuyết là có thể dùng thoải mái ở tài khoản miễn phí
Kết luận sơ bộ
Cấu hình cho bài này, thực sự phức tạp quá sức cần thiết 😀 rất nhiều thứ mình làm, cũng không chắc hoạt động có đúng như mình nghĩ không 😀 cụ thể là vấn đề Reverse Proxy FastCgi Cache, trong cấu hình mình nhớ set là cache lưu 10 năm, mà thi thoảng ở 1 vài tấm ảnh, ấn vào coi thử thì thấy MISS cache rồi, chẳng hiểu lạc đi đâu 😀
Cloudinary cho chất lượng ảnh rất tốt, dung lượng file khá nhỏ, các tùy biến về ảnh thì cực kì đa dạng, các trang bán hàng, sản phẩm nhiều làm thumbnail mới thấy sự ưu việt về tùy biến của họ, còn thuần túy chỉ tạo thumbnail như mình đang dùng thì chưa tận dụng hết ưu điểm
Link ảnh rất gọn cũng có thể là 1 ưu điểm 😀 nếu bạn nào làm theo bài này, gần như không ai biết là đang dùng Cloudinary để nén ảnh, tạo thumbnail, vì các thông tin bị ẩn đi sạch sẽ
Sử dụng Auto upload mapping, có một ưu điểm nhỏ, các ảnh sẽ được kéo về Cloudinary với cấu trúc thư mục tương tự trên WordPress, trong trường hợp bạn xóa nhầm ảnh, vẫn còn 1 nơi để sơ cua
Cách này cũng có thêm 1 ưu điểm, bạn có thể set chính xác các tùy biến vào vị trí mình mong muốn, ví dụ ở ảnh thumbnail, có thể giảm chất lượng ảnh, chọn các tỷ lệ cắt, zoom khác nhau …. các plugin khác đa phần áp dụng cùng 1 bộ lọc cho tất cả vị trí
Nói chung mình viết bài này vì … thích, dùng Cloudinary do đây là dịch vụ đầu tiên mình biết tới liên quan tới ảnh
Dùng bình thường mình thấy cài plugin Jetpack, bật Jetpack Photon lên, mất chưa tới 10s, quá đủ hiệu quả và siêu nhàn 😀
Comment policy: We love comments and appreciate the time that readers spend to share ideas and give feedback.
Notes: However, those deemed to be spam or solely promotional will be deleted.
You can create a Gravatar account, add avatar, then use that email to comment here, your account will have a more beautiful Avatar, easier to recognize with other members.