javascript - 無効 - pointer-events none 効かない
JavaScriptを無効にする前にCSSを含めることをお勧めしますか? (9)
オンラインの無数の場所では、私はJavaScriptの前にCSSを含めることを勧めました。 推論は、一般的に、この形式です:
あなたのCSSとJavaScriptを注文する際には、CSSが最初に来るようにします。 理由は、レンダリングスレッドがページをレンダリングするのに必要なすべてのスタイル情報を持っているからです。 JavaScriptが最初に含まれる場合、JavaScriptエンジンは次のリソースセットに進む前にすべて解析する必要があります。 つまり、レンダリングスレッドは必要なスタイルをすべて持っていないため、ページを完全に表示することはできません。
私の実際のテストでは、
私のテストハーネス
私は以下のRubyスクリプトを使用して、さまざまなリソースに対して特定の遅延を生成します。
require 'rubygems'
require 'eventmachine'
require 'evma_httpserver'
require 'date'
class Handler < EventMachine::Connection
include EventMachine::HttpServer
def process_http_request
resp = EventMachine::DelegatedHttpResponse.new( self )
return unless @http_query_string
path = @http_path_info
array = @http_query_string.split("&").map{|s| s.split("=")}.flatten
parsed = Hash[*array]
delay = parsed["delay"].to_i / 1000.0
jsdelay = parsed["jsdelay"].to_i
delay = 5 if (delay > 5)
jsdelay = 5000 if (jsdelay > 5000)
delay = 0 if (delay < 0)
jsdelay = 0 if (jsdelay < 0)
# Block which fulfills the request
operation = proc do
sleep delay
if path.match(/.js$/)
resp.status = 200
resp.headers["Content-Type"] = "text/javascript"
resp.content = "(function(){
var start = new Date();
while(new Date() - start < #{jsdelay}){}
})();"
end
if path.match(/.css$/)
resp.status = 200
resp.headers["Content-Type"] = "text/css"
resp.content = "body {font-size: 50px;}"
end
end
# Callback block to execute once the request is fulfilled
callback = proc do |res|
resp.send_response
end
# Let the thread pool (20 Ruby threads) handle request
EM.defer(operation, callback)
end
end
EventMachine::run {
EventMachine::start_server("0.0.0.0", 8081, Handler)
puts "Listening..."
}
上記のミニサーバーでJavaScriptファイル(サーバーとクライアントの両方)と任意のCSS遅延の任意の遅延を設定することができます。 たとえば、 http://10.0.0.50:8081/test.css?delay=500
delay=500では、CSSを転送するのに500msの遅延があります。
私は次のページを使ってテストします。
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script type='text/javascript'>
var startTime = new Date();
</script>
<link href="http://10.0.0.50:8081/test.css?delay=500" type="text/css" rel="stylesheet">
<script type="text/javascript" src="http://10.0.0.50:8081/test2.js?delay=400&jsdelay=1000"></script>
</head>
<body>
<p>
Elapsed time is:
<script type='text/javascript'>
document.write(new Date() - startTime);
</script>
</p>
</body>
</html>
最初にCSSを組み込むと、ページのレンダリングに1.5秒かかります。
JavaScriptを最初にインクルードすると、ページのレンダリングには1.4秒かかります。
Chrome、Firefox、Internet Explorerでも同様の結果が得られます。 Operaでは、順序は関係ありません。
何が起こっているように見えるのは、JavaScriptインタプリタがすべてのCSSがダウンロードされるまで開始を拒否することです。 したがって、JavaScriptスレッドにはより多くの実行時間がかかるため、JavaScriptを最初に組み込む方が効率的です。
私は何かが欠けている、CSSを配置するための推奨事項は、JavaScriptが正しくないが含まれて前に含まれていますか?
Asyncを追加したり、setTimeoutを使用してレンダリングスレッドを解放したり、JavaScriptコードをフッターに配置したり、JavaScriptローダーを使用したりすることは可能です。 ここでのポイントは、必須のJavaScriptビットとCSSビットを頭に並べることです。
JavaScriptの前にCSSを置く主な理由は2つあります。
古いブラウザ(Internet Explorer 6-7、Firefox 2など)は、スクリプトのダウンロードを開始した後のすべてのダウンロードをブロックします。 したがって、
a.js
後ろにb.css
場合、それらは順番にダウンロードされます。b.css
続いてb.css
がある場合、それらは並行してダウンロードされるので、ページはより迅速に読み込まれます。すべてのスタイルシートがダウンロードされるまで、何もレンダリングされません。これはすべてのブラウザで当てはまります。 スクリプトは異なります。ページ内のスクリプトタグの下にあるすべてのDOM要素のレンダリングをブロックします。 スクリプトをHEADに配置すると、すべてのスタイルシートとすべてのスクリプトがダウンロードされるまで、ページ全体がレンダリングからブロックされることを意味します。 スタイルシートのすべてのレンダリングをブロックするのは理にかなっています(つまり、最初に正しいスタイリングを得て、スタイルのないコンテンツFOUCのフラッシュを避けるようにしています)。スクリプトのページ全体のレンダリングをブロックするのは意味がありません。 多くの場合、スクリプトはDOM要素やDOM要素の一部には影響しません。 可能な限りページ内のスクリプトをロードするか、非同期にロードする方が良いでしょう。
Cuzillionを使ってサンプルを作成するのは楽しいことCuzillion 。 たとえば、 このページにはHEADにスクリプトがあり、ダウンロードが完了するまでページ全体が空白になります。 ただし、スクリプトをBODYブロックの最後に移動すると、ページヘッダーはレンダリングされます 。 これは、 このページでわかるように、DOM要素がSCRIPTタグの上にあるためです 。
JavaScriptを無効にする前にCSSを含めることをお勧めしますか?
それを単に勧告として扱っているわけではありません。 しかし、あなたがそれを硬くて速いルールとして扱うなら、それは無効です。
https://developer.mozilla.org/en-US/docs/Web/Reference/Events/DOMContentLoadedから
Stylesheetはスクリプトの実行をブロックするので、
<link rel="stylesheet" ...>
の後に<script>
があると、スタイルシートが読み込まれるまでページの解析が終了せず、DOMContentLoadedも起動しません。
各スクリプトが依存していることを知り、適切な完了イベントの後までスクリプトの実行を遅らせる必要があるようです。 スクリプトがDOMにのみ依存している場合は、ロードするイメージやスタイルシートに依存してondomready / domcontentloadedで再開することができます。上記の参照を正しく読み込むと、そのコードはonloadイベントまで延期されなければなりません。
私は1つの靴のサイズはすべてに合っているとは思わない、それは彼らが販売されている方法ですが、私は1つの靴のサイズがすべてに合っていないことを知っています。 私は最初に、スタイルやスクリプトを読み込む決定的な答えがあるとは思わない。 どのような順序でロードされなければならないか、後で「クリティカルパス」にならないまで延期することができるかどうかは、ケースバイケースで決定されます。
観察者は、シートがきれいになるまでユーザーとのやりとりを遅らせる方がよいとコメントしました。 そこには多くの人がいて、反対を感じる相手を悩ます。 彼らは目的を達成するためにサイトに来て、読み込みを完了するのに重要でないものを待つ間にサイトとやり取りする能力に遅れをとることは非常にイライラです。 私はあなたが間違っていると言っているわけではなく、あなたの優先順位を分け合わない別の派閥があることに気づくべきです。
この質問は、特にウェブサイトに掲載されているすべての広告に当てはまります。 サイトの作者が広告コンテンツのプレースホルダdivだけをレンダリングし、onloadイベントで広告を挿入する前にサイトが読み込まれ、インタラクティブになっていることを確認した場合は、 それでも、膨大な広告が読み込まれている間にサイトコンテンツをスクロールする機能に影響するため、広告は一度にではなくシリアルに読み込まれます。 しかしそれは一人の人間の視点に過ぎません。
- ユーザーとその価値を把握する。
- ユーザーと使用するブラウズ環境を把握する。
- 各ファイルが何をしているのか、その前提条件は何かを知る。 すべての作業をスピードとかわいらしさよりも優先させます。
- 開発時にネットワークタイムラインを示すツールを使用してください。
- ユーザーが使用する各環境でテストします。 動的に(ページを作成するときにサーバー側)、ユーザーの環境に基づいて読み込みの順序を変更する必要があります。
- 不確かな場合は、順序を変更して再度測定してください。
- ロード順序のスタイルとスクリプトの混在が最適になる可能性があります。 すべてのものではなく、すべてのものではありません。
- ファイルをロードする順序だけでなく、どこでテストしますか。 頭? 身体? 身体の後ろ? DOMレディ/ロード済み? ロードされた?
- 必要に応じて非同期オプションと遅延オプションを考慮して、ユーザーがページとやりとりする前に経験する正味の遅延を減らしてください。 彼らが助けて傷つけるかどうかを判断するためにテストしてください。
- 最適なロードオーダーを評価する際には常にトレードオフが考慮されます。 Pretty対Responsiveはちょうど1つです。
個人的には、私はそのような「フォークの知恵」をあまり重視しません。 過去に真実であったかもしれないことは、今は真実ではないかもしれません。私は、Webページの解釈とレンダリングに関連するすべての操作は、完全に非同期的であると考えています(「取り出し」と「それに作用する」は、異なるスレッドなどによって処理される2つの全く異なるものです)。いずれにしてもあなたのコントロールや懸念を完全に超えています。
私はCSSリファレンスを外部スクリプトへの参照とともに、ドキュメントの「先頭」部分に配置します。(一部のスクリプトは身体に配置されることを要求することがあり、そうであれば、それらを強要することがあります)。
それを超えて...「このブラウザよりも速く/遅いようだ」と観察すれば、興味深いが無関係の好奇心として扱い、あなたの意思決定に影響を与えないようにしてください。あまりにも多くのものがあまりにも速く変化する。(誰かがFirefoxのチームが製品の暫定版をリリースする前に、何分も賭けたいと思っている人はいますか?
2017-12-16更新
私はOPでのテストについてはわからなかった。 私は少し実験をすることに決め、いくつかの神話を崩壊させました。
同期
<script src...>
は、ダウンロードされて実行されるまで、その下のリソースのダウンロードをブロックする
これはもはや真実ではない 。 Chrome 63によって生成された滝を見てみましょう:
<head>
<script src="//alias-0.redacted.com/payload.php?type=js&delay=333&rand=1"></script>
<script src="//alias-1.redacted.com/payload.php?type=js&delay=333&rand=2"></script>
<script src="//alias-2.redacted.com/payload.php?type=js&delay=333&rand=3"></script>
</head>
<link rel=stylesheet>
はその下にあるスクリプトのダウンロードと実行をブロックしません
これは間違っています。 スタイルシートはダウンロードをブロックしませんが、スクリプトの実行をブロックします( ここでの説明はほとんどありません )。 Chrome 63で生成された掲載結果グラフをご覧ください。
<link href="//alias-0.redacted.com/payload.php?type=css&delay=666" rel="stylesheet">
<script src="//alias-1.redacted.com/payload.php?type=js&delay=333&block=1000"></script>
上記を念頭に置いて、OPの結果は次のように説明できます。
CSSファースト:
CSS Download 500ms:<------------------------------------------------>
JS Download 400ms:<-------------------------------------->
JS Execution 1000ms: <-------------------------------------------------------------------------------------------------->
DOM Ready @1500ms: ◆
JSファースト:
JS Download 400ms:<-------------------------------------->
CSS Download 500ms:<------------------------------------------------>
JS Execution 1000ms: <-------------------------------------------------------------------------------------------------->
DOM Ready @1400ms: ◆
これは非常に興味深い質問です。 私はいつも自分のCSS <link href="...">
JS <script src="...">
sの前に置いています。 だから、あなたは正しい。 それは私たちが実際の研究をするのに十分な時間です!
Node(下のコード)に私自身のテストハーネスをセットアップしました。 基本的に、私は:
- HTTPキャッシュがないことを確認して、ページが読み込まれるたびにブラウザが完全にダウンロードする必要がありました。
- 現実をシミュレートするために、私はjQueryとH5BP CSSを含んでいました(したがって、解析するスクリプト/ CSSの量は多少あります)
- 2つのページを設定します.1つはCSSの前にスクリプトを、もう1つはCSSの後にスクリプトを設定します。
-
<head>
内の外部スクリプトが実行されるまでに要した時間を記録 -
<body>
内のインラインスクリプトが実行されるまでにDOMReady
をDOMReady
。これはDOMReady
似ていDOMReady
。 - CSSやスクリプトをブラウザに500ms遅らせることができました。
- 3大ブラウザでテストを20回実行します。
結果
まず、CSSファイルが500ms遅れている:
Browser: Chrome 18 | IE 9 | Firefox 9
CSS: first last | first last | first last
=======================================================
Header Exec | | |
Average | 583ms 36ms | 559ms 42ms | 565ms 49ms
St Dev | 15ms 12ms | 9ms 7ms | 13ms 6ms
------------|--------------|--------------|------------
Body Exec | | |
Average | 584ms 521ms | 559ms 513ms | 565ms 519ms
St Dev | 15ms 9ms | 9ms 5ms | 13ms 7ms
次に、jQueryをCSSの代わりに500ms遅らせるように設定しました。
Browser: Chrome 18 | IE 9 | Firefox 9
CSS: first last | first last | first last
=======================================================
Header Exec | | |
Average | 597ms 556ms | 562ms 559ms | 564ms 564ms
St Dev | 14ms 12ms | 11ms 7ms | 8ms 8ms
------------|--------------|--------------|------------
Body Exec | | |
Average | 598ms 557ms | 563ms 560ms | 564ms 565ms
St Dev | 14ms 12ms | 10ms 7ms | 8ms 8ms
最後に、jQueryとCSSの両方を500ms遅らせるように設定しました。
Browser: Chrome 18 | IE 9 | Firefox 9
CSS: first last | first last | first last
=======================================================
Header Exec | | |
Average | 620ms 560ms | 577ms 577ms | 571ms 567ms
St Dev | 16ms 11ms | 19ms 9ms | 9ms 10ms
------------|--------------|--------------|------------
Body Exec | | |
Average | 623ms 561ms | 578ms 580ms | 571ms 568ms
St Dev | 18ms 11ms | 19ms 9ms | 9ms 10ms
結論
まず、ドキュメントの<head>
( <body>
終わりではなく)にスクリプトがあるという前提の下で動作していることに注意することが重要です。 <head>
とドキュメントの最後の部分でスクリプトにリンクする理由はさまざまですが、これはこの回答の範囲外です。 これは、 <script>
<head>
の<link>
の前に置く必要があるかどうかについて厳密になります。
現代のDESKTOPブラウザでは、CSSにリンクするとパフォーマンスが向上することはまずありません 。 スクリプトの後にCSSを置くと、CSSとスクリプトの両方が遅れてもかなりの量の利益を得ることができますが、CSSが遅れると大きな利益が得られます。 (最初の結果セットのlast
列に表示されます)。
CSSへのリンクがパフォーマンスに悪影響を及ぼすことはないが、特定の状況下では利益を得ることができるため、古いブラウザのパフォーマンスが重要でない場合は、 デスクトップブラウザでのみ外部スクリプトにリンクしてから外部スタイルシートにリンクする必要があります 。 モバイルの状況についてお読みください。
どうして?
歴史的に、ブラウザが外部リソースを指す<script>
タグを見つけたら、ブラウザはHTMLの解析、スクリプトの取得、実行、HTMLの解析を続けます。 これとは対照的に、ブラウザが外部スタイルシートの<link>
遭遇した場合、CSSファイルをフェッチしている間(並行して)HTMLを解析し続けます。
したがって、最初にスタイルシートを配置するための広範なアドバイス - 最初にダウンロードし、ダウンロードする最初のスクリプトを並行して読み込むことができます。
しかし、現代のブラウザ(上記でテストしたすべてのブラウザを含む)は投機的解析を実装しています 。ここで、ブラウザはHTMLを先読みし、スクリプトをダウンロードして実行する前にリソースのダウンロードを開始します。
投機的解析をしない古いブラウザでは、スクリプトを最初に置くと、並行してダウンロードされないため、パフォーマンスに影響します。
ブラウザのサポート
投機的解析は、(2012年1月現在、このバージョン以上を使用している世界中のデスクトップブラウザユーザーの割合とともに)最初に実装されました。
- Chrome 1(WebKit 525)(100%)
- IE 8(75%)
- Firefox 3.5(96%)
- Safari 4(99%)
- オペラ11.60(85%)
合計で、今日使用されているデスクトップブラウザの約85%が投機的なローディングをサポートしています。 CSSの前にスクリプトを置くと、 全世界のユーザーの15%がパフォーマンスに悪影響を与えます。 あなたのサイトの特定の視聴者に基づくYMMV。 (そしてその数が減少していることを覚えておいてください。)
モバイルブラウザでは、モバイルブラウザとOSのランドスケープがどれほど異質であるかによって、決定的な数字を得るのは少し難しいです。 投機的レンダリングはWebKit 525(2008年3月リリース)に実装されており、価値あるモバイルブラウザはすべてWebKitに基づいているため、「ほとんどの」モバイルブラウザでサポートする必要があります。 quirksmodeによると、iOS 2.2 / Android 1.0はWebKit 525を使用しています.Windows Phoneの外観はquirksmodeません。
しかし、私はAndroid 4デバイスでテストを実行しましたが、デスクトップの結果と似た数字を見ていましたが、Android用Chromeの新しいリモートデバッガに接続し、[Network]タブはブラウザが実際にダウンロードを待っていることを示しましたJavaScriptが完全に読み込まれるまで、つまりAndroid用のWebKitの最新バージョンでさえ、投機的解析をサポートしていないように見える。 私はそれがCPU、メモリ、および/またはモバイルデバイスに固有のネットワークの制約のためにオフになる可能性があると考えています。
コード
不器用さを許してください - これはQ&Dでした。
app.js
var express = require('express')
, app = express.createServer()
, fs = require('fs');
app.listen(90);
var file={};
fs.readdirSync('.').forEach(function(f) {
console.log(f)
file[f] = fs.readFileSync(f);
if (f != 'jquery.js' && f != 'style.css') app.get('/' + f, function(req,res) {
res.contentType(f);
res.send(file[f]);
});
});
app.get('/jquery.js', function(req,res) {
setTimeout(function() {
res.contentType('text/javascript');
res.send(file['jquery.js']);
}, 500);
});
app.get('/style.css', function(req,res) {
setTimeout(function() {
res.contentType('text/css');
res.send(file['style.css']);
}, 500);
});
var headresults={
css: [],
js: []
}, bodyresults={
css: [],
js: []
}
app.post('/result/:type/:time/:exec', function(req,res) {
headresults[req.params.type].push(parseInt(req.params.time, 10));
bodyresults[req.params.type].push(parseInt(req.params.exec, 10));
res.end();
});
app.get('/result/:type', function(req,res) {
var o = '';
headresults[req.params.type].forEach(function(i) {
o+='\n' + i;
});
o+='\n';
bodyresults[req.params.type].forEach(function(i) {
o+='\n' + i;
});
res.send(o);
});
css.html
<!DOCTYPE html>
<html>
<head>
<title>CSS first</title>
<script>var start = Date.now();</script>
<link rel="stylesheet" href="style.css">
<script src="jquery.js"></script>
<script src="test.js"></script>
</head>
<body>
<script>document.write(jsload - start);bodyexec=Date.now()</script>
</body>
</html>
js.html
<!DOCTYPE html>
<html>
<head>
<title>CSS first</title>
<script>var start = Date.now();</script>
<script src="jquery.js"></script>
<script src="test.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script>document.write(jsload - start);bodyexec=Date.now()</script>
</body>
</html>
test.js
var jsload = Date.now();
$(function() {
$.post('/result' + location.pathname.replace('.html','') + '/' + (jsload - start) + '/' + (bodyexec - start));
});
jquery.jsはjquery-1.7.1.min.js
スティーブ・スーダーズはすでに決定的な答えを出していますが...
私はサムのオリジナルテストとジョシュの繰り返しの両方に問題があるのだろうかと思う。
両方のテストは、低遅延接続で実行されているように見えますが、TCP接続の設定には些細なコストがかかります。
どのようにこれがテストの結果に影響を与えるか分かりません。私は、通常のレイテンシ接続でテスト用の滝を見たいと思いますが...
ダウンロードされた最初のファイルはhtmlページに使用される接続を取得し、ダウンロードされた2番目のファイルは新しい接続を取得します。 (早い段階で洗い流すとそのダイナミックは変化するが、ここでは行われていない)
新しいブラウザでは、2番目のTCP接続が投機的に開かれているため、接続のオーバーヘッドが減少/消滅します。古いブラウザでは、これは正しくなく、2番目の接続ではオーバーヘッドが発生します。
これがテストの結果に影響を与えるかどうかはわかりません。
新しいブラウザは、Javascriptエンジンやパーサなどを使って作業しているので、<= IE8などの古代のブラウザで発生した問題はもはや重要ではないという点で、共通コードとマークアップの問題を最適化しています。マークアップだけでなく、JavaScript変数、要素セレクタなどの使用にも関係しています。私は遠くない未来において、技術が実際にはもう問題にならないポイントに達した状況を見ることができます。
私はあなたが持っている結果をあまり重視しないでしょう、私はそれが主観的だと信じていますが、私はCSSの前にCSSを置く方が良いとあなたに説明する理由があります。
あなたのウェブサイトを読み込んでいる間に、次の2つのシナリオが表示されます:
事例1:白い画面>非表示のウェブサイト>スタイル付きウェブサイト>インタラクション>スタイルとインタラクティブなウェブサイト
ケース2:白い画面>非表示のWebサイト>インタラクション>スタイル付きウェブサイト>スタイルとインタラクティブなウェブサイト
ケース2を選んだ人は誰も想像もできません。これは、低速インターネット接続を使用している訪問者が、Javascriptを使用して(既にロードされているので)相互作用することができるスタイルのないウェブサイトに直面することを意味します。 さらに、未構築のウェブサイトを見ているのに費やす時間は、このように最大化されます。 なぜ誰もそれを望むだろうか?
また、 jQueryの状態
「CSSスタイルプロパティの値に依存するスクリプトを使用する場合は、スクリプトを参照する前に外部スタイルシートを参照するか、スタイル要素を埋め込むことが重要です。
ファイルが間違った順序(最初のJS、CSS)で読み込まれると、CSSファイルに設定されたプロパティ(divの幅や高さなど)に依存するJavascriptコードは正しく読み込まれません。 間違った読み込み順序では、正しいプロパティがJavascriptに「時には」知られているようです(これは競合状態によって引き起こされるでしょうか?)。 この効果は、使用されるブラウザによって大きくまたは小さく見えます。
私はこれがすべての場合に当てはまるとは思わない。 cssは並行してダウンロードできますが、js cantはダウンロードされるためです。 同じ場合を考えてみましょう。
単一のCSSを持つ代わりに、2つまたは3つのCSSファイルを取り出して、これらの方法で試してみてください。
1)css..css..js 2)css..js..css 3)js..css..css
私は確かにcss..css..jsは他のすべてより良い結果を与えるでしょう。