ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript パフォーマンス最適化のヒント

JavaScript パフォーマンス最適化のヒント

黄舟
黄舟オリジナル
2017-02-22 13:29:581418ブラウズ


ロードして実行

  • スクリプトの遅延

    <scripttype="text/javascript" src="file1.js"defer></script> js文件要在dom加载完成时才会被下载

  • 動的スクリプト要素

    var script= document.createElement ("script");
      script.type= "text/javascript";
      script.src= "file1.js"; document.getElementsByTagName_r("head")[0].appendChild(script)
    
      无论在何处启动下载,文件的下载和运行都不会阻塞其他页面的处理过程

  • XHR スクリプト インジェクション

    var xhr = newXMLHttpRequest();
      xhr.open("get", "file1.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)
    
      在html页面中产生内联的js代码,它下载后不会立即执行,所以可以控制它的执行状态

  • おすすめの練習方法

    <script type = "text/javascript" >
          functionloadScript(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_r("head")[0].appendChild(script);
          }
      loadScript("the-rest.js", function() {
          Application.init();
      }); </script>

データアクセス

  • 当代码流执行到一个 with 表达式时,运行期上下文的作用域链被临时改变了。一个新的可变对象将被
      创建,它包含指定对象的所有属性。此对象被插入到作用域链的前端,意味着现在函数的所有局部变量都
      被推入第二个作用域链对象中,所以访问代价更高了(参见下图)。
    
      通过将 document 对象传递给 with 表达式,一个新的可变对象容纳了 document 对象的所有属性,被插入到作用域链的前端。这使得访问 document 的属性非常快,但是访问局部变量的速度却变慢了,例如 bd 变量。正因为这个原因,最好不要使用 with 表达式。正如前面提到的,只要简单地将 document 存储在一个
      局部变量中,就可以获得性能上的提升。

    で回避

JavaScript パフォーマンス最適化のヒント

ここに画像の説明を入力してください

  • トライキャッチは避けてください

    在 JavaScript 中不只是 with 表达式人为地改变运行期上下文的作用域链,try-catch 表达式的 catch 子句
      具有相同效果。当 try 块发生错误时,程序流程自动转入 catch 块,并将异常对象推入作用域链前端的一个
      可变对象中。在 catch 块中,函数的所有局部变量现在被放在第二个作用域链对象中。例如: try {
       methodThatMightCauseAnError();
      } catch (ex){
       alert(ex.message); //scope chain is augmented here }

  • 深すぎるスコープチェーンやプロトタイプチェーンに何度もアクセスする必要があり、アクセスした内容が変わらない場合は、アクセスに必要な値をローカル変数

    在 JavaScript 中,数据存储位置可以对代码整体性能产生重要影响。有四种数据访问类型:直接量,变量,数组项,对象成员。它们有不同的性能考虑。
    
      直接量和局部变量访问速度非常快,数组项和对象成员需要更长时间。
    
      局部变量比域外变量快,因为它位于作用域链的第一个对象中。变量在作用域链中的位置越深,访问所需的时间就越长。全局变量总是最慢的,因为它们总是位于作用域链的最后一环。

    に代入する必要があります。

Domプログラミング

これはパフォーマンスにとって何を意味しますか?簡単に言うと、2 つの独立した部分を機能インターフェイスで接続すると、パフォーマンスが低下します。非常に鮮やかな比喩は、DOM を島、JavaScript (ECMAScript) を別の島、その 2 つを有料橋で結ぶと考えることです

(John Hrvatin、Microsoft、MIX09、http://www.php.cn/ を参照)。 ECMAScript が DOM にアクセスする必要があるたびに、橋を渡って「橋の通行料」を支払う必要があります。 DOM を操作すればするほど、コストは高くなります。一般的なアドバイスは、できる限り橋を渡らず、ECMAScript アイランドにとどまるようにすることです。

  • DOM アクセスを最小限に抑え、可能な限り JavaScript 側で実行します。

  • ローカル変数を使用して、繰り返しアクセスされる場所に DOM 参照を保存します

  • HTML コレクションは「存在」を示し、常に基礎となるドキュメントを再クエリするため、HTML コレクションは慎重に扱ってください。コレクションの長さプロパティを変数にキャッシュし、反復中にこの変数を使用します。このコレクションを頻繁に操作する場合は、コレクションを配列にコピーできます

  • 可能であれば、querySelectorAll() や firstElementChild、querySelector() やその他の CSS セレクターなどのより高速な API を使用してください

  • 再描画とリフローに注意してください。スタイルをバッチで変更し、DOM ツリーをオフラインで操作し、レイアウト情報をキャッシュしてアクセスを減らします。

  • アニメーションでは絶対座標を使用し、ドラッグ アンド ドロップ プロキシを使用します。

  • イベント ホスティング技術を使用して、イベント ハンドラーの数を最小限に抑えます。

アルゴリズムとプロセス制御

他のプログラミング言語と同様に、コードの記述方法と選択されたアルゴリズムは JavaScript の実行時間に影響します。他のプログラミング言語とは異なり、JavaScript では利用できるリソースが限られているため、最適化手法がより重要です。

  • for、while、do-while ループのパフォーマンス特性は似ており、どちらが他より速いか遅いということはありません。プロパティが不明なオブジェクトを反復処理する場合を除き、for-in ループを使用しないでください。

  • 判定条件が多い場合は、if-elseやswitchよりもテーブル参照方式の方が高速です。

  • スタック オーバーフロー エラーが発生した場合は、メソッドを反復アルゴリズムに変更するか、表作成を使用することで、作業の重複を回避できます。

  • 当遇到递归时,如果有一些重复性的返回,就应该用缓存cache存储重复的返回

字符串与正则表达式

  • 字符串

    当连接数量巨大或尺寸巨大的字符串时,数组联合是 IE7 和它的早期版本上唯一具有合理性能的方法。如果你不关心 IE7 和它的早期版本,数组联合是连接字符串最慢的方法之一。使用简单的+和+=取而代之,可避免(产生)不必要的中间字符串。

  • 正则表达式

    正则表达式并不总是完成工作的最佳工具,尤其当你只是搜索一个文本字符串时。

响应接口

  • UI 线程

    大多数浏览器有一个单独的处理进程,它由两个任务所
      共享:JavaScript 任务和用户界面更新任务。每个时刻只有其中的一个操作得以执行,也就是说当 JavaScript
      代码运行时用户界面不能对输入产生反应,反之亦然。或者说,当 JavaScript 运行时,用户界面就被“锁定”
      了。管理好 JavaScript 运行时间对网页应用的性能很重要
    
      JavaScript 和 UI 更新共享的进程通常被称作浏览器 UI 线程(虽然对所有浏览器来说“线程”一词不一定准确)。此 UI 线程围绕着一个简单的队列系统工作,任务被保存到队列中直至进程空闲。一旦空闲,队列中的下一个任务将被检索和运行。这些任务不是运行 JavaScript 代码,就是执行 UI更新,包括重绘和重排版(在第三章讨论过)。此进程中最令人感兴趣的部分是每次输入均导致一个或多个任务被加入队列。

  • JS最佳运行时间是100ms以内

    如果该接口在 100毫秒内响应用户输入,用户认为自己是“直接操作用户界面中的对象。”超过 100毫秒意味着用户认为自己与接口断开了。由于 UI 在JavaScript 运行时无法更新,如果运行时间长于 100 毫秒,用户就不能感受到对接口的控制

  • 定时器可用于安排代码推迟执行,它使得你可以将长运行脚本分解成一系列较小的任务。

Ajax 异步JavaScript 和 XML

Ajax 是高性能 JavaScript 的基石。它可以通过延迟下载大量资源使页面加载更快。它通过在客户端和服务器之间异步传送数据,避免页面集体加载。它还用于在一次 HTTP 请求中获取整个页面的资源。通过选择正确的传输技术和最有效的数据格式,你可以显著改善用户与网站之间的互动。

  • 高性能 Ajax 包括:知道你项目的具体需求,选择正确的数据格式和与之相配的传输技术。

    作为数据格式,纯文本和 HTML 是高度限制的,但它们可节省客户端的 CPU 周期。XML 被广泛应用普遍支持,但它非常冗长且解析缓慢。JSON 是轻量级的,解析迅速(作为本地代码而不是字符串),交互性与 XML 相当。字符分隔的自定义格式非常轻量,在大量数据集解析时速度最快,但需要编写额外的程序在服务器端构造格式,并在客户端解析。

  • 减少请求数量,可通过 JavaScript 和 CSS 文件打包,或者使用 MXHR。

  • 缩短页面的加载时间,在页面其它内容加载之后,使用 Ajax 获取少量重要文件。

编程实践

  • 给 setTimeout()和 setInterval()传递函数参数而不是字符串参数

  • 创建新对象和数组时使用对象直接量和数组直接量。它们比非直接量形式创建和初始化更快

  • 避免重复进行相同工作。当需要检测浏览器时,使用延迟加载或条件预加载

  • 原生方法总是比 JavaScript 写的东西要快。尽量使用原生方法

创建部署

开发和部署过程对基于JavaScript的应用程序可以产生巨大影响,最重要的几个步骤如下:

  • 合并 JavaScript 文件,减少 HTTP 请求的数量

  • 压缩JavaScript 文件

  • 以压缩形式提供 JavaScript 文件(gzip 编码)

  • 通过设置 HTTP 响应报文头使 JavaScript 文件可缓存,通过向文件名附加时间戳解决缓存问题

  • 使用内容传递网络(CDN)提供 JavaScript 文件,CDN不仅可以提高性能,它还可以为你管理压缩和缓存

 

以上就是JavaScript 性能优化技巧的内容,更多相关内容请关注PHP中文网(www.php.cn)!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。