+15

Tối ưu performance website

Trong bài viết này mình sẽ chia sẻ cho bạn cách tối ưu tốc độ website, để có tốc độ load trang web nhanh hơn cũng như có điểm ranking cao hơn với google search engine.

Đầu tiên bạn vào trang web https://developers.google.com/speed/pagespeed/insights/ và nhập địa chỉ website vào input và ấn Analyze thì google sẽ chấm điểm website của bạn xem nó được bao nhiêu điểm và sẽ đưa ra những recommend để web site của bạn chạy nhanh hơn dưới đây mình sẽ tổng hợp những yêu cầu chủ yếu của google đưa ra và cách fix những yêu cầu này.

1. Optimize images

Đây có lẽ là yêu cầu đầu tiên và cũng là hay gặp nhất với bất kì website nào. Như bạn thấy trong hình thì có nhiều ảnh được đưa ra là có thể giảm đến 90% dung lượng của ảnh xuống, kết quả thật đáng mơ ước phải không.

alt

Vậy làm sao để fix được trường hợp này. Thật may là google đã làm hết cho bạn, bạn chỉ cần kéo xuống dưới cùng của site đó (tab destop nhé) và download ảnh về và thay vào website của mình mà thôi.

optimize img.png

Vậy cũng sẽ có nhiều bạn thắc mắc rằng nếu dung lượng của ảnh giảm đi nhiều như vậy thì chất lượng ảnh sẽ như thế nào. Tôi xin trả lời rằng chất lượng ảnh sẽ ko thay đổi nếu trong danh sách ảnh của bạn chỉ có từ là Losslessly compressing hoặc là compressing, còn nếu bạn nhìn thấy có từ resized tức là google đã thay đổi kích thước ảnh của bạn, nó sẽ thay đổi chất lượng với các kích thước màn hình khác nhau, nên tốt nhất bạn nên check kỹ trường hợp này.

Với những hình ảnh có thừa kích thước (Delivering scaled image assets):

Nghĩa là chỗ đó bạn đã fix ảnh có widthheght là 400 x 400 chẳng hạn, thì tốt nhất bạn phải cắt ảnh có có kích thước như vậy nó sẽ giảm đáng kể dung lượng ảnh xuống.

pixel

Bạn có thể thấy lượng pixel thừa là rất nhiều với những hình ảnh lớn hơn kích thước bạn cần.

Một lưu ý cuối cùng với bạn là nên Download img ở tab desktop về thì chất lượng ảnh sẽ được giữ nguyên.

2. Minify Css/Js

Minify css tức là nén file css/js lại để có dung lượng file nhỏ hơn, nó sẽ xóa tất cả khoảng trống trong file css/js của bạn để giảm dung lượng của file xuống.

minify css js.png

Trước khi minify

 body
{
  background-color:#d0e4fe;
}
h1
{
   color:orange;
   text-align:center;
}

Sau khi minify:

 body {background-color:#d0e4fe;} h1 {color:orange;text-align:center;}

Trường hợp này thì cách fix hoàn toàn tương tự như đối với phần đầu tiên optimize images thôi, bạn chỉ cần download về và thay các file css/js là xong.

Khi thay các file thì nó sẽ là 1 chuỗi css/js liền mạch sẽ rất khó khăn trong quá trình phát triển, vậy lời khuyên cho bạn là tốt nhất website đã chạy thực tế hoặc những file đó đã không sửa đến nữa thì thay. Hoặc nếu bạn có hiểu biết về lập trình thì bạn có thể sử dụng công cụ nén là gulp, bạn vui lòng search từ khóa minify css/js with gulp sẽ có rất nhiều bài hướng dẫn về trường hợp này.

Đối với css thì các bạn không nên dùng @import url("style.css") trong file css vì nó sẽ làm chậm quá trình tải trang web.

3. Render blocking Css

Đây cũng là phần rất nhiều website hiện nay đang mắc phải và cách fix của nó cũng không hề đơn giản như hai phần trước. Vậy render là gì, Render chính là cách mà trình duyệt load trang web của bạn. Thông thường khi website được load nó sẽ download toàn bộ css về trước khi render html, vậy làm sao quá trình render được nhanh nhất:

  1. Như đã nói ở trên là không sử dụng @import trong file css, mà nếu thật sự cần thì load 1 file riêng <link rel="stylesheet" href="style.css">
  2. Gộp những file nhỏ thành một file css duy nhất, nếu các bạn load quá nhiều css thì trình duyệt sẽ phải tạo nhiều request tới server để download về những file có dung lượng rất nhỏ, vậy tốt nhất nên gộp thành một để tạo 1 request duy nhất.
  3. Chỉ rõ label conditional css, nghĩa là file nào được sử dụng ở tất cả thiết bị thì chúng ta thêm vào media = "all", còn nếu chỉ sử dụng cho print thì thêm vào <link href="print.css" rel="stylesheet" media="print"> hoặc <link href="other.css" rel="stylesheet" media="(min-width: 40em)">. Thuộc tính media báo cho trình duyệt biết rằng nó sẽ chỉ phải download file đó khi cần thiết mà thôi.
  4. Không nên sử dụng một file css quá nhỏ, tốt nhất nên gộp nó vào hoặc inline nó trên cùng của trang.
<style>
.... your small css instructions here .....
</style>
  1. Không nên dùng style trực tiếp trong thẻ HTMl. <p style="color:red">Some text has red color</p> mà nên dùng nó trong file css riêng.

Ngoài ra bạn có thể tham khảo bài viết của @sonchedinh tại đây. https://viblo.asia/sonchedinh/posts/qm6RWq5zGeJE

4. Render blocking javascripts

Render blocking javascripts tức là các file javascripts sẽ chặn hiển thị của trang web:

render js.png

Render Javascripts có nghĩa là khi tải một trang web, nếu trình duyệt gặp một file hay một thuộc tính javascripts nó sẽ ngừng tải html để tải và thực thi mã javascript, khi nào thực thi xong javascripts thì html mới tiếp tục được tải. Điều này sẽ làm chậm quá trình tải trang web của bạn.

Lời khuyên của google đưa ra là defer or asynchronously vậy defer và asynchronously là gì, và làm sao để fix nó.

// nothing
<script src="scripts.js"></script>
// async
<script src="scripts.js" async></script>

// defer
<script src="scripts.js" defer></script>

Nhìn đoạn code trên ta thấy có 3 cách để load một file javascript. Vậy điển khác nhau giữa chúng là gì:

defer async javascript.jpg

Nhìn vào bức ảnh này bạn có thể thấy cách load trang:

  1. Dòng đầu tiên là cách load trang không có thuộc tính nào, html sẽ dừng tải đến khi mã javascript được tải và thực thi xong. Như vậy trang của bạn phải dừng lại để tải Javascript xong mới tiếp tục tải HTML, nó sẽ làm chậm quá trình load trang web của bạn.
  2. Có thuộc tính async lúc này HTML và Javascript được tải song song, nhưng HTML sẽ dừng tải đến khi javascript được thực thi xong.
  3. Có thuộc tính defer tức là HTML và Javascript sẽ cùng được tải, khi tải xong HTML thì Javascript mới được thực thi.

Vậy nếu file Js của bạn chỉ cần thực hiện khi trang được load hoàn toàn thì có thể dùng thuộc tính defer còn nếu muốn nó được thực hiện cùng với HTML được load thì dùng async.

Do vậy tùy theo tác dụng của file js của bạn mà quyết định cho phù hợp dùng thuộc tính nào.

Chú ý: Nếu bạn dùng thư viện Jquery mà có file php nào đó bạn viết trực tiếp js vào thì thư viện cần được load theo cách thông thường.

Lưu ý nữa là với mã javascript bạn luôn để ở cuối trang web - trước thẻ </body>, và css thì luôn để đầu trang - trước thẻ </head>.

5. Leverage browser caching

Đây có lẽ là một phần rất quan trong đối với bất kỳ website nào. Chúng ta sẽ thông báo cho trình duyệt là phải remember những resources (images, js, css ...) đã được load, khi người dùng sang trang khác hoặc quay lại trang cũ thì những gì đã được load rồi sẽ không phải load lại lần nữa.

Bạn vui lòng tạo 1 file .htaccess hoặc edit nếu đã có và thêm vào đoạn mã sau:

## EXPIRES CACHING ##
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpg "access 1 year"
    ExpiresByType image/jpeg "access 1 year"
    ExpiresByType image/gif "access 1 year"
    ExpiresByType image/png "access 1 year"
    ExpiresByType text/css "access 1 month"
    ExpiresByType text/html "access 1 month"
    ExpiresByType application/pdf "access 1 month"
    ExpiresByType text/x-javascript "access 1 month"
    ExpiresByType application/x-shockwave-flash "access 1 month"
    ExpiresByType image/x-icon "access 1 year"
    ExpiresDefault "access 1 month"
</IfModule>

# 1 Month for most static assets
<filesMatch ".(css|jpg|jpeg|png|gif|js|ico)$">
    Header set Cache-Control "max-age=2592000, public"
</filesMatch>
## EXPIRES CACHING ##

Bạn có thể thay đổi thời gian được cache ở trên cho phù hợp với website của mình.

Lưu ý .htaccess không có tác dụng với web server là NGINX

6. Enable gzip compression

Gzip là một giải pháp để nén file (js, css, html ...) trong quá trình truyền tải qua mạng. Nó sẽ giúp cho dung lượng của file giảm đi đáng kể để tăng tốc độ tải trang web của bạn.

Thêm vào .htaccess đối với server là apache

<ifModule mod_gzip.c>
    mod_gzip_on Yes
    mod_gzip_dechunk Yes
    mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
    mod_gzip_item_include handler ^cgi-script$
    mod_gzip_item_include mime ^text/.*
    mod_gzip_item_include mime ^application/x-javascript.*
    mod_gzip_item_exclude mime ^image/.*
    mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>

Với Apache webservers

Thêm vào .htaccess

AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript

NGINX webservers

Thêm vào file config

gzip on;
gzip_comp_level 2;
gzip_http_version 1.0;
gzip_proxied any;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

# Disable for IE < 6 because there are some known problems
gzip_disable "MSIE [1-6].(?!.*SV1)";

# Add a vary header for downstream proxies to avoid sending cached gzipped files to IE6
gzip_vary on;

6. Lazy loading images

Đối với những website có nhiều hình ảnh thì phần này sẽ rất quan trọng đối với tốc độ load trong web của bạn, lazy loading có thể hiểu là hình ảnh chỉ được tải khi người dùng kéo đến nó. Kéo đến đâu ảnh được load độc lập đến đó.

Trước tiên tải file jquery.lazyload.js tại đây https://github.com/tuupola/jquery_lazyload, chú ý chỉ lấy file jquery.lazyload.js mà thôi.

Nhúng vào website của bạn:

<script src="jquery.js" type="text/javascript"></script>
<script src="jquery.lazyload.js" type="text/javascript"></script>

Đối với trang php hình ảnh sẽ được load như sau:

<img class="lazy" src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-original="img/example.jpg" width="640" height="480">

Bạn có thế thấy src lúc này không phải là hỉnh ảnh bạn muốn, mà nó chỉ là một ảnh base64 có kích thước 1px mà thôi, khi trang được load thì hình ảnh này sẽ không được tải về luôn mà nó sẽ đợi đến khi người dùng kéo đến nó thì nó mới được taỉ về. data-original chính là link đến hình ảnh mà chúng ta cần.

Trong file Js hoặc cuối trang php bạn đặt đoạn code sau:

$("img.lazy").lazyload({
    effect : "fadeIn"
});

Như vậy là chúng ta đã có một trang web có hình ảnh được load theo lazy rồi đó.

Trên đây là toàn bộ những gì mình muốn chia sẻ với bạn, ngoài ra các bạn cũng có thể tìm hiểu thêm về cách tối ưu server như Zend Opcache để website của bạn có hiệu năng cao nhất.

Hy vọng rằng bài viết có ích với bạn.Nếu có bất cứ thắc mắc nào xin vui lòng để lại comment ở phía dưới, tác giả rất vui lòng được giải đáp thắc mắc của bạn.

Thank you for reading!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí