빅파이프 소개
HTTP 요청을 줄이고 첫 화면을 빠르게 로드하는 Facebook 최초의 비동기 로딩 페이지 솔루션입니다. 프론트엔드 성능 최적화를 위한 방향입니다.
BigPipe와 AJAX 비교
AJAX는 주로 XMLHttpRequest입니다. 프런트 엔드는 서버에 동적 데이터를 가져와 웹 페이지에 추가하도록 비동기적으로 요청합니다. 이러한 왕복 요청에는 시간이 걸리며 BigPipe 기술은 XMLHttpRequest 요청을 보낼 필요가 없으므로 시간이 절약됩니다. 요청 감소의 또 다른 이점은 서버 로드가 직접적으로 감소한다는 것입니다. 또 다른 차이점은 서버가 AJAX 요청 전에 대기한다는 것입니다. 페이지가 요청 후 대기 중입니다. BIGPIPE는 프런트 엔드와 백 엔드에서 병렬로 작동할 수 있어 효율성도 향상됩니다.
빅파이프의 단점
SEO 문제. Facebook의 동적 디스플레이 콘텐츠는 주로 고객 중심의 개인화된 페이지입니다. SEO에 대한 요구 사항은 높지 않습니다. 그리고 Taobao에서 BIGPIPE 기술을 사용하면 Baidu가 이러한 동적 페이지 검색을 얼마나 잘 지원하는지 잘 모르겠습니다. 실제로 ANGULARJS를 사용하여 데이터를 동적으로 바인딩할 때도 이러한 문제가 발생합니다. , SEO가 필요한 페이지에서는 BIGPIPE 기술을 사용할지 여부를 신중하게 고려해야 합니다. (GOOGLE 검색은 ANGULAR의 SEO에 최적화된 것으로 알려져 있습니다.) Baidu의 경우 -. -아래 사진을 보시면 알 수 있습니다
NODEJS 구현
bigpipe.js 페이지에서 가져온 js
var Bigpipe=function(){ this.callbacks={}; } Bigpipe.prototype.ready=function(key,callback){ if(!this.callbacks[key]){ this.callbacks[key]=[]; } this.callbacks[key].push(callback); } Bigpipe.prototype.set=function(key,data){ var callbacks=this.callbacks[key]||[]; for(var i=0;i<callbacks.length;i++){ callbacks[i].call(this,data); } }
app.js 서버 코드
var express = require('express'); var path = require('path'); var http = require('http'); var ejs = require('ejs'); var app = express(); app.set('port', process.env.PORT || 3000); app.use(express.static(path.join(__dirname, 'public'))); app.engine('.html', ejs.__express); app.set('view engine', 'html'); app.get('/index.html', function (req, res) { res.render('index', { title: "测试" }, function (err, str) { res.write(str) }) var Pagelets_list ={ pagelet1:false, pagelet2:false } var data = {is: "true"}; function is_end(Pagelets) { Pagelets_list[Pagelets]=true; for (x in Pagelets_list) { if(!Pagelets_list[x]){ return; } } res.end(); return; } function Pagelets(Pagelets) { res.write('<script>bigpipe.set("' + Pagelets + '",' + JSON.stringify(data) + ');</script>'); is_end(Pagelets) } setTimeout(function(){Pagelets("pagelet1");},1000); setTimeout(function(){Pagelets("pagelet2");},3000); }); http.createServer(app).listen(3000);
index.html 프런트엔드 코드
<!doctype html> <html class="no-js"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="description" content=""> <meta name="keywords" content=""> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <title>zchq88-bigpipe</title> <!-- Set render engine for 360 browser --> <meta name="renderer" content="webkit"> <!-- No Baidu Siteapp--> <meta http-equiv="Cache-Control" content="no-siteapp"/> <link href="//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="test1">loading......</div> <div id="test2">loading......</div> <script src="//cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script> <script src="//cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> <script src="//cdn.bootcss.com/angular.js/1.5.0-rc.0/angular.min.js"></script> <script src="/js/bigpipe.js"></script> <script> var bigpipe=new Bigpipe(); bigpipe.ready('pagelet1',function(data){ $("#test1").html("test1 ready"); }) bigpipe.ready('pagelet2',function(data){ $("#test2").html("test2 ready"); }) </script> </body> </html>
요약
사실 Bigpipe 기술의 구체적인 구현에는 서버 코드의 협력이 필요합니다. 개발 중에는 기능이 20%를 차지하고 최적화가 작업 부하의 80%를 차지한다고 생각합니다. 전체 스택에 대한 이해도 필요합니다. 그래서 지금은 프론트엔드와 백엔드를 분리하는 중간 레이어인 nodejs가 개인적으로 더 합리적이라고 생각하는 솔루션입니다. 프론트엔드와 백엔드가 nodejs의 중간 계층 분리를 완성한다면 Bigpipe 기술의 구현은 프론트엔드가 독립적으로 완성될 수 있는 최적화가 될 것입니다. 첫 번째 화면 로딩 시간을 개선합니다. 그리고 전체 웹 페이지의 로딩 시간을 개선하면 조회수를 늘리는 데 일정한 효과가 있을 것입니다.