用Flask來寫個輕部落格(28)—使用Flask-Assets壓縮CSS/JS提升網頁載入速度

範桂颶發表於2016-12-20

目錄

前文列表

用 Flask 來寫個輕部落格 (1) — 建立專案
用 Flask 來寫個輕部落格 (2) — Hello World!
用 Flask 來寫個輕部落格 (3) — (M)VC_連線 MySQL 和 SQLAlchemy
用 Flask 來寫個輕部落格 (4) — (M)VC_建立資料模型和表
用 Flask 來寫個輕部落格 (5) — (M)VC_SQLAlchemy 的 CRUD 詳解
用 Flask 來寫個輕部落格 (6) — (M)VC_models 的關係(one to many)
用 Flask 來寫個輕部落格 (7) — (M)VC_models 的關係(many to many)
用 Flask 來寫個輕部落格 (8) — (M)VC_Alembic 管理資料庫結構的升級和降級
用 Flask 來寫個輕部落格 (9) — M(V)C_Jinja 語法基礎快速概覽
用 Flask 來寫個輕部落格 (10) — M(V)C_Jinja 常用過濾器與 Flask 特殊變數及方法
用 Flask 來寫個輕部落格 (11) — M(V)C_建立檢視函式
用 Flask 來寫個輕部落格 (12) — M(V)C_編寫和繼承 Jinja 模板
用 Flask 來寫個輕部落格 (13) — M(V)C_WTForms 服務端表單檢驗
用 Flask 來寫個輕部落格 (14) — M(V)C_實現專案首頁的模板
用 Flask 來寫個輕部落格 (15) — M(V)C_實現博文頁面評論表單
用 Flask 來寫個輕部落格 (16) — MV(C)_Flask Blueprint 藍圖
用 Flask 來寫個輕部落格 (17) — MV(C)_應用藍圖來重構專案
用 Flask 來寫個輕部落格 (18) — 使用工廠模式來生成應用物件
用 Flask 來寫個輕部落格 (19) — 以 Bcrypt 密文儲存賬戶資訊與實現使用者登陸表單
用 Flask 來寫個輕部落格 (20) — 實現登錄檔單與應用 reCAPTCHA 來實現驗證碼
用 Flask 來寫個輕部落格 (21) — 結合 reCAPTCHA 驗證碼實現使用者註冊與登入
用 Flask 來寫個輕部落格 (22) — 實現部落格文章的新增和編輯頁面
用 Flask 來寫個輕部落格 (23) — 應用 OAuth 來實現 Facebook 第三方登入
用 Flask 來寫個輕部落格 (24) — 使用 Flask-Login 來保護應用安全
用 Flask 來寫個輕部落格 (25) — 使用 Flask-Principal 實現角色許可權功能
用 Flask 來寫個輕部落格 (26) — 使用 Flask-Celery-Helper 實現非同步任務
用 Flask 來寫個輕部落格 (27) — 使用 Flask-Cache 實現網頁快取加速

擴充套件閱讀

http://flask-assets.readthedocs.io/en/latest/
Flask-Assets例項學習
Flask-Assets中文參考

Flask-Assets

在訪問 Web 應用的時候瀏覽器會在載入和解析為 HTML 檔案之後, 再下載大量的 CSS/JS 檔案, 傳送了大量的 HTTP 請求. 雖然現在很多瀏覽器能夠支援並行下載, 但也是由限制的, 所以這就成為了網頁載入速度的另外一個瓶頸.

Flask-Assets 能夠幫助我們將多個 CSS 或 JS 檔案合併成為一個大的檔案, 並且將這個檔案中的空白符和換行符去除, 這樣能夠讓檔案的 Size 減少近 30%. 而且 Flask-Assets 還會使用特定的 HTTP Response Header, 讓瀏覽器快取這些檔案, 只有在這些檔案的內容被修改時, 才會再次下載, 這個功能一般的 HTTP 方式是不會有的.

  • 安裝 Flask-Assets
pip install Flask-Assets, cssmin, jsmin
pip freeze > requirements.txt

將 Flask-Assets 應用到專案中

  • 初始化 assets 物件, 並建立打包物件
    vim jmilkfansblog/extensions.py
from flask_assets import Environment, Bundle


#### Create the Flask-Assets`s instance
assets_env = Environment()
# Define the set for js and css file.
main_css = Bundle(
    `css/bootstrap.css`,
    `css/bootstrap-theme.css`,
    filters=`cssmin`,
    output=`assets/css/common.css`)

main_js = Bundle(
    `js/bootstrap.js`,
    filters=`jsmin`,
    output=`assets/js/common.js`)

NOTE 1: Bundel() 的構造器能夠接受無限個檔名作為非關鍵字引數, 定義那些檔案需要被打包, 這裡主要打包本地 static 下的 CSS 和 JS 兩種型別檔案.
NOTE 2: 關鍵字引數 filters 定義了這些需要被打包的檔案通過那些過濾器(可以為若干個)進行預處理, 這裡使用了 cssmin/jsmin 會將 CSS/JS 檔案中的空白符和換行符去除.
NOTE 3: 關鍵字引數 output 定義了打包後的包檔案的存放路徑
NOTE 4: 上述的所有路徑的字首都會預設為 ./static/

  • 將 assets 和包物件註冊到 app 物件中
from jmilkfansblog.extensions import assets_env, main_js, main_css

...

def create_app(object_name):
    """Create the app instance via `Factory Method`"""

...

    #### Init the Flask-Assets via app object
    assets_env.init_app(app)
    assets_env.register(`main_js`, main_js)
    assets_env.register(`main_css`, main_css)

注意: 在開發環境下不應該將 CSS/JS 檔案打包, 因為我們可能會經常對這些檔案進行修改, 所以需要設定在開發環境中不打包, 但生產環境中會自動進行打包.

vim jmilkfansblog/config.py

class DevConfig(Config):
    """Development config class."""

    #### Flask-Assets`s config
    # Can not compress the CSS/JS on Dev environment.
    ASSETS_DEBUG = True

NOTE 1: ProdConfig 不需要修改, 預設是自動打包壓縮的.

  • 使用特殊的 Jinja 控制程式碼來修改 templates 中的 CSS/JS 引用標籤 <link><script>

link Old:

  <link rel="stylesheet" href="{{ url_for(`static`, filename=`css/bootstrap.css`) }}">

link New:

  {% assets "main_css" %}
  <link rel="stylesheet" type="text/css" href="{{ ASSET_URL }}">
  {% endassets %}

script Old:

<script src="{{ url_for(`static`, filename=`js/bootstrap.js`) }}"></script>

script New:

  {% assets "main_js" %}
  <script src="{{ ASSET_URL }}"></script>
  {% endassets %}

經過這些處理之後, 如果 templates 檔案的 link 或 script 使用的 css/js 檔案路徑已經被包含在了 Bunble 中, 那麼這些原來會被載入到瀏覽器中 CSS/JS 檔案, 將不會再被載入, 取而代之的是被壓縮過的 Size 更小的檔案.

  • 我們也可以使用 manager shell 指令的方式來打包 CSS/JS 檔案
from flask_assets import ManageAssets
from jmilkfansblog.extensions import assets_env

...

# Pack the static file
manager.add_command(`assets`, ManageAssets(assets_env))

這樣我們就能夠通過指令 python manage.py assets -h 來檢視其使用方法了:

usage: manage.py assets [-h] [-v] [-q] [--jinja-extension JINJA_EXTENSION]
                        [--parse-templates]
                        {watch,build,clean,check} ...

Manage assets.

positional arguments:
  {watch,build,clean,check}

optional arguments:
  -h, --help            show this help message and exit
  -v                    be verbose
  -q                    be quiet
  --jinja-extension JINJA_EXTENSION
                        specify the glob pattern for Jinja extensions
                        (default: *.html)
  --parse-templates     search project templates to find bundles


相關文章