Rumah >hujung hadapan web >tutorial js >Node.js melaksanakan BigPipe secara terperinci_node.js
BigPipe ialah teknologi yang dibangunkan oleh Facebook untuk mengoptimumkan kelajuan memuatkan halaman web. Hampir tiada artikel yang dilaksanakan menggunakan node.js di Internet Malah, pelaksanaan BigPipe dalam bahasa lain, bukan sahaja node.js, jarang berlaku di Internet. Lama selepas teknologi ini muncul, saya fikir selepas keseluruhan bingkai halaman web dihantar terlebih dahulu, satu lagi atau beberapa permintaan ajax digunakan untuk meminta modul dalam halaman. Sehingga tidak lama dahulu, saya mengetahui bahawa konsep teras BigPipe adalah menggunakan hanya satu permintaan HTTP, tetapi elemen halaman dihantar tidak teratur.
Ia akan menjadi lebih mudah apabila anda memahami konsep teras ini Terima kasih kepada ciri tak segerak node.js, adalah mudah untuk melaksanakan BigPipe dengan node.js. Artikel ini akan menggunakan contoh langkah demi langkah untuk menerangkan asal usul teknologi BigPipe dan pelaksanaan mudah berdasarkan node.js.
Saya akan menggunakan ekspres untuk menunjukkan untuk memudahkan, kami memilih jed sebagai enjin templat, dan kami tidak menggunakan ciri sub-templat (separa) enjin, tetapi menggunakan HTML selepas sub-templat dipaparkan sebagai. data templat induk.
Mula-mula buat folder nodejs-bigpipe dan tulis fail package.json seperti berikut:
Jalankan npm install untuk memasang ketiga-tiga perpustakaan ini digunakan untuk memudahkan panggilan jed.
Mari cuba yang paling mudah dahulu, dua fail:
app.js:
apl var = ekspres()
app.engine('jed', kontra.jed)
app.set('views', path.join(__dirname, 'views'))
app.set('enjin lihat', 'jed')
app.use(fungsi (req, res) {
res.render('layout', {
s1: "Helo, saya bahagian pertama."
, s2: "Helo, saya bahagian kedua."
})
})
app.listen(3000)
pandangan/layout.jed
kepala
tajuk Hello, World!
gaya
Bahagian {
jidar: 20px auto;
Sempadan: 1px bertitik kelabu;
lebar: 80%;
Tinggi: 150px;
}
bahagian#s1!=s1
bahagian#s2!=s2
Kesannya adalah seperti berikut:
Seterusnya kami meletakkan dua templat bahagian ke dalam dua fail templat yang berbeza:
pandangan/s1.jed:
pandangan/s2.jed:
Tambahkan beberapa gaya pada gaya susun atur.jed
Tukar bahagian app.use() app.js kepada:
Sebelum kami berkata "gunakan HTML selepas sub-templat dipaparkan sebagai data templat induk", itulah maksudnya kedua-dua kaedah temp.s1 dan temp.s2 akan menghasilkan dua fail, s1.jade dan kod HTML s2.jade, dan kemudian gunakan dua keping kod ini sebagai nilai dua pembolehubah s1 dan s2 dalam layout.jade.
Halaman sekarang kelihatan seperti ini:
Secara umumnya, data kedua-dua bahagian diperoleh secara berasingan - sama ada dengan menanyakan pangkalan data atau permintaan RESTful, kami menggunakan dua fungsi untuk mensimulasikan operasi tak segerak tersebut.
Dengan cara ini, logik dalam app.use() akan menjadi lebih rumit Cara paling mudah untuk menanganinya ialah:
Ini juga boleh mendapatkan hasil yang kita inginkan, tetapi dalam kes ini, ia akan mengambil masa 8 saat penuh untuk kembali.
Malah, logik pelaksanaan menunjukkan bahawa getData.d2 dipanggil hanya selepas hasil getData.d1 dikembalikan, dan tiada pergantungan sedemikian antara kedua-duanya. Kita boleh menggunakan perpustakaan seperti async yang mengendalikan panggilan tak segerak JavaScript untuk menyelesaikan masalah ini, tetapi mari tulis dengan tangan di sini:
Ini hanya akan mengambil masa 5 saat.
Sebelum pengoptimuman seterusnya, kami menambah perpustakaan jquery dan meletakkan gaya css ke dalam fail luaran, kami juga menambah fail runtime.js yang diperlukan untuk menggunakan templat jed pada bahagian penyemak imbas yang akan kami gunakan kemudian. . Jalankan dalam direktori yang mengandungi app.js:
Dan keluarkan kod dalam teg gaya dalam layout.jade dan masukkan ke dalam statik/style.css, dan kemudian tukar teg kepala kepada:
Dalam app.js, kami mensimulasikan kelajuan muat turun kedua-duanya kepada dua saat dan menambah:
sebelum app.use(function (req, res) {
Halaman kami kini dimuatkan dalam masa sekitar 7 saat disebabkan oleh fail statik luaran.
Jika kami memulangkan bahagian kepala sebaik sahaja kami menerima permintaan HTTP, dan kemudian kedua-dua bahagian menunggu sehingga operasi tak segerak selesai sebelum kembali, ini menggunakan mekanisme pengekodan pemindahan chunked HTTP. Dalam node.js, selagi anda menggunakan kaedah res.write(), pengepala Pemindahan-Pengekodan: chunked akan ditambahkan secara automatik. Dengan cara ini, semasa penyemak imbas memuatkan fail statik, pelayan nod sedang menunggu keputusan panggilan tak segerak Mari kita padamkan kedua-dua baris ini dalam bahagian dalam susun atur. jed:
Jadi kita tidak perlu memberikan objek { s1: …, s2: … } dalam res.render(), dan kerana res.render() akan memanggil res.end() secara lalai, kita perlu secara manual set render selepas selesai Fungsi panggil balik menggunakan kaedah res.write() di dalamnya. Kandungan layout.jade tidak perlu berada dalam fungsi panggil balik writeResult() Kami boleh kembali apabila menerima permintaan ini. Harap maklum bahawa kami menambahkan pengepala jenis kandungan:
Kelajuan pemuatan akhir kini kembali kepada sekitar 5 saat. Dalam operasi sebenar, penyemak imbas mula-mula menerima bahagian kepala kod, dan kemudian memuatkan tiga fail statik, yang mengambil masa dua saat, Kemudian pada saat ketiga, bahagian Separa 1 muncul, dan bahagian Separa 2 muncul pada saat ke-5, dan halaman web dimuatkan. Saya tidak akan mengambil tangkapan skrin, kesan tangkapan skrin adalah sama seperti tangkapan skrin 5 saat sebelumnya.
Tetapi sila ambil perhatian bahawa kesan ini boleh dicapai kerana getData.d1 lebih pantas daripada getData.d2 Dalam erti kata lain, sekatan dalam halaman web yang dikembalikan dahulu bergantung pada hasil panggilan tak segerak antara muka di belakang yang kembali dahulu. Jika kita meletakkan getData. Jika d1 ditukar kepada 8 saat untuk kembali, Separa 2 akan dikembalikan dahulu, dan susunan s1 dan s2 akan diterbalikkan.
Soalan ini akhirnya membawa kita ke BigPipe ialah teknologi yang boleh memisahkan susunan paparan setiap bahagian halaman web daripada pesanan penghantaran data.
Idea asasnya ialah memindahkan bingkai umum keseluruhan halaman web dahulu, dan bahagian yang perlu dipindahkan kemudian diwakili oleh div kosong (atau tag lain):
Kemudian tulis data yang dikembalikan menggunakan JavaScript
s2 dikendalikan dengan cara yang sama. Pada masa ini, anda akan melihat bahawa dalam saat kedua meminta halaman web, dua kotak bertitik kosong muncul, pada saat kelima, bahagian Separa 2 muncul, dalam saat kelapan, bahagian Separa 1 muncul dan halaman web permintaan selesai.
Pada ketika ini, kami telah melengkapkan halaman web yang dilaksanakan dengan teknologi BigPipe yang paling mudah.
Perlu diambil perhatian bahawa serpihan halaman web yang akan ditulis mempunyai tag skrip Contohnya, tukar s1.jade kepada:
Kemudian muat semula halaman web dan anda akan mendapati bahawa amaran tidak dilaksanakan dan akan terdapat ralat pada halaman web. Semak kod sumber dan ketahui bahawa ralat itu disebabkan oleh yang muncul dalam rentetan di dalam
还要在 susun atur.jed 把两个 bahagian 添加回来:
本文的代码在
https://github.com/undozen/bigpipe-on-node ,我把每一步做成一个 commit 了,希望佡帐望佡menggodam 一下看看。因为后面几步涉及到加载顺序了,确实要自己打开浏览器才能体验到水王了(其实应该可以用 gif 动画实现,但是我懒得做了)。
关于 BigPipe 的实践还有很大的优化空间,比如说,要 pipe 的内容最好设置一个触发的是受用的数据很快返回,就不需要用 BigPipe,直接生成网页送出即可,可以等到数据请求超过一定时间才用 BigPipe。使用 BigPipe 相比 ajax 既节省了晨节省了浏览 node.求数,又节省了 node.js 服务器到数据源的请求数。不过具体的优化和实践方法,等到雪球网用上 BigPipe 以后再分享吧。