ユーニックス総合研究所

  • home
  • archives
  • django-blog-create

Djangoでブログを2つ作成して得られた知見

  • 作成日: 2022-06-07
  • 更新日: 2023-12-25
  • カテゴリ: Django

ブログをDjangoで作った

2つのブログをDjangoで作ってみた。
1つは2019年6月にリリース。
もう1つは2020年8月にリリース。

2022年現在、もう2~3年ほど2つのブログを運営し更新を続けている。
Djangoでブログを作ってみて得られた知見をまとめておこうと思う。

関連記事

低スペックサーバーでDjangoとuWSGIを動かす時の設定
adminサイトにモデルを追加する【Django】
Django入門: 簡単な一行掲示板アプリを作る その1【Windows10】
Django入門: 管理サイト ~ 簡単な一行掲示板アプリを作る その11【Windows10】
Django入門: 微調整 ~ 簡単な一行掲示板アプリを作る その15【Windows10】

スピードに問題はあるか?

Pythonと言えば遅いと言われている。
当然、Python製のDjangoも遅いのではないか?
という話になる。

結論から言うと、速度はそれほど問題にはならない。
仮にDjango製のサービスが遅いのであればそれはDjangoに問題があるのではなく別のところに問題があると言える。

なぜこんなことが言えるのかというと、自分のブログはPageSpeed Insightでパフォーマンスのスコアを70~80点ぐらい出しているからである。
だからDjangoでブログを作る際はそれほどスピードのことは気にしなくてよいだろう。
もし遅くなったらJavaScriptを疑ったほうがいい。
JavaScriptのコードとJavaScriptの読み込みは非常に時間がかかる。

ブログの構築難易度は?

ブログの構築難易度は小中大で言うと中ぐらいである。
動的サイトなのでほどほどに難易度はある。
だがめちゃくちゃ難しいと言えばそんなことはない。
高度なアルゴリズムも使わないし、エンジニアとして中ぐらいのスキルがあれば十分構築できるだろう。

だがこれはブログに限らずサービス全般に言えることだが最初に行った設計はその後数年、いやずっと付き合うことになる。
どういうことか説明しよう。

記事のURLの設計

自分の作ったブログは記事のURLをスラッグで表現している。
たとえば↓のようなURLになる。

blog/2022/5/1/my-django-work/  

このURLには日付とそれからスラッグが含まれている。
特に深く考えずにこの設計にしたが記事のURLの設計というのはそんな適当にやるものじゃない。
記事というのは一度公開したらその後半永久的に公開していくことになる。
だからURLの設計に不満があったら途中で301リダイレクトなどを検討しなくてはいけない。

このURLの設計で私が持っている不満は↓のとおりである。

  • 日付のせいで仕事が増える

Djangoで書いたコードの内部では記事を取得するコードも多い。
そして記事のURLを取得するコードも自然と増える。
そうなったときにこのURLの設計だと記事の取得に日付を考慮しないといけない。

それで日付というのはけっこう繊細なデータだ。
データベースのタイムゾーンが設定されていないだけで変わったりする。
サーバー移転などでは日付がちゃんと合うようにデータベースやその他をセットアップしなくてはいけない。
仮にそういったセットアップが間違っていて、コードで生成される日付が1日ズレたりするとしよう。
そうすると記事すべてのURLが無効になってしまう可能性が出てくる。
これは大変ストレスの多い懸念事項である。

サーバー移転といえばサーバーのOSを変える時もこのことを覚えておかないといけない。
記事のURLが無効にならないようにテストを書き、そしてセットアップが完了したらちゃんと日付が合っているかテストをする。
そういうことをやる必要がこのURLの設計によって出てくる。

これは大変コストが高いことだ。

なぜ日付によって管理コストが高くなるのか?

なぜこんなにコスト高になるのかというと、この記事のURLの日付には記事のcreatedを使っているからである。
記事をArticleというモデルにしたとしよう。
そうするとArticleは↓のような設計になる。

from django.db import models  


class Article(models.Model):  
    title = models.CharField(max_length=255, help_text='記事のタイトル')  
    content = models.TextField(help_text='記事のコンテンツ')  
    created = models.DateTimeField(auto_now_add=True, help_text='作成日')  

↑のような日付(created)からURLの日付は生成される。
たとえばArticleにget_url()のようなメソッドを定義して、そのメソッド内で日付を使ってURLを生成する。

深く考えずに設計するとこんな感じのコードになる。
データベースに保存する日付のデータから記事の日付を再現するのはごくごく自然なことだろう。

タイムゾーンと日付

だが先ほど書いたように日付というのは繊細なデータである。
設定が違うだけですぐ変わってしまう揮発的なデータだ。

データベースに設定するタイムゾーンが違うと、この日付は異なる値になることがある。
たとえばタイムゾーンがAsia/TokyoからSystemになっただけで、先ほどのコードが生成する記事の日付は変わってしまうのだ。

このようなタイムゾーンの設定ミスが起こるとブログの記事はどんなことになるだろうか。
検索エンジンにインデックスされている記事のURLが無効になる可能性がある。
そうするとせっかく検索上位にインデックスされた記事がおしゃかになってしまう。

これは大変問題のある設計であると言える。

どうすれば良かったか?

この設計の問題は記事のcreatedから、つまりデータベースに保存されている日付データから記事のURLを生成している点である。
日付というのは設定によって表示される値が異なる場合があるから、こういった大事なところに使ってはいけないと思う。

createdの日付を使うのではなくてベタ打ちの文字列にするべきだっただろう。
つまりDateTimeFieldを使うのではなくてCharFieldにしてべた書きの日付にしておけばこんな問題は起こらない。

あるいスラッシュで日付を区切るのをやめてスラッグに日付を含めるという方法もある。

あるいは記事のURLに日付を含めないほうが良かった。
これが一番良い。

対策は?

これの対策は301リダイレクトなどがあげられる。
ページの評価を維持したまま、新しいURLに記事をリダイレクトするのだ。
Djangoではredirect()関数で行える。

実は私のブログはいまのところこの方法を検討中である。
(現在は対応済み)
古い日付を含んだURLから新しいスラッグのみのURLにリダイレクトする。

リダイレクトであればSEO的なページの評価を引き継ぐことができると調べると出てくる。

新しい URL にリダイレクトすると、リンクのクレジットは失われますか?
いいえ。301 や 302 のリダイレクトは PageRank の損失につながりません。.

だからこの方法は有効であろう。

ブログは速度がとにかく大事

ブログを作り運営していて実感するのが「速度」の大事さである。
具体的にはページ表示速度だ。

ブログのユーザーがどこから流入するかというとそのほとんどは検索エンジンからの流入である。
それで検索エンジンというのはページ表示速度が遅いページを優遇してくれない。

むしろページ表示速度が遅いページは検索上位に表示しなくなってしまう。
だからブログではとにかく速度が大事である。

こういったSEOに無知だと(かつての私だが)ページ表示速度よりも見た目のクオリティに気をつかうようになる。
つまりJavaScriptやCSSで見た目をリッチにしてアニメーションさせたりギミックを仕込んだりする。
画像をふんだんに使いきらびやかな見た目にするように努める。

それは創作的には楽しいことである。
だがそういった創作を続けるとどうなるか?
JavaScriptとCSSのコードは多くなり結果的にページ表示速度が下がる要因を作ってしまう。
特に画像などはモバイルではかなり神経質なオブジェクトだ。

最近の検索エンジンはモバイルでの表示速度を非常に重視するようになっている。
ブログのメインユーザーはパソコンユーザーであるが、検索エンジンの上位に記事を表示したい場合はモバイルにも気をつかわないといけない。

PageSpeed Insightなどでは一般的にパソコンよりモバイルのスコアが悪いことが多い。
だからモバイルのスコアをどのように上げるかが一番の関心ごとになる。

効果的な施策は何か?

モバイルでの表示速度を上げるのに効果的な施策は↓の2つだ。

  • JavaScriptの遅延読み込み
  • 画像を減らす

たとえばブログでアドセンスの広告を使っているとする。
そうするとアドセンス用の外部スクリプトを読み込む必要が出てくる。
だがこのアドセンスの外部スクリプトは非常に重い。
だから普通に読み込もうとするとパフォーマンスのスコアを下げることになる。

このような場合はスクリプトの遅延読み込みが有効である。
たとえばアドセンスのスクリプトなら「スクロールが始まったら読み込む」というコードにしておく。
こうするとPageSpeed Insightでのスコアが上がることがある。

また画像は非常に重いのが一般的である。
画像をふんだんに使っているコンテンツはページ表示速度が下がる。
モバイルのページでは画像をあまり使わないようにしたほうが良いだろう。

おわりに

今回はDjangoでブログを2つ作ってみた知見をあなたに共有した。
これからDjangoでブログを作る人の参考になると嬉しい。

🦝 < 画像は重いって

🐭 < 俺ら重いのか……

参考文献