Web 1.5たたはAjaxの郚分的な眮き換え

HelloHabrauser。

最初ずは異なり、その䞻な欠点がない、ajaxテクノロゞヌのアナログのアむデア/実装を共有したいず思いたす。 ajax wikiから、次のこずがわかりたす 。

メリット
  • トラフィックの節玄。
  • サヌバヌの負荷を軜枛したす。
  • むンタヌフェヌスの反応の加速。

欠点
  • 暙準ブラりザツヌルずの統合の欠劂。
  • 動的にロヌドされたコンテンツは怜玢゚ンゞンでは利甚できたせん。
  • サむト統蚈の叀い䌚蚈方法は無関係になりたす。
  • プロゞェクトの耇雑さ。


テンプレヌトクラむアントキャッシュ以埌TCCの発明のアむデアには、ajaxず同じ利点がありたすが、その欠点はたったくありたせん。

アむデア


ajaxの堎合、䞻な「トリック」は個々のブロックをロヌドするこずであり、これによりトラフィックが倧幅に節玄されたす。 しかし、ajaxの倧きな問題は、叀いブラりザヌず怜玢゚ンゞンの䞡方ずの匷い非互換性、および既存のプロゞェクトぞの耇雑な統合です。 ブロック䞊の次のサむトをajaxで曞き盎しおパズルを解くず、珟代のテクノロゞヌの助けを借りおも同様の結果を達成するこずは実際には䞍可胜ですが、実装ず互換性のコストは䜎くなりたすか だから...氎を泚ぎ終えたしょう...アむデアは非垞に単玔です曎新する必芁があるものだけをロヌドしたす実際には、ajaxのアむデアによく䌌おいたす。 党䜓の問題は実装です。 基瀎は、JSのニヌズlocalStorageなどのためにある皮のストレヌゞをサポヌトするための最新の暙準ず、サヌバヌ偎でテンプレヌトをキャッシュするずいうアむデアでした。 それらを暪断しお、TCCを取埗したした。 ぀たり、サヌバヌ䞊のテンプレヌトの堎合のように、ペヌゞ党䜓は通垞、別々のファむルコヌドによっお凊理および圢成された郚分に分割され、ナヌザヌによっお結合および砎棄されたす。 倚くの堎合、䞀郚の断片はキャッシュされ、しばらくの間再構成されたせん。 アむデアは、このキャッシュの䞀郚をクラむアント偎に転送し、クラむアントからサヌバヌに情報を転送し、キャッシュをリキッド状態に維持するためのむンフラストラクチャを䜜成するこずです。 ぀たり ペヌゞをロヌドするずき、通垞通り、サヌバヌ偎でフォヌムを䜜成し、いく぀かのブロックをスキップしたすが、サヌバヌキャッシュからそれらを取埗せず、単に空のたたにしたす。この圢匏では、クラむアントに転送したす。既存のキャッシュを䜿甚しお、結果のペヌゞをナヌザヌに衚瀺したす。 説明から、次のこずが明らかです。


画像

党䜓ずしお、TCCの䞀連の䜜業は次のように衚すこずができたす。


実装


デモのサンプルも短期間で収集するこずは明らかです。したがっお、倚くのこずに目を぀ぶりたすhtmlの解析にjQueryを䜿甚するなど、迅速な結果を埗るための軜さ。

以䞋に瀺すように、改善できるもののリストですので、デモの䟋本番環境でのアプリケヌションの芳点からを批刀しないでください。

たず、キャッシュ甚にブロックをマヌクする方法を決定する必芁がありたす。 簡単にするために、暙準のhtml span芁玠を䜿甚したした。これは、含たれるブロックにほずんど圱響を䞎えないためです぀たり、ネストされたフロヌティングブロックおよびむンラむンコンテキストで通垞動䜜したす。 これがマヌカヌであるこずを瀺すために、次の原則によっお呌び出される特別なクラスが遞択されたした。
tcc_ <ID> _ <MODE> [_ <TTL>];
どこで
<ID>-䞀意のブロック番号。
<MODE>-キャッシングモヌド以䞋に぀いお。
<TTL>-キャッシュの有効期間。

キャッシングモヌドは、クラむアントが凊理しおいるブロックをクラむアントに瀺すこずを目的ずしおいたす。 3぀のキャッシュモヌドが割り圓おられたした。
rリアルタむム-キャッシュの察象ではないブロックペヌゞがリロヌドされるたびに曎新されたす;
sサヌバヌ-サヌバヌ䞊に圢成され、キャッシュの察象ずなるブロックキャッシュ内のブロックを圢成たたは眮換する必芁がある堎合に䜜成されたす;
cクラむアント-クラむアントがキャッシュされたデヌタを配眮する空のサヌバヌ䞊に圢成されたブロック。

実装に移りたしょうサヌバヌコヌドはPHPにありたすが、䜕にでも曞き換えるこずは難しくないず思いたす。 たず、ブロックの先頭を圢成する単玔な関数を䜜成したす実際、この関数は、いく぀かの入力デヌタに基づいお、特別なクラスで暙準スパンを圢成する必芁がありたす。

function blockStart($id, $ttl = false)
{
global $curTime;
global $tcc;

if (!$ttl)
{
echo '<span class="tcc_' . $id . '_r">';
return true;
}
else if (isset($tcc[$id]) && ($tcc[$id] > $curTime))
{
echo '<span class="tcc_' . $id . '_c_' . $tcc[$id] . '">';
return false;
}
else
{
echo '<span class="tcc_' . $id . '_s_' . $ttl . '">';
return true;
}
}


ご芧のずおり、この関数は2぀の倖郚倉数、$ curTime必芁な圢匏の珟圚時刻、および$ tccクラむアントのキャッシュのリスト。以䞋のクラむアントからサヌバヌで受信するこずに぀いお説明したすを䜿甚したす。 関数の残りのロゞックは非垞にシンプルで簡単です。

次に、ストレヌゞこの堎合はlocalStorageを操䜜するための特定のサヌビス関数セットをクラむアント偎぀たり、JS偎で蚘述する必芁がありたす。

function storSet(id, ttl, value)
{
localStorage.setItem('tcc_' + id, ttl + ':' + value);
}

function storGet(id, ttl)
{
var data = localStorage.getItem('tcc_' + id);
if (data == null) return null;

var data_ttl = data.substr(0, 12).split(':', 1)[0];
if ((data_ttl != ttl) || (data_ttl <= curTime)) return null;

return data.substr(data_ttl.length + 1);
}


ここでもすべおが簡単です... storSetでは、ブロックの有効性をチェックするためにidを指定しおttlを保存するこずを忘れずにデヌタを保存したす。 storGetでは、そのIDでブロックを取埗し、ttlの有効性を確認し、成功した堎合、キャッシュされたブロックを返したす。

次に、サヌバヌから受信したすべおを解析するメガパヌサヌが必芁です。

function tcc()
{
var item;

while ((item = $('[class^=tcc_]:first')) && (item.length != 0))
{
var cn = item.attr('class').split('_');

if (cn[2] == 's')
{
var nItem = item.clone();
var cItem;

while ((cItem = nItem.find('[class^=tcc_]:first')) && (cItem.length != 0))
{
cItem.replaceWith('<span class="cache_' + cItem.attr('class') + '"></span>');
}

storSet(cn[1], cn[3], nItem.html());
}
else if (cn[2] == 'c')
{
var data = storGet(cn[1], cn[3])

if (data == null)
{
alert('critical error');
}
else
{
var nItem = $('<span>' + data + '</span>');
var cItem;

while ((cItem = nItem.find('[class^=cache_tcc_]:first')) && (cItem.length != 0))
{
var ncn = cItem.attr('class').split('_');

var rItem = item.find('[class^=tcc_' + ncn[2] + '_]');

if (rItem.length != 0)
{
cItem.replaceWith('<span class="' + rItem.attr('class') + '">' + rItem.html() + '</span>');
}
else
{
cItem.remove();
}
}

item.replaceWith(nItem.html());
}
}

if (cn[2] != 'c')
{
item.replaceWith(item.html());
}
}

...

}


コヌドは非垞に透過的であるため、ここで説明するこずはあたりありたせん。 ブロックを芋぀けた->それがわかった->必芁なアクションを生成した。

その結果、クラむアント偎で行うべきこずは、サヌバヌがキャッシュを持っおいるこずをサヌバヌに知らせるこずだけです。これにより、サヌバヌは埌続のペヌゞを正しく圢成できたす。 トランスポヌトの圢匏では、シンプルで基本的なCookieが遞択されたした。

function tcc()
{

...

var storage = '';

for (var i = localStorage.length - 1; i >= 0; i--)
{
var key = localStorage.key(i);
var prefix = key.split('_', 1)[0];
var key = key.substr(prefix.length + 1);

if (prefix != 'tcc') continue;

var ttl = storExist(key);

if (ttl != null)
{
if (storage.length != 0) storage += ',';

storage += key + '_' + ttl;
}
else
{
localStorage.removeItem('tcc_' + key);
}
}

var cookie = 'tcc=' + escape(storage) + ';path=/';

if (storage == '') cookie += ';expires=Thu, 01-Jan-1970 00:00:01 GMT';

document.cookie = cookie;
}


Cookieは非垞に透過的に圢成され、倉庫を通過しおブロックを探し、Cookieのリストに各ブロックのIDずTTLを蚘入したす。 指定されたコヌドでは、別のサヌビス関数storExistが䜿甚されたす。これは、ブロックが有効な堎合にブロックのTTLを返すこずを陀いお、storGetずほが同じです。

function storExist(key)
{
var data = localStorage.getItem('tcc_' + key);

if (data == null) return false;

var data_ttl = data.substr(0, 12).split(':', 1)[0];

if (data_ttl <= curTime) return null;

return data_ttl;
}


さお、クラむアント偎では、基本的にすべおを実行し、サヌバヌに戻りたした。 冒頭で、特定の$ tcc配列マヌカヌブロックの圢成機胜甚に蚀及したした。これは、圢成する必芁がありたす。

if (isset($_COOKIE['tcc']))
{
$list = explode(',', $_COOKIE['tcc']);

for ($i = 0; $i < count($list); $i++)
{
$item = explode('_', $list[$i]);

if (count($item) == 2)
{
$tcc[$item[0]] = $item[1];
}
}
}


すべおが基本です。

たずめ


私は実隓の結果に非垞に満足しおいるず蚀わなければなりたせん。 最埌のスクリプトでは、キャッシュを自動的に凊理し、可胜な限り少ないトラフィックをマヌゞしお送信する単玔なシステムを埗たした。 最終的なJSスクリプト理論的には垞にクラむアントからサヌバヌに送信する必芁がありたすは、2kの圧瞮YUVトラフィックを受け取りたすが、非圧瞮のGZipトラフィックは、私にずっおはかなり蚱容範囲です。 たた、叀いブラりザヌたたは怜玢゚ンゞンの堎合、クラむアント偎はJS、localStorageたたはCookieをサポヌトしないため、サヌバヌは垞にクラむアント偎にキャッシュがないず刀断し、垞にフルペヌゞを圢成したす぀たり、高霢者ずの互換性を備えた自動システムを手に入れたした。これは私にずっおずおもクヌルです。 たた、テンプレヌト゚ンゞンず簡単に組み合わせおブロックをマヌクし、プログラマヌが䞍必芁なhemoを䜿わずにクラむアント偎ずサヌバヌの䞡方にキャッシュできる、かなり単玔なサヌバヌ実装も泚目に倀したす。 たた、オプションで、この方法でJSずCSSをドキュメントの本文に盎接キャッシュするこずができたすちなみに、この堎合、必芁なスクリプトずスタむルをすべお含めるこずができたす。 この堎合、各JSたたはCSSを個別のブロックに分離および分離するこずにより、必芁なJSおよびCSSコヌドのみをロヌドする䟿利で基本的なシステムを取埗し、サヌバヌリク゚ストを最小限に抑えたすこのリク゚ストが単なるキャッシュ怜蚌であっおも。

短所たたは別の方法でできるこず


明らかに、jQueryを取り陀く必芁がありたすこれは理解できたす。
ブロックのマヌキングを<-cc_ <ID> _ <MODE> [_ <TTL>]->のようなものに倉曎したす。この堎合、暙準ずの互換性や共有htmlの敎合性を心配せずにブロックをマヌクできたすただし、スパンブロックでは、完成したhtmlブロックのみをカットする必芁がありたす。そうしないず、TCCブラりザヌからサポヌトされおいない堎合、すべおがバラバラになりたす。

アむデア自䜓の䞻な欠点は次のずおりです。


たあ、それがすべおです...
最適化のための合理的な批刀ずアむデアを聞きたいです。 すべおの質問に喜んでお答えしたす。

PS残念ながら、誰かが私に1぀のphpファむルの堎所を教えおくれたら、私は感謝するでしょう、䜜業スクリプトの䟋をレむアりトするこずはできたせん。
UPD。 PS実䟋ぞのリンク catsmile.heliohost.org/Mear/tcc.php 堎所に぀いおはcatsmileに感謝

UPD.2 PPSこのトピックの目的を理解するあいたいさを排陀するために、明確にしたす。 本圓の意味でのajaxの眮き換えは提案したせん。 特定の実装では、クラむアントキャッシングのオプションのみを怜蚎するこずを提案したす。 たた、実蚌されたコヌドは完党であるず䞻匵せず、アプロヌチを実蚌する目的でのみ䜜成されたした。 このトピックの䞻な目暙は、クラむアント偎でいく぀かのブロックをキャッシュするアむデアず、これらのブロックを操䜜する方法に関するアむデアずコメントを収集するこずです。

Source: https://habr.com/ru/post/J97414/


All Articles