Google在Web前端方面的经验PPT模板.pptx

上传人:san****019 文档编号:20886813 上传时间:2021-04-20 格式:PPTX 页数:69 大小:1.80MB
返回 下载 相关 举报
Google在Web前端方面的经验PPT模板.pptx_第1页
第1页 / 共69页
Google在Web前端方面的经验PPT模板.pptx_第2页
第2页 / 共69页
Google在Web前端方面的经验PPT模板.pptx_第3页
第3页 / 共69页
点击查看更多>>
资源描述
Steve Shttp:/ Faster Web SitesDisclaimer: This content does not necessarily reflect the opinions of my employer. 17% 83%iGoogle, primed cachethe importance of frontend performance9% 91%iGoogle, empty cache time spent on the frontendEmpty Cache Primed C 97% 97% 95% 81% 95% 81% 47% 0% 67% 0% 98% 94% 98% 98%en.wikipedia.org/wiki 94% 91% 97% 96% 98% 97% April 2008 14 RULES 1. MAKE FEWER HTTP REQUESTS2. USE A CDN3. ADD AN EXPIRES HEADER4. GZIP COMPONENTS5. PUT STYLESHEETS AT THE TOP6. PUT SCRIPTS AT THE BOTTOM7. AVOID CSS EXPRESSIONS8. MAKE JS AND CSS EXTERNAL9. REDUCE DNS LOOKUPS10.MINIFY JS11.AVOID REDIRECTS12.REMOVE DUPLICATE SCRIPTS13.CONFIGURE ETAGS14.MAKE AJAX CACHEABLE 25% discount code: ssouders25 Sept 2007 June 2009 Even Faster WebsitesSplit the initial payloadLoad scripts without blockingCouple asynchronous scriptsDont scatter inline scriptsSplit the dominant domainFlush the document earlyUse iframes sparinglySimplify CSS Selectors Ajax performance (Doug Crockford)Writing efficient JavaScript (Nicholas Zakas)Creating responsive web apps (Ben Galbraith, Dion Almaer)Comet (Dylan Schiemann)Beyond Gzipping (Tony Gentilcore)Optimize Images (Stoyan Stefanov, Nicole Sullivan) AOLeBayMySpaceWikipediaYah !why focus on JavaScript?YouTub scripts block blocks parallel downloads and renderinghttp:/ MSNScripts and other resources downloaded in parallel! How? Secret sauce?!var p= g.getElementsByTagName(HEAD)0;var c=g.createElement(script);c.type=text/javascript;c.onreadystatechange=n;c.onerror=c.onload=k;c.src=e;p.appendChild(c)MSN.com: parallel scripts asynchronous script loadingXHR EvalXHR InjectionScript in IframeScript DOM ElementScript Deferdocument.write Script Tag XHR Evalscript must have same domain as main pagemust refactor scriptvar xhrObj = getXHRObject();xhrObj.onreadystatechange = function() if ( xhrObj.readyState != 4 ) return; eval(xhrObj.responseText); ;xhrObj.open(GET, A.js, true);xhrObj.send(); http:/ XHR Injectionvar xhrObj = getXHRObject();xhrObj.onreadystatechange = function() if ( xhrObj.readyState != 4 ) return; var se=document.createElement(script); document.getElementsByTagName(head) 0.appendChild(se); se.text = xhrObj.responseText; ;xhrObj.open(GET, A.js, true);xhrObj.send();script must have same domain as main page http:/ Script in Iframe iframe must have same domain as main pagemust refactor script:/ access iframe from main pagewindow.frames0.createNewDiv();/ access main page from iframeparent.document.createElement(div); http:/ Script DOM Elementvar se = document.createElement(script);se.src = http:/ .appendChild(se); script and main page domains can differno need to refactor JavaScript http:/ Script Deferonly supported in IE (just landed in FF 3.1)script and main page domains can differno need to refactor JavaScript http:/ document.write Script Tagdocument.write( + );parallelization only works in IEparallel downloads for scripts, nothing elseall document.writes must be in same script block http:/ browser busy indicators browser busy indicatorsgood to show busy indicators when the user needs feedback bad when downloading in the background Ensure scripts execute in order:necessary when scripts have dependenciesIE: http:/ http:/ scripts executing in order:faster first script back is executed immediatelyhttp:/ ordered execution load scripts without blocking *Only other document.write scripts are downloaded in parallel (in the same script block). and the winner is.XHR EvalXHR InjectionScript in iframeScript DOM ElementScript DeferScript DOM ElementScript Defer Script DOM ElementScript DOM Element (FF)Script Defer (IE) XHR EvalXHR InjectionScript in iframeScript DOM Element (IE)XHR InjectionXHR EvalScript DOM Element (IE) Managed XHR InjectionManaged XHR EvalScript DOM ElementManaged XHR InjectionManaged XHR Eval Script DOM Element (FF)Script Defer (IE)Managed XHR EvalManaged XHR InjectionScript DOM Element (FF)Script Defer (IE)Managed XHR EvalManaged XHR Injectiondifferent domains same domainsno order preserve orderno orderno busy show busy show busyno busypreserve order load scripts without blockingdont let scripts block other downloadsyou can still control execution order, busy indicators, and onload eventWhat about inline scripts? synchronous JS example: menu.jsvar aExamples = couple-normal.php, Normal Script Src, couple-xhr-eval.php, XHR Eval, . managed-xhr.php, Managed XHR ;function init() EFWS.Menu.createMenu(examplesbtn, aExamples);init(); asynchronous JS example: menu.jsvar domscript = document.createElement(script);domscript.src = menu.js; document.getElementsByTagName(head)0.appendChild(domscript);var aExamples = couple-normal.php, Normal Script Src, couple-xhr-eval.php, XHR Eval, . managed-xhr.php, Managed XHR ; function init() EFWS.Menu.createMenu(examplesbtn, aExamples);init();script DOM element approach beforeafter load scripts without blocking *Only other document.write scripts are downloaded in parallel (in the same script block). !IE asynchronous scripts wrap-upwhat aboutinlined code that depends on the script? what aboutinlined code that depends on the script? baseline coupling results (not good) * Scripts download in parallel regardless of the Defer attribute.need a way to load scripts asynchronously AND preserve order coupling techniqueshardcoded callbackwindow onloadtimerdegrading script tagsscript onload technique 1: hardcoded callbackvar aExamples = couple-normal.php, Normal Script Src, .;function init() EFWS.Menu.createMenu(examplesbtn, aExamples);var domscript = document.createElement(script);domscript.src = menu.js;document.getElementsByTagName(head)0.appendChild(domscript);init() is called from within menu.jsnot very flexibledoesnt work for 3rd party scripts technique 2: window onload var aExamples = couple-normal.php, Normal Script Src, .;function init() EFWS.Menu.createMenu(examplesbtn, aExamples);if ( window.addEventListener ) window.addEventListener(load, init, false);else if ( window.attachEvent ) window.attachEvent(onload, init);init() is called at window onloadmust use async technique that blocks onload:Script in Iframe does this across most browsersinit() called later than necessary technique 3: timervar domscript = document.createElement(script);domscript.src = menu.js;document.getElementsByTagName(head)0.appendChild(domscript);var aExamples = couple-normal.php, Normal Script Src, .;function init() EFWS.Menu.createMenu(examplesbtn, aExamples);function initTimer(interval) if ( undefined = typeof(EFWS) ) setTimeout(initTimer, interval); else init(); initTimer(300);load if interval too low, delay if too highslight increased maintenance EFWS John Resigs degrading script tagsvar aExamples = couple-normal.php, Normal Script Src, .;function init() EFWS.Menu.createMenu(examplesbtn, aExamples);init();at the end of menu-degrading.js:var scripts = document.getElementsByTagName(script);var cntr = scripts.length;while ( cntr ) var curScript = scriptscntr-1; if (curScript.src.indexOf(menu-degrading.js) != -1) eval( curScript.innerHTML ); break; cntr-;http:/ejohn.org/blog/degrading-script-tags/cleanerclearersafer inlined code not called if script failsno browser supports it technique 4: degrading script tagsvar aExamples = couple-normal.php, Normal Script Src,.;function init() EFWS.Menu.createMenu(examplesbtn, aExamples);var domscript = document.createElement(script);domscript.src = menu-degrading.js;if ( -1 != navigator.userAgent.indexOf(Opera) ) domscript.innerHTML = init();else domscript.text = init();document.getElementsByTagName(head)0.appendChild(domscript); elegant, flexible (cool!)not well knowndoesnt work for 3rd party scripts (unless.) technique 5: script onloadvar aExamples = couple-normal.php, Normal Script Src, .;function init() EFWS.Menu.createMenu(examplesbtn, aExamples);var domscript = document.createElement(script);domscript.src = menu.js;domscript.onloadDone = false;domscript.onload = function() if ( ! domscript.onloadDone ) init(); domscript.onloadDone = true; ;domscript.onreadystatechange = function() if ( loaded = domscript.readyState ) if ( ! domscript.onloadDone ) init(); domscript.onloadDone = true; document.getElementsByTagName(head)0.appendChild(domscript);pretty nice, medium complexity what aboutmultiple scripts that depend on each other, and inlined code that depends on the scripts?two solutions: Managed XHR DOM Element and Doc Write multiple script example: menutier.jsvar aRaceConditions = couple-normal.php, Normal.;var aWorkarounds = hardcoded-callback.php, Hardcod.;var aMultipleScripts = managed-xhr.php, Managed XH.;var aLoadScripts = loadscript.php, loadScript, .;var aSubmenus = Race Conditions, aRaceConditions, Workarounds, aWorkarounds, Multiple Scripts, aMultipleScripts, General Solution, aLoadScripts;function init() EFWS.Menu.createTieredMenu(examplesbtn, aSubmenus); technique 1: managed XHRvar aRaceConditions = couple-normal.php, Normal.;var aWorkarounds = hardcoded-callback.php, Hardcod.;var aMultipleScripts = managed-xhr.php, Managed XH.;var aLoadScripts = loadscript.php, loadScript, .;var aSubmenus = Race Conditions, aRaceConditions, .;function init() EFWS.Menu.createTieredMenu(examplesbtn, aSubmenus);EFWS.Script.loadScriptXhrInjection(menu.js, null, true);EFWS.Script.loadScriptXhrInjection(menutier.js, init, true);XHR Injection asynchronous technique does not preserve order we have to add that beforeafter EFWS.loadScriptXhrInjection/ Load an external script. / Optionally call a callback and preserve order.loadScriptXhrInjection: function(url, onload, bOrder) var iQ = EFWS.Script.queuedScripts.length; if ( bOrder ) var qScript = response: null, onload: onload, done: false ; EFWS.Script.queuedScriptsiQ = qScript; var xhrObj = EFWS.Script.getXHRObject(); xhrObj.onreadystatechange = function() if ( xhrObj.readyState = 4 ) if ( bOrder ) EFWS.Script.queuedScriptsiQ.response = xhrObj.responseText; EFWS.Script.injectScripts(); else eval(xhrObj.responseText); if ( onload ) onload(); ; xhrObj.open(GET, url, true); xhrObj.send();process queue (next slide)or. eval now, call callbacksave response to queueadd to queue (if bOrder) EFWS.injectScripts/ Process queued scripts to see if any are ready to inject.injectScripts: function() var len = EFWS.Script.queuedScripts.length; for ( var i = 0; i len; i+ ) var qScript = EFWS.Script.queuedScriptsi; if ( ! qScript.done ) if ( ! qScript.response ) / STOP! need to wait for this response break; else eval(qScript.response); if ( qScript.onload ) qScript.onload(); qScript.done = true; ready for this script, eval and call callbackbail need to wait to preserve orderif not yet injectedpreserves external script order non-blockingworks in all browserscouples with inlined codeworks with scripts across domains technique 2: DOM Element and Doc WriteFirefox rely on Safari 4 and Chrome 2 EFWS.loadScriptsloadScripts: function(aUrls, onload) / first pass: see if any of the scripts are on a different domain var nUrls = aUrls.length; var bDifferent = false; for ( var i = 0; i nUrls; i+ ) if ( EFWS.Script.differentDomain(aUrlsi) ) bDifferent = true; break; / pick the best loading function var loadFunc = EFWS.Script.loadScriptXhrInjection; if ( bDifferent ) if ( -1 != navigator.userAgent.indexOf(Firefox) | -1 != navigator.userAgent.indexOf(Opera) ) loadFunc = EFWS.Script.loadScriptDomElement; else loadFunc = EFWS.Script.loadScriptDocWrite; / second pass: load the scripts for ( var i = 0; i nUrls; i+ ) loadFunc(aUrlsi, ( i+1 = nUrls ? onload : null ), true); multiple scripts with dependenciesvar aRaceConditions = couple-normal.php, Normal.;var aWorkarounds = hardcoded-callback.php, Hardcod.;var aMultipleScripts = managed-xhr.php, Managed XH.;var aLoadScripts = loadscript.php, loadScript, .;var aSubmenus = Race Conditions, aRaceConditions, .;function init() EFWS.Menu.createTieredMenu(examplesbtn, aSubmenus);EFWS.Script.loadScripts(menu.js, menutier.js, init);scripts on same domain:order preserved, no blockingscripts on different domain:order preserved: allloads scripts in parallel: all except Saf3, Chr1load script and image in parallel: FF, Saf4, Chr2 asynchronous scripts wrap-up case study: Google Analyticsrecommended pattern:1var gaJsHost = (https: = document.location.protocol) ? https:/ssl. : http:/www.);document.write(unescape(%3Cscript src= + gaJsHost + google- type=text/javascript%3E%3C/script%3E);var pageTracker = _gat._getTracker(UA-xxxxxx-x);pageTracker._trackPageview();document.write Script Tag approach blocks other resources 1http:/ dojo.create(script, src: gaHost + google- , dojo.doc.getElementsByTagName(head)0); setTimeout(dojo.hitch(this, _checkGA), this.loadInterval);,_checkGA: function() setTimeout(dojo.hitch(this, !window_gat ? _checkGA : _gotGA), this.loadInterval);,_gotGA: function() this.tracker = _gat._getTracker(this.acct); .Script DOM Element approachtimer coupling technique (script onload better) 1http:/docs.dojocampus.org/dojox/analytics/Urchin asynchronous loading FF 2, 3.0, 3.1b2; Safari 3.2, 4; Opera 9.63, 10; Chrome 1.0, 2.0 iframes block onloadparents onload doesnt fire until iframe and all its components are downloadedworkaround for Safari and Chrome: set iframe src in JavaScriptdocument.getElementById(iframe1).src=url; scripts block iframeno surprise scripts in the parent block the iframe from loadingIEFirefoxSafari ChromeOpera scriptscriptscript stylesheets block iframe (IE, FF)surprise stylesheets in the parent block the iframe or its resources in IE & FirefoxIEFirefoxSafari ChromeOpera stylesheetstylesheetstylesheet stylesheets after iframe still block (FF)surprise even moving the stylesheet after the iframe still causes the iframes resources to be blocked in FirefoxIEFirefoxSafari ChromeOpera stylesheetstylesheetstylesheet iframes: no free connectionsiframe shares connection pool with parent (here 2 connections per server in IE 7)iframeparent flush the document earlygotchas: PHP output_buffering ob_flush() Transfer-Encoding: chunked gzip Apaches DeflateBufferSize before 2.2.8 proxies and anti-virus software browsers Safari (1K), Chrome (2K)other languages: $| or FileHandle autoflush (Perl), flush (Python), ios.flush (Ruby)htmlimageimagescripthtmlimageimagescript call PHPs flush() flushing and domain blockingyou might need to move flushed resources to a domain different from the HTML dochtmlimageimage scripthtmlimageimagescriptgoogle imageimagescriptimage204case study: Google search blocked by HTML documentdifferent domains takeawaysfocus on the frontendrun YSlow: http:/ years focus: JavaScriptspeed matters impact on revenueGoogle:Yahoo:Amazon: 1 http:/ http:/ +500 ms -20% traffic1+400 ms -5-9% full-page traffic2+100 ms -1% sales1 cost savingshardware reduced loadbandwidth reduced response size http:/ if you want better user experience more revenue reduced operating expensesthe strategy is clearEven Faster Web Sites Steve Shttp:/
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!