690 likes | 810 Vues
Join John Hrvatin, Lead Program Manager at Microsoft, as he uncovers essential strategies to optimize website performance. This session focuses on actionable methods to accelerate your site today, covering principles for improving CSS and JavaScript efficiency, optimizing HTTP requests, and maintaining code simplicity. Key takeaways include minimizing styles, simplifying selectors, and reducing unnecessary re-layouts. Discover best practices that enhance user experience while ensuring compatibility across all browsers, all without relying on magic solutions. ###
E N D
Building High-Performance Web Applications and Sites John Hrvatin Lead Program Manager Internet Explorer johnhrv@microsoft.com
Objectives and Takeaways • Session objective(s) • How to make your site faster today • Principles to remember when building sites • Key takeaways • Suggestions help in ALL browsers • No magic solutions • Consider maintainability
Acknowledgements "If I have seen further it is only by standing on the shoulders of giants." - Isaac Newton
Topics • CSS performance • Optimizing symbol resolution • Javascript coding inefficiencies • HTTP performance
Topics • CSS performance • Optimizing symbol resolution • Javascript coding inefficiencies • HTTP performance
CSS PerformanceMinimize included styles • Unused styles increase download size • Browser must parse and match all selectors • Failures are expensive!
CSS PerformanceSimplify selectors • Complex element selectors are slow • When possible • Use class – or ID-based selectors • Make element selectors as simple as possible • Use child instead of descendent selectors • Do not mix RTL and LTR styles • Minimizing included styles makes this easier Better in IE8
CSS PerformanceSimplify selectors • table tr td ulli {color: green;} • li#pass {color: green;} • ulli {color: purple;} • ul > li {color: purple;}
CSS PerformanceDon't use expressions • Slow – evaluated frequently • Not supported in IE8 standards mode!
CSS PerformanceMinimize page re-layouts • Poor user experience as content moves • Browser performs unnecessary work
demo Minimize Page Re-layouts
CSS PerformanceTakeaways • Minimize included styles • Use less-complicated selectors • Don’t use expressions • Minimize page re-layouts • Simplify!
Topics • CSS Performance • Optimizing Symbol Resolution • JavaScript Coding Inefficiencies • HTTP Performance
Optimizing Symbol ResolutionLookup chains • Scope • var name • Prototype • obj.name Cost DOM Global Prototype … Intermediate … Instance Local
Optimizing Symbol ResolutionLocal variables • function WorkOnLocalVariable(){ • localVariable = foo(); • return ( localVariable + 1 ); • } localVariable localVariable
Optimizing Symbol ResolutionLocal variables: Declare them as local • function WorkOnLocalVariable2(){ • var localVariable = foo(); • return ( localVariable + 1 ); • } varlocalVariable localVariable
Optimizing Symbol ResolutionImplicit lookups • function BuildUI(){ • var elm = document.getElementById('ui'); • // Clear existing contentselm.innerHTML = ''; • // Generate UI • elm.innerHTML += BuildTitle();elm.innerHTML += BuildBody();elm.innerHTML += BuildFooter(); • } 7 innerHTML References = += += +=
Optimizing Symbol ResolutionImplicit lookups: Batch changes • function BuildUI2(){ • var elm = document.getElementById('ui'); • // Generate UI • var contents = BuildTitle() • + BuildBody() • + BuildFooter(); • // Replace existing contents with UIelm.innerHTML = contents; • } 1 innerHTML Reference =
Optimizing Symbol ResolutionMultiple DOM lookups • function CalculateSum(){ • // Retrieve Values • var lSide = document.body.all.lSide.value;var rSide = document.body.all.rSide.value; • // Generate Resultdocument.body.all.result.value = lSide • + rSide; • } document.body.all document.body.all document.body.all
Optimizing Symbol ResolutionMultiple DOM lookups: Cache references • function CalculateSum2(){ • // Cache Element Collection • var elms = document.body.all; • // Retrieve Values • var lSide = elms.lSide.value;var rSide = elms.rSide.value; • // Generate Resultelms.result.value = lSide + rSide; • } var elms = document.body.all; elms elms elms
Optimizing Symbol ResolutionFunction lookups • function IterateWorkOverCollection(){ • var length = myCollection.length; • for(var i = 0; i < length; i++){ • Work(myCollection[i]); • } • } Work
Optimizing Symbol ResolutionFunction lookups: Cache pointers • function IterateWorkOverCollection2(){ • var funcWork = Work; • var length = myCollection.length; • for(var i = 0; i < length; i++){ • funcWork(myCollection[i]); • } • } varfuncWork = Work; funcWork
Optimizing Symbol ResolutionTakeaways • Watch for expensive name lookups • Cache repeated lookups to local variables • Optimize only when needed • Consider maintainability
demo IE8 JavaScript Profiler
Visual Studio 2010 Profiler • New summary page depicting performance bottlenecks
Visual Studio 2010 Profiler • Ajax/JScript Profiling is now integrated with Load Test Performance Sessions • See a demo at http://channel9.msdn.com/pdc2008/TL24/
Topics • CSS Performance Considerations • Optimizing Symbol Resolution • JavaScript Coding Inefficiencies • HTTP Performance
JavaScript Coding InefficienciesParsing JSON • With eval • Requires new script execution context (slow) • Less secure • With custom library • More secure, but even slower
JavaScript Coding InefficienciesParsing JSON: Use the native methods New in IE8 • Built-in JSON methods • JSON.parse() • JSON.stringify() • toJSON() on prototypes of Date, Number, String, and Boolean • Native equivalent of the reference parser from http://wiki.ecmascript.org/doku.php?id=es3.1:json_support • As safe as http://www.json.org/json_parser.jsbut faster
demo JSON Performance
JavaScript Coding InefficienciesThe switch statement • switch(option) • { • case 1: … • case 2: … • case 3: … • … • case 1000: … • } case 1000:
JavaScript Coding InefficienciesThe switch statement: Use a lookup table • var lookup = { • 1: function(){…} • 2: function(){…} • 3: function(){…} • … • 1000: function(){…} • } • try { • lookup [option](); • } catch(e) { • // Default operation • } lookup[option]();
JavaScript Coding InefficienciesProperty access methods • var property = foo(); • this.getProperty = function() • { • return property; • } • this.setProperty = function(value) • { • property = value; • }
JavaScript Coding InefficienciesProperty access methods: Use direct access • this.property = foo();
JavaScript Coding InefficienciesProperty access methods • Instantiating DOM functions • Problems: Costly (in CPU cycles) • Consider: Caching function pointers, batching changes • Why: Generic script interface Better in IE8
JavaScript Coding InefficienciesMinimize DOM interaction • Scope • var name • Prototype • obj.name Cost DOM Global Prototype … Intermediate … Instance Local
JavaScript Coding InefficienciesMinimize DOM interaction Better in IE8 • Scope • var name • Prototype • obj.name Cost DOM Global Prototype … Intermediate … Instance Local
JavaScript Coding InefficienciesMinimize DOM interaction Trident (MSHTML) DOM JScript Engine
JavaScript Coding InefficienciesMinimize DOM interaction function getElementsByClassName(className, node, tag) { … var elements = node.getElementsByTagName(tag); var pattern = new RegExp("(^|\\s)" + className + "(\\s|$)"); for(var i = 0, j = 0; i < elements.length; i++) { if (pattern.test(elements[i].className)) { classElements[j] = elements[i]; j++; } } return classElements; } var elements = node.getElementsByTagName(tag); elements.length elements[i]
JavaScript Coding InefficienciesMinimizeDOM interaction function getElementsByClassName(className, node, tag) { … var results = node.getElementsByTagName(tag); var elements = new Array(results.length); while (length--) elements[length] = results[length]; var pattern = new RegExp("(^|\\s)" + className + "(\\s|$)"); for(var i = 0, j = 0; i < elements.length; i++) { if (pattern.test(elements[i].className)) { classElements.push(results[i]); j++; } } return classElements; } • var elements = new Array(results.length); • while (length--) elements[length] = results[length]; elements.length elements[i]
JavaScript Coding InefficienciesSmart use of DOM methods • Smart use of DOM methods can minimize overall DOM interaction • nextSibling() better than childNodes[i] • querySelectorAll() better for element groups
JavaScript Coding InefficienciesSmart use of DOM methods function LoopChildren(elm) { • var nodes = elm.childNodes; • var length = nodes.length; • for(var i = 0; i < length; i++) • { • var node = nodes[i]; • … • } } nodes[i];
JavaScript Coding InefficienciesSmart use of DOM methods function LoopChildren2(elm) { • var node = elm.firstChild; • while(node != null) • { • … • node = node.nextSibling; • } • } node.nextSibling;
JavaScript Coding InefficienciesUse querySelectorAll for groups New in IE8 function doValidation2() { • // Retrieve the required elements by using Selectors • // Selects all form fields with 'required' classes • var reqs = document.querySelectorAll(".required"); • // Set the flag to false by default • var missingRequiredField = false; • // Validate that the form data is not empty • for (var i = 0; i < reqs.length; i++) { • if (reqs[i].value == "") • missingRequiredField = true; • } } document.querySelectorAll
JavaScript Coding InefficienciesTakeaways • Use the native JSON object • Turn large switch statements into lookups • Avoid property access methods • Minimize DOM interaction • Use querySelectorAll for groups • Optimize only when needed • Consider maintainability