Rumah  >  Artikel  >  Operasi dan penyelenggaraan  >  Cara menggunakan Prestasi untuk memantau prestasi bahagian hadapan

Cara menggunakan Prestasi untuk memantau prestasi bahagian hadapan

WBOY
WBOYke hadapan
2023-06-03 09:02:321048semak imbas

Prestasi.kini

Prestasi ialah API yang amat diperlukan untuk pemantauan prestasi bahagian hadapan Sebaiknya gunakannya selepas halaman dimuatkan sepenuhnya, kerana banyak nilai mesti dimuatkan sepenuhnya sebelum halaman Anda boleh mendapatkannya kemudian. Cara paling mudah ialah membaca pelbagai data dalam acara window.onload.

Kaedah performance.now() mengembalikan DOMHighResTimeStamp tepat kepada milisaat.

Menurut MDN:

Cap masa ini sebenarnya tidak begitu tepat. Untuk mengurangkan ancaman keselamatan seperti Spectre, pelbagai penyemak imbas membulatkan nilai jenis ini kepada tahap yang berbeza-beza. (Firefox membundarkan kepada ketepatan 2 milisaat bermula dengan Firefox 59) Sesetengah penyemak imbas mungkin juga sedikit rawak nilai ini. Ketepatan nilai ini mungkin bertambah baik lagi dalam versi masa hadapan, pembangun penyemak imbas masih menyiasat serangan masa ini dan cara untuk mengurangkannya dengan lebih baik.

Oleh kerana, untuk mengira masa pelaksanaan fungsi, hanya bandingkan nilai performance.now() dua kali sebelum dan selepas fungsi itu dilaksanakan, seperti yang ditunjukkan di bawah:

const t0 = performance.now(); for (let i = 0; i <p><img src="https://img.php.cn/upload/article/000/887/227/168575415495196.png" alt="Cara menggunakan Prestasi untuk memantau prestasi bahagian hadapan"></p><p>Di sini anda boleh melihat bahawa hasil yang dibentangkan oleh Firefox dan Chrome adalah berbeza sama sekali. Ini kerana bermula dengan versi 60, Firefox mengurangkan ketepatan API prestasi kepada 2ms. </p><p>API prestasi bukan sahaja mempunyai fungsi mengembalikan cap masa, tetapi juga mempunyai banyak kaedah praktikal Anda boleh pergi ke MDN untuk bertanya dokumen berkaitan seperti yang diperlukan. </p><p>Walau bagaimanapun, untuk kes penggunaan kami, kami hanya mahu mengira prestasi fungsi tunggal, jadi cap masa sudah memadai. </p><p><strong>Adakah performance.now() sama dengan Date.now?</strong></p><p>Anda mungkin berfikir, hey, saya boleh melakukannya dengan Date.now juga?</p> <p>Ya, anda boleh, tetapi terdapat kelemahan. </p><p>Date.now mengembalikan masa berlalu dalam milisaat sejak zaman Unix (1970-01-01T00:00:00Z) dan bergantung pada jam sistem. Ini bukan sahaja bermakna ia tidak cukup tepat, tetapi ia tidak selalu meningkat. Di sini, jurutera WebKit Tony Gentilcore menerangkan: </p><p>Menggunakan masa sistem sebagai tarikh mungkin bukan pilihan terbaik, dan juga tidak sesuai untuk pemantauan pengguna. Kebanyakan sistem menjalankan daemon yang menyegerakkan masa secara berkala. Biasanya jam dilaraskan dengan beberapa milisaat setiap 15 hingga 20 minit. Pada kadar itu, kira-kira 1% daripada selang 10 saat akan menjadi tidak tepat. </p><p><strong>Performance.mark and Performance.measure</strong></p><p>Selain fungsi Performance.now, terdapat juga fungsi yang membolehkan kita mengukur masa bahagian yang berlainan dalam kod dan gunakannya sebagai metrik tersuai dalam alat ujian prestasi seperti Webpagetest. </p><p><strong>Performance.mark</strong></p><p>Mari kita lihat dulu definisi kaedah tanda dalam MDN:</p>
  • Kaedah mark() mencipta cap masa dalam penimbal kemasukan prestasi penyemak imbas dengan nama yang diberikan.

Petikan ini boleh dipecahkan kepada tiga kata kunci. Cap masa pertama, cap masa di sini merujuk kepada cap masa ketepatan tinggi (seperseribu milisaat), diikuti dengan penimbal kemasukan prestasi.

Penimbal masukan prestasi merujuk kepada kawasan tempat objek contoh prestasi disimpan dan nilai awalnya kosong.

Yang terakhir ialah nama yang diberikan, yang bermaksud setiap cap masa yang dijana mempunyai nama yang sepadan.

Jadi ayat ini boleh difahami sebagai menghasilkan cap masa ketepatan tinggi berdasarkan nama dalam penimbal masukan prestasi penyemak imbas. Inilah yang ramai orang panggil **"pengurusan"**.

Sama seperti Performance.now, fungsi ini mempunyai skor ketepatan sehingga 5&mikro;s. Entri prestasi yang ditandakan oleh

performance.mark('name');

akan mempunyai nilai atribut berikut:

  • entryType - ditetapkan kepada "tanda".

  • nama - Tetapkan kepada "nama" yang diberikan apabila tanda dicipta

  • masa mula - Tetapkan kepada cap waktu apabila kaedah mark() dipanggil.

  • tempoh - ditetapkan kepada "0" (penanda tiada tempoh).

Prestasi.ukuran

Mari kita lihat juga definisi ukuran pada MDN:

Definisi ini agak serupa dengan definisi markah di atas. Perbezaan inti terletak pada ayat antara dua markah yang ditentukan. Jadi ukuran menentukan cap masa antara dua titik tanda. Jika tanda boleh difahami sebagai "titik", ukuran boleh difahami sebagai "sambungan".

performance.measure(name, startMark, endMark);

Kira masa antara dua markah, buat DOMHighResTimeStamp dan simpan dalam data cache sumber, yang boleh diperoleh melalui antara muka yang berkaitan seperti performance.getEntries().

  • entryType ialah ukuran rentetan

  • nama ialah nilai yang ditetapkan semasa mencipta

  • masa mula ialah Masa apabila ukuran dipanggil

  • tempoh ialah tempoh antara dua markah

Pengukuran bermula dari navigasi

performance.measure('measure name');

Navigasi mula menandai

performance.measure('measure name', undefined, 'mark-2');

Dari tag ke tag

performance.measure('measure name', 'mark-1', 'mark-2');

Data Prestasi Sumber

Dapatkan data daripada penimbal kemasukan prestasi

在上面的函数中,总是提到结果存储在performance entry buffer,但是如何访问其中的内容呢?

performance API有3个函数可以用来访问该数据:

performance.getEntries()

获取一组当前页面已经加载的资源PerformanceEntry对象。接收一个可选的参数options进行过滤,options支持的属性有name,entryType,initiatorType。

let entries = window.performance.getEntries();

performance.getEntriesByName

根据参数name,type获取一组当前页面已经加载的资源数据。资源数据中的"name"字段对应于"name"的取值,资源数据中的"entryType"字段对应于"type"的取值。

let entries = window.performance.getEntriesByName(name, type);

performance.getEntriesByType

根据参数type获取一组当前页面已经加载的资源数据。type取值对应到资源数据中的entryType字段。

var entries = window.performance.getEntriesByType(type);

结合事例:

performance.mark('mark-1'); // some code performance.mark('mark-2') performance.measure('test', 'mark-1', 'mark-2') console.log(performance.getEntriesByName('test')[0].duration);

Console.time

这个  API确实易于使用。当需要统计一段代码的执行时间时,可以使用console.time方法与console.timeEnd方法,其中console.time方法用于标记开始时间,console.timeEnd方法用于标记结束时间,并且将结束时间与开始时间之间经过的毫秒数在控制台中输出。这两个方法的使用方法如下所示。

console.time('test'); for (let i = 0; i <p><img src="https://img.php.cn/upload/article/000/887/227/168575415499236.png" alt="Cara menggunakan Prestasi untuk memantau prestasi bahagian hadapan"></p><p>输出的结果与Performance API非常相似。</p><p>console.time的优点是易于使用,因为它不需要手动计算两个时间戳之间的差。</p><p><strong>减少时间精度</strong></p><p>如果在不同的浏览器中使用上面提到的 api 测量函数,你可能会注意到结果是不同的。</p><p>这是由于浏览器试图保护用户免受时序攻击(timing attack)和指纹采集(Fingerprinting  ),如果时间戳过于准确,黑客可以使用它们来识别用户。</p><p>例如,Firefox等浏览器试图通过将精度降低到2ms(版本60)来防止这种情况发生。</p><p><strong>注意事项</strong></p><p>现在,我们已经知道了要测量JavaScript函数的速度所需方法。但是,最好还要避免一些陷阱:</p><p><strong>分而治之</strong></p><p>开发过程中,我们可能会我发现有些模块执行速度很慢,但是我们不知道具体问题出在哪里。一种解决方案是使用前面提到的这些函数来测量代码,而不是随便猜测哪一部分比较慢。</p><p>为了跟踪它,你需要在执行速度较慢的代码块周围放置console.time语句。然后测量它们不同部分的表现。如果一个比另一个慢,那就继续往下走,直到发现问题所在。</p><p><strong>注意输入值</strong></p><p>在实际应用中,给定函数的输入值可能会发生很大变化。我们无法通过仅针对任意随机值测量函数的速度来获得任何实用的有价值数据。</p><p><strong>确保使用相同的输入值运行代码。</strong></p><p><strong>多次运行该函数</strong></p><p>如果你拥有一个函数,它的功能在于遍历一个数组,在对数组的每个值执行一些计算后,返回一个包含计算结果的新数组。你想知道是forEach循环还是简单的for循环性能更好。</p><pre class="brush:php;toolbar:false">function testForEach(x) {   console.time('test-forEach');   const res = [];   x.forEach((value, index) => {     res.push(value / 1.2 * 0.1);   });    console.timeEnd('test-forEach')   return res; }  function testFor(x) {   console.time('test-for');   const res = [];   for (let i = 0; i <p>然后这样测试它们:</p><pre class="brush:php;toolbar:false">const x = new Array(100000).fill(Math.random()); testForEach(x); testFor(x);

如果在 Firefox 中运行上述函数,结果:

Cara menggunakan Prestasi untuk memantau prestasi bahagian hadapan

看起来forEach慢多了,对吧?

那如果是相同的输入,运行两次呢:

testForEach(x); testForEach(x); testFor(x); testFor(x);

Cara menggunakan Prestasi untuk memantau prestasi bahagian hadapan

在第二次调用forEach的情况下,其执行效果应该是和使用for循环相同。考虑到初始值较慢,在一些性能要求极高的项目,可能就不适合使用forEach。

在多个浏览器中测试

如果我们在Chrome中运行上述代码,结果又会不一样:

Cara menggunakan Prestasi untuk memantau prestasi bahagian hadapan

这是因为Chrome和Firefox具有不同的JavaScript引擎,它们具有不同类型的性能优化。

在本例中,Firefox 在对相同输入的forEach进行优化方面做得更好。

for在两个引擎上的性能都更好,因此在一些性能要求极高的项目就需要使用for循环。

这是为什么要在多个引擎中进行测量的一个很好的例子。只使用Chrome作为度量标准可能导致你得出结论,forEach与for相比并不那么糟糕。

限制的 CPU

在本地测试时得到的结果不代表用户在浏览器中的使用情况,因为我们开发者使用的电脑通常比大多数用户的电脑配置更好。

Pelayar mempunyai ciri yang mengehadkan prestasi CPU Kami boleh menetapkannya agar lebih sesuai dengan keadaan sebenar.

Atas ialah kandungan terperinci Cara menggunakan Prestasi untuk memantau prestasi bahagian hadapan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam