ブラウザーでの JavaScript のパフォーマンスは、開発者が直面する最も重要なユーザビリティの問題となっています。この問題は、JavaScript のブロック的な性質によって複雑になります。つまり、ブラウザーが JavaScript コードを実行している間は、同時に他のことを行うことができません。この記事では、JavaScript コードを適切にロードして実行し、ブラウザーでのパフォーマンスを向上させる方法について詳しく説明します。
概要
現在の JavaScript コードが埋め込まれているか、外部リンク ファイルに埋め込まれているかに関係なく、ページのダウンロードとレンダリングは停止し、スクリプトの実行が完了するまで待つ必要があります。 JavaScript の実行プロセスに時間がかかるほど、ブラウザがユーザー入力に応答するまでの待ち時間も長くなります。スクリプトのダウンロードおよび実行時にブラウザがブロックされる理由は、スクリプトによってページまたは JavaScript の名前空間が変更され、後続のページのコンテンツに影響を与える可能性があるためです。典型的な例は、ページで document.write() を使用することです。
JavaScript コードのインライン例
<html> <head> <title>Source Example</title> </head> <body> <p> <script type="text/javascript"> document.write("Today is " + (new Date()).toDateString()); </script> </p> </body> </html>
ブラウザーが <script> タグに遭遇したとき、現在の HTML ページでは、JavaScript が <p> タグにコンテンツを追加するか、他の要素を導入するか、さらには削除するかを知る方法がありません。鬼ごっこ 。したがって、ブラウザーはこの時点でページの処理を停止し、最初に JavaScript コードを実行してから、ページの解析とレンダリングを続行します。 src 属性を使用して JavaScript をロードするときにも、同じ状況が発生します。ブラウザは、まず外部リンク ファイル内のコードをダウンロードし、それからそれを解析して実行するのに時間を費やす必要があります。このプロセス中、ページのレンダリングとユーザーの操作は完全にブロックされます。 </script>
スクリプトの配置
HTML 4 仕様では、<script> タグを HTML ドキュメントの <head> または <body> に配置でき、複数回出現することが許可されています。 Web 開発者は通常、外部リンクの JavaScript を <head> にロードし、次に <link> タグを使用して外部リンクの CSS ファイルまたはその他のページ情報をロードすることに慣れています。 </script>
非効率なスクリプトの場所の例
<html> <head> <title>Source Example</title> <script type="text/javascript" src="script1.js"></script> <script type="text/javascript" src="script2.js"></script> <script type="text/javascript" src="script3.js"></script> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <p>Hello world!</p> </body> </html>
ただし、この一般的なアプローチには、重大なパフォーマンスの問題が隠れています。リスト 2 の例では、ブラウザーが <script> タグ (行 4) を解析すると、ブラウザーはその後のコンテンツの解析を停止し、最初にスクリプト ファイルをダウンロードしてその中のコードを実行します。つまり、後続のスタイルは.css スタイル ファイルと <body> タグを読み込むことができないため、ページを表示できません。したがって、JavaScript コードが完全に実行されるまで、ページは空白になります。 </script>
スクリプトはページ上の他のリソースのダウンロードをブロックするため、すべての <script> タグをできるだけ <body> タグの下部に配置することをお勧めします。ページ。 </script>
推奨されるコードの配置例
<html> <head> <title>Source Example</title> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <p>Hello world!</p> <!-- Example of efficient script positioning --> <script type="text/javascript" src="script1.js"></script> <script type="text/javascript" src="script2.js"></script> <script type="text/javascript" src="script3.js"></script> </body> </html>
このコードは、HTML ドキュメント内の <script> タグの推奨される配置を示しています。スクリプトのダウンロードによって別のスクリプトがブロックされても、ページのコンテンツのほとんどはすでにダウンロードされてユーザーに表示されているため、ページのダウンロードがそれほど遅いようには見えません。これは JavaScript を最適化するための最初のルールです。スクリプトを最後に配置します。 </script>
スクリプトを整理する
最初にダウンロードされるときに各 <script> タグがページのレンダリングをブロックするため、ページに含まれる <script> タグの数を減らすと、この状況を改善できます。これは、外部リンク スクリプトだけでなく、埋め込みスクリプトの数にも当てはまります。ブラウザが HTML ページの解析プロセス中に <script> タグに遭遇するたびに、スクリプトの実行により一定の遅延が発生するため、遅延時間を最小限に抑えると、ページの全体的なパフォーマンスが大幅に向上します。 </script>
外部リンクの JavaScript ファイルを扱う場合、この問題は少し異なります。 HTTP リクエストに関連する追加のパフォーマンス オーバーヘッドを考慮すると、1 つの 100 Kb ファイルをダウンロードする方が、5 つの 20 Kb ファイルをダウンロードするよりも高速になります。ただし、ページ上の外部スクリプトの数を減らすとパフォーマンスが向上します。
通常、大規模な Web サイトやアプリケーションは複数の JavaScript ファイルに依存しています。複数のファイルを 1 つにマージできるため、参照する必要があるのは <script> タグのみとなり、パフォーマンスの消費を削減できます。ファイルのマージは、オフライン パッケージング ツールまたは一部のリアルタイム オンライン サービスを通じて実行できます。 </script>
外部スタイル シートを参照する の後にインライン スクリプトを配置すると、スタイル シートがダウンロードされるまでページがブロックされることに注意してください。これは、インライン スクリプトが実行時に最も正確なスタイル情報を取得できるようにするために行われます。したがって、 タグの直後にインライン スクリプトを配置しないことをお勧めします。
ノンブロッキング スクリプト
JavaScript ファイル サイズを削減し、HTTP リクエストの数を制限することは、機能が豊富な Web アプリケーションや大規模な Web サイトでは常に実現できるとは限りません。 Web アプリケーションの機能が豊富であればあるほど、より多くの JavaScript コードが必要になります。また、より大きな JavaScript ファイルを 1 つダウンロードしても HTTP リクエストが 1 つしか生成されませんが、ブラウザーが長時間ロックされる可能性があります。これを回避するには、ブラウザをブロックしない方法で JavaScript ファイルをページに徐々に読み込む特定のテクニックが必要です。
无阻塞脚本的秘诀在于,在页面加载完成后才加载 JavaScript 代码。这就意味着在 window 对象的 onload 事件触发后再下载脚本。有多种方式可以实现这一效果。
延迟加载脚本
HTML 4 为 <script> 标签定义了一个扩展属性: defer 。 Defer 属性指明本元素所含的脚本不会修改 DOM,因此代码能安全地延迟执行。 defer 属性只被 IE 4 和 Firefox 3.5 更高版本的浏览器所支持,所以它不是一个理想的跨浏览器解决方案。在其他浏览器中, defer 属性会被直接忽略,因此 <script> 标签会以默认的方式处理,也就是说会造成阻塞。然而,如果您的目标浏览器支持的话,这仍然是个有用的解决方案。</script>
defer 属性使用方法示例
<script type="text/javascript" src="script1.js" defer></script>
带有 defer 属性的 <script> 标签可以放置在文档的任何位置。对应的 JavaScript 文件将在页面解析到 <script> 标签时开始下载,但不会执行,直到 DOM 加载完成,即 onload 事件触发前才会被执行。当一个带有 defer 属性的 JavaScript 文件下载时,它不会阻塞浏览器的其他进程,因此这类文件可以与其他资源文件一起并行下载。</script>
任何带有 defer 属性的 <script> 元素在 DOM 完成加载之前都不会被执行,无论内嵌或者是外链脚本都是如此。清单 5 的例子展示了 defer 属性如何影响脚本行为:</script>
defer 属性对脚本行为的影响
<html> <head> <title>Script Defer Example</title> </head> <body> <script type="text/javascript" defer> alert("defer"); </script> <script type="text/javascript"> alert("script"); </script> <script type="text/javascript"> window.onload = function(){ alert("load"); }; </script> </body> </html>
这段代码在页面处理过程中弹出三次对话框。不支持 defer 属性的浏览器的弹出顺序是:“defer”、“script”、“load”。而在支持 defer 属性的浏览器上,弹出的顺序则是:“script”、“defer”、“load”。请注意,带有 defer 属性的 <script> 元素不是跟在第二个后面执行,而是在 onload 事件被触发前被调用。</script>
如果您的目标浏览器只包括 Internet Explorer 和 Firefox 3.5,那么 defer 脚本确实有用。如果您需要支持跨领域的多种浏览器,那么还有更一致的实现方式。
HTML 5 为 <script> 标签定义了一个新的扩展属性: async 。它的作用和 defer 一样,能够异步地加载和执行脚本,不因为加载脚本而阻塞页面的加载。但是有一点需要注意,在有 async 的情况下,JavaScript 脚本一旦下载好了就会执行,所以很有可能不是按照原本的顺序来执行的。如果 JavaScript 脚本前后有依赖性,使用 async 就很有可能出现错误。</script>
动态脚本元素
文档对象模型(DOM)允许您使用 JavaScript 动态创建 HTML 的几乎全部文档内容。 <script> 元素与页面其他元素一样,可以非常容易地通过标准 DOM 函数创建:</script>
通过标准 DOM 函数创建<script>元素</script>
var script = document.createElement ("script"); script.type = "text/javascript"; script.src = "script1.js"; document.getElementsByTagName("head")[0].appendChild(script);
新的 <script> 元素加载 script1.js 源文件。此文件当元素添加到页面之后立刻开始下载。此技术的重点在于:无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程。您甚至可以将这些代码放在 <head> 部分而不会对其余部分的页面代码造成影响(除了用于下载文件的 HTTP 连接)。</script>
当文件使用动态脚本节点下载时,返回的代码通常立即执行(除了 Firefox 和 Opera,他们将等待此前的所有动态脚本节点执行完毕)。当脚本是“自运行”类型时,这一机制运行正常,但是如果脚本只包含供页面其他脚本调用调用的接口,则会带来问题。这种情况下,您需要跟踪脚本下载完成并是否准备妥善。可以使用动态 <script> 节点发出事件得到相关信息。</script>
Firefox、Opera, Chorme 和 Safari 3+会在 <script> 节点接收完成之后发出一个 onload 事件。您可以监听这一事件,以得到脚本准备好的通知:</script>
通过监听 onload 事件加载 JavaScript 脚本
var script = document.createElement ("script") script.type = "text/javascript"; //Firefox, Opera, Chrome, Safari 3+ script.onload = function(){ alert("Script loaded!"); }; script.src = "script1.js"; document.getElementsByTagName("head")[0].appendChild(script);
Internet Explorer 支持另一种实现方式,它发出一个 readystatechange 事件。 <script> 元素有一个 readyState 属性,它的值随着下载外部文件的过程而改变。 readyState 有五种取值:</script>
微软文档上说,在 <script> 元素的生命周期中, readyState 的这些取值不一定全部出现,但并没有指出哪些取值总会被用到。实践中,我们最感兴趣的是“loaded”和“complete”状态。Internet Explorer 对这两个 readyState 值所表示的最终状态并不一致,有时 <script> 元素会得到“loader”却从不出现“complete”,但另外一些情况下出现“complete”而用不到“loaded”。最安全的办法就是在 readystatechange 事件中检查这两种状态,并且当其中一种状态出现时,删除 readystatechange 事件句柄(保证事件不会被处理两次):</script>
通过检查 readyState 状态加载 JavaScript 脚本
var script = document.createElement("script") script.type = "text/javascript"; //Internet Explorer script.onreadystatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete"){ script.onreadystatechange = null; alert("Script loaded."); } }; script.src = "script1.js"; document.getElementsByTagName("head")[0].appendChild(script);
大多数情况下,您希望调用一个函数就可以实现 JavaScript 文件的动态加载。下面的函数封装了标准实现和 IE 实现所需的功能:
通过函数进行封装
function loadScript(url, callback){ var script = document.createElement ("script") script.type = "text/javascript"; if (script.readyState){ //IE script.onreadystatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete"){ script.onreadystatechange = null; callback(); } }; } else { //Others script.onload = function(){ callback(); }; } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); }
此函数接收两个参数:JavaScript 文件的 URL,和一个当 JavaScript 接收完成时触发的回调函数。属性检查用于决定监视哪种事件。最后一步,设置 src 属性,并将 <script> 元素添加至页面。此 loadScript() 函数使用方法如下:</script>
loadScript()函数使用方法
loadScript("script1.js", function(){ alert("File is loaded!"); });
您可以在页面中动态加载很多 JavaScript 文件,但要注意,浏览器不保证文件加载的顺序。所有主流浏览器之中,只有 Firefox 和 Opera 保证脚本按照您指定的顺序执行。其他浏览器将按照服务器返回它们的次序下载并运行不同的代码文件。您可以将下载操作串联在一起以保证他们的次序,如下:
通过 loadScript()函数加载多个 JavaScript 脚本
loadScript("script1.js", function(){ loadScript("script2.js", function(){ loadScript("script3.js", function(){ alert("All files are loaded!"); }); }); });
此代码等待 script1.js 可用之后才开始加载 script2.js,等 script2.js 可用之后才开始加载 script3.js。虽然此方法可行,但如果要下载和执行的文件很多,还是有些麻烦。如果多个文件的次序十分重要,更好的办法是将这些文件按照正确的次序连接成一个文件。独立文件可以一次性下载所有代码(由于这是异步进行的,使用一个大文件并没有什么损失)。
动态脚本加载是非阻塞 JavaScript 下载中最常用的模式,因为它可以跨浏览器,而且简单易用。
使用 XMLHttpRequest(XHR)对象
此技术首先创建一个 XHR 对象,然后下载 JavaScript 文件,接着用一个动态 <script> 元素将 JavaScript 代码注入页面。清单 12 是一个简单的例子:</script>
通过 XHR 对象加载 JavaScript 脚本
var xhr = new XMLHttpRequest(); xhr.open("get", "script1.js", true); xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){ var script = document.createElement ("script"); script.type = "text/javascript"; script.text = xhr.responseText; document.body.appendChild(script); } } }; xhr.send(null);
此代码向服务器发送一个获取 script1.js 文件的 GET 请求。 onreadystatechange 事件处理函数检查 readyState 是不是 4,然后检查 HTTP 状态码是不是有效(2XX 表示有效的回应,304 表示一个缓存响应)。如果收到了一个有效的响应,那么就创建一个新的 <script> 元素,将它的文本属性设置为从服务器接收到的 responseText 字符串。这样做实际上会创建一个带有内联代码的 <script> 元素。一旦新 <script> 元素被添加到文档,代码将被执行,并准备使用。</script>
这种方法的主要优点是,您可以下载不立即执行的 JavaScript 代码。由于代码返回在 <script> 标签之外(换句话说不受 <script> 标签约束),它下载后不会自动执行,这使得您可以推迟执行,直到一切都准备好了。另一个优点是,同样的代码在所有现代浏览器中都不会引发异常。</script>
此方法最主要的限制是:JavaScript 文件必须与页面放置在同一个域内,不能从 CDN 下载(CDN 指"内容投递网络(Content Delivery Network)",所以大型网页通常不采用 XHR 脚本注入技术。
总结
减少 JavaScript 对性能的影响有以下几种方法:
通过以上策略,可以在很大程度上提高那些需要使用大量 JavaScript 的 Web 网站和应用的实际性能。
原文来自:http://www.php.cn/
补充js加载函数:
function loadJs(url, callback, charset) { var head = document.getElementsByTagName("head")[0]; var script = document.createElement("script"); if ( !!charset) script.charset = "utf-8"; script.src = url; script.onload = script.onreadystatechange = function() { var f = script.readyState; if (f && f != "loaded" && f != "complete") return; script.onload = script.onreadystatechange = null; head.removeChild(script) if (callback) { callback() || callback }; }; head.appendChild(script); }
// js同步加载 function getScripts(i, linkArray, fn) { env || getEnv(); var script = document.createElement('script'); script.type = 'text/javascript'; script.src = linkArray[i]; var head = document.head || document.getElementsByTagName('head')[0]; head.appendChild(script); if (env.ie && 'onreadystatechange' in script && !('draggable' in script)){ //ie浏览器使用以下方式加载 script.onreadystatechange = function () { if (/loaded|complete/.test(script.readyState)) { script.onreadystatechange = null; if(i === linkArray.length-1) { if (fn) { fn(); } } else { getScripts(++i, linkArray, fn); } } }; }else{ script.onload = function() { if(i === linkArray.length-1) { if (fn) { fn(); } } else { getScripts(++i, linkArray, fn); } }; } }
// js存在依赖关系 依次加载 getScripts(0, [ 'http://caibaojian.com/demo/base.js', 'http://caibaojian.com/demo/reset.js'], function() { alert('callback'); });
以上就是加快JavaScript加载和执行效率的内容,更多相关内容请关注PHP中文网(www.php.cn)!

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境
