Django/Mezzanine Templateに
critical CSS を
前提
以下の
OS
CentOS release 6.9 (Final)Python Version
Python 2.7.8Package (必要そうな
ものだけ 抜粋)
Django (1.10.7) Mezzanine (4.2.3) mezzanine-pagedown (1.0)
動的ページ での critical CSS を 読み込む際の 関心事
critical CSS は、
ページ描画時に
critical css を 生成する。 次回の 読み込み時は cache から 取得する。 2
[2] 一度目の読み込み時は 遅い。 デプロイ後に、
別タスクで、 critical css を 生成する。 ページ側は ファイルが 生成されていたら、 html 上に インライン展開する。 開発環境で
デプロイ後に、 事前に 生成して おく。 Production 環境では 事前生成した ものを 組み込み、 読み込む。
3 でできると、
Django pulgin で 作成されている ものが あるか ?
Django で、
現在、
この
以降は、django-critical
に
Django-critical を 使う
設定の 流れ
django-critical
を
1.前提とnode.js
の
django-critical
は、penthouse
はnpm
にnpm
はnode.js
に
2.django-critical の
django-critical
の
3.template ファイルの
template ファイルに
4.動作確認
1. 前提となる node.js
の ライブラリの インストール
node.js
関連の
node npm の
インストール
node.jsをyumで インストールする (centos6.5) - Qiita を 参考に しました。 WARNING がyum install gcc gcc-c++ yum install epel-release yum install nodejs npm --enablerepo=epel
出ますが、 強行します。 パッケージをダウンロードしています: warning: rpmts_HdrFromFdno: Header V4 RSA/SHA1 Signature, key ID f2ee9d55: NOKEY Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo Importing GPG key 0xF2EE9D55: Userid : CentOS SoftwareCollections SIG (https://wiki.centos.org/SpecialInterestGroup/SCLo) <security@centos.org> Package: centos-release-scl-rh-2-3.el6.centos.noarch (@extras) From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
penthouse の
インストール
django-critical
で使用可能な penthouse
のversion は 結構前の ものです。
python からは、index.js
ではなく、penthouse.js
を指定する 必要が あり、 0.4.0
以前だと、penthouse.js
がバンドルされていますので、 ここでは、 alpha 版ではない1番新しい version の 0.3.6
をインストールします。
また、settings.py
のdefault 設定に 従う 場合は、 django-project の root フォルダの 配下に node_module
フォルダがあると、 設定が しやすいので、 install コマンドは django-project の root フォルダで 実施するのを お勧めします。 npm install penthouse@0.3.6
2.django-criticalの インストール、 設定
django-critical には、
あまりよい
Fixes Encoding issue by programmdesign · Pull Request #4 · martinblech/django-critical
django-critical を
この
django-critical の インストール
pip でdjango-critical
を
pip install git+https://github.com/kemsakurai/django-critical pip list | grep django-critical --------------------------------------------- django-critical (0.1.1) ---------------------------------------------
設定
基本的に、
settings.py
に
INSTALLED_APPS critical を
追加 INSTALLED_APPS = ( # other apps "critical", )
MIDDLEWARE_CLASSES に、
"critical.middleware.CriticalCssMiddleware"
を追加 MIDDLEWARE_CLASSES = ( .... # django-htmlmin "htmlmin.middleware.HtmlMinifyMiddleware", "critical.middleware.CriticalCssMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", ... )
CRITICAL_PENTHOUSE_PATH と、
CRITICAL_PHANTOMJS_PATH の 設定
以下のように、penthouse.js
のpath と phantomjs
のpath を 設定します。
phantomjs
は、penthouse.js
をインストールすると、 芋づるで インストールされます。 CRITICAL_PENTHOUSE_PATH = os.path.join( BASE_DIR, 'node_modules/penthouse/penthouse.js') CRITICAL_PHANTOMJS_PATH = os.path.join( BASE_DIR, 'node_modules/penthouse/node_modules/phantomjs/bin/phantomjs')
3.template ファイルの 調整
以下、
base.htmlの
抜粋 {% load critical %} {% critical %} {% compress css %} <!-- Bootstrap Core CSS --> <link href="{% static "css/bootstrap.min.css" %}" rel="stylesheet"> <link href="{% static "css/clean-blog.min.css" %}" rel="stylesheet"> <!-- Custom Fonts --> <link href="{% static "css/font-awesome.min.css" %}" rel="stylesheet"> <link href="{% static "css/fonts.css" %}" rel="stylesheet"> <!-- Code Hilite --> {% ifinstalled mezzanine_pagedown %} <link rel="stylesheet" href="{% static "css/codehilite.css" %}"> {% endifinstalled %} {% if LANGUAGE_BIDI %} <link rel="stylesheet" href="{% static "css/rtl.css" %}"> {% endif %} {% ifinstalled cartridge.shop %} <link rel="stylesheet" href="{% static "css/cartridge.css" %}"> {% if LANGUAGE_BIDI %} <link rel="stylesheet" href="{% static "css/cartridge.rtl.css" %}"> {% endif %} {% endifinstalled %} {% block extra_css %}{% endblock %} {% endcompress %} {% endcritical %} ................. {% autoescape off %} {% critical_async %} {% endautoescape %} </body>
criticalタグの
ロード
{% load critical %}
でタグの 読み込みを します。 criticalCSS を
生成したい 箇所を 囲む
{% critical %}
、{% endcritical %}
で、criticalCSSを 生成したい 箇所を 囲みます。
上記は、タグ内に django-compressor の {% compress css %}
タグがあり、 圧縮、 結合して 作成されたcssファイルの criticalCSSを 生成します。 元々の
css の 遅延ロードを 行う
body タグ直前に以下の タグを 追加する ことで、 criticalCSSの 出力対象 css ファイルを 遅延読み 込みする ことができます。 上記タグで、{% autoescape off %} {% critical_async %} {% endautoescape %}
以下の HTMLが 出力されます。 で、<script> !function(e){"use strict";var n=function(n,t,o){function r(e){if(a.body)return e();setTimeout(function(){r(e)})}function i(){l.addEventListener&&l.removeEventListener("load",i),l.media=o||"all"}var d,a=e.document,l=a.createElement("link");if(t)d=t;else{var s=(a.body||a.getElementsByTagName("head")[0]).childNodes;d=s[s.length-1]}var f=a.styleSheets;l.rel="stylesheet",l.href=n,l.media="only x",r(function(){d.parentNode.insertBefore(l,t?d:d.nextSibling)});var c=function(e){for(var n=l.href,t=f.length;t--;)if(f[t].href===n)return e();setTimeout(function(){c(e)})};return l.addEventListener&&l.addEventListener("load",i),l.onloadcssdefined=c,c(i),l};"undefined"!=typeof exports?exports.loadCSS=n:e.loadCSS=n; var elem = document.getElementById("django-critical-async-css-marker"); loadCSS('https://www.monotalk.xyz/static/CACHE/css/690a0d57c104.css', elem); elem.parentNode.removeChild(elem); }("undefined"!=typeof global?global:this); </script>
もともと CSS の リンクが 出るはずの 場所に、 inline CSS が 書き出させれます。
4.動作確認
動作確認の
初回表示時は
異常に 遅い
初回表示時、ページ描画とともに、 penthouse
のコマンドが 実行され、 phantomjs
が起動します。
10秒ほどページ描画に 時間が かかり、 inline CSS の cache が 作成され、 2回目の 表示以降 cahce が 使われ 早くなる 動作と なります。
ですので、実ユーザが 初回起動に あたらないように、 cache 作成の タイミングを 工夫する 必要が あるかと 思います。 実施前、
実施後の Page Speed Insight の 点数
実施前、88点で、 実施後、 92点に なりました。
実施労力の割に 点数の 上がり 幅は 低いです。
まとめ
Django/Mezzanine のdjango-critical
を
以下、
django-compressor との
相性が いい。
compressor で圧縮/結合した CSS を 入力に 用いる ことができ、 また CSS の 遅延読み 込みが 可能な ため 競合する ことなく 使えます。 メンテされていないが、
動く。
日本語環境で使えない バグも あり、 依存する node ライブラリが 古いです。 頑張って 動かすことは できましたが、 仕事で 使ったりするには 少し 不安です。 エンコードの
問題を 解決し、 新しめの critical で 動かす?
penthouse
の新しい version で 動くようにして、 エンコードの 問題を 解決すれば、 結構イケてる ものに なりそうな 気が します。
critical を
以上です。
コメント