CSS Grid

Gridレイアウトは遅い

ブロックレイアウトで作成した 8000 行を超える HTML ソースをほぼそのまま Grid レイアウトで書き直したところ、画面の表示速度が遅くなった。単純に PC の処理能力の問題なのか、構造的にレンダリングの負荷が大きすぎるのか、エンジンの最適化がまだ進んでいないのか、詳しくはわからないが、いずれにしてもそのままでは使えないレベルであった。

少し具体的に書くと、行事予定表を 3 ヶ月分表示するホームページで、変動要素の行事関連データは javascript でサーバーから一括して非同期通信で取得し、動的に HTML に埋め込んでいる。データはいくつかの要素に分かれていて、中にはアイコンとして小さなイメージ情報も含まれている。1 日のデータは、月、日、曜日、複数の時間区分、複数の行事データ、複数の行事アイコンなどで、平均的には 1 日あたり約 10 要素、3 ヶ月で約 900 要素になる。さらに、個々のデータにはテーブルサーチや疑似要素による処理なども付加される。

それら約 900 個の情報を javascript で動的に書き込む度にリフロー(再描画)が発生する。結果としてスクリプトによる処理時間が 100ms をオーバーすることもあり、極端な場合は、400ms などというケースも発生する。Google Chrome のコンソールでチェックすると確実に時間オーバーの警告が出る。PC の性能やネットワークの能力、レンタルサーバーも水準以上の高性能な範囲であり、この状況ではページを閲覧する一般の利用者からみて不評となること間違いない。

自分が Grid レイアウトを消化不良のまま非効率な使い方をしているのかもしれない。このページを書き直した後、時間の経過とともに Grid レイアウトによって記述したページ数が増え、Auto 機能を使ったシンプルなソースや、自動的な回り込み配置の機能を利用した効率的な記述など、使える技術の幅も広がってきた。現時点で再トライすれば少しは表示速度の高速化につながるのかもしれない。

だがしかし、そう思うようになったのは最近のことで、実は、"遅い"と感じた時点で、リフローの回数を減らす技術を模索し始め、最終的に HTML を javascript で動的に生成する手法に取り組むこととした。

採用した手法は HTML に対する修正を<html></html>の中で行うことなく、ローカルな環境である「 fragmentNode 」の中で行い、行事予定を組み込んで出来上がったオブジェクトをまとめて<html></html>の中に投入するという方法なのだが、行事がない、すなわち HTML の段落ごと不要(あるいは非表示)というケースもあり、あらかじめ最大限の HTML ソースを用意しておいて不要な部分を非表示とするよりも、必要の都度 HTML ソースを書き足していく方が合理的な処理となる。つまり、「修正」ではなくて必要なソースをその都度「生成」するという方法を採用した。結果、HTML は外側の枠組みだけとなり、内容はすべて javascript で生成することとなった。

この手法によって、HTML の行数は約 8300 行から 300 行へと1/27に激減した。動的な部分は javascript で生成するので当然といえば当然なのだが。そして肝心の Chrome の警告は出なくなった。使用開始してまもなく 6 ヶ月が経過しようとしているが、今のところ、見た目に気づかれないような軽微な不具合が 3 件発生したのみで、致命的な不具合は発生していない。

javascript は 8 本のソースで、全体で約 2000 行になった。プログラムの規模としては大きなものでないと思うが、HTML による繰り返し基調の視覚的に分かり易いソースコードから、配列を多用したいかにもプログラム風のソースコードになったため、パッと見には長文の行がぎっしりと並び、わけの分からないものに見える。 それを補うため、ドキュメントの量が多くなることを承知の上で、配列の説明や、最近はあまり見かけなくなったフローチャートを1ステップ対応で書くなど、根気よく見てもらえれば必ず理解できるという環境を整備してきた。

場違いを承知の上で、20 代のときアセンブラー言語でプログラムを書いていた頃を思い出しながら、仕様を確実に書き落とし、机上で事前検証するやり方を実践してみた。ソースコードを書き始めてから完成するまでの期間は数日だった。全体としては間違いなく非効率的だが、時間がかかること以外は今に通用する手法であることを再認識した。非営利の取り組みにあっては 50 年前の昭和の技術もまだまだ使えることを実感した。

話を戻して、fgagmentNode を使用して<html></html>の外で HTML 文を組み立てたと書いたが、javascript が扱うのは単なるテキストではなくて、html オブジェクトなので、HTML を組み立てたというのが正しい。本来ならばレンダリングエンジンが担うべき役割の一部をわざわざ javascript で複雑な仕組みを作って代行したということもできる。リフローの発生を抑止し、処理の高速化に寄与したということがその代償というわけだ。

このような処理は、本来、クライアントではなくてサーバーサイドで HTML ソースを編集する形で行う方が望ましいと思う。HTML ソースを HTML というオブジェクトに仕上げるのはクライアント側のレンダリングエンジンの仕事であって、その役割分担を乱すことはやはり避けたいところだ。しかし、そのために必要なサーバーサイドの技術を持ち合わせないために javascript を使うこととなった。自分の技術の限界でもある。

※掲載記事及び写真に係る著作権は著者に帰属します。著作権を侵害するような利用を禁止します。掲載記事及び写真の全部または一部を複製、蓄積、出版、送信、頒布および改変する等、著者の権利を侵害する利用をすることはできません。