Enhance Web Performance
Upcoming SlideShare
Loading in...5
×
 

Enhance Web Performance

on

  • 2,912 views

 

Statistics

Views

Total Views
2,912
Views on SlideShare
2,906
Embed Views
6

Actions

Likes
7
Downloads
60
Comments
1

1 Embed 6

http://www.slideshare.net 6

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Enhance Web Performance Enhance Web Performance Presentation Transcript

  • Enhance Web Performance Adam Lu [email_address] Y!ID: adamlu86 http://adamlu.com/
  • The Performance Golden Rules 80-90% of the end-user response time is spent on the front-end.
  • High Performance Web Sites
    • Make fewer Http Requests
    • Style sheets at the top
    • Placing scripts.
    • Avoid CSS Expressions
    • Make CSS and JS external
    • Minification
    • Make Ajax cacheable
    • Miscellaneous Tips
    View slide
  • Make fewer Http Requests
    • Combine CSS and JavaScript files
    • Css Sprites – Used for snappy image replacement
      • Combine static images into a single image file.
      • Use Css to cut and place.
      • CSS properties background-image and background-position are used.
        • background:transparent url(“sprite.png”;) no-repeat
        • background-position: 0 -30px
    View slide
  • Style sheets at the top
    • Use <link> tags to include stylesheets.
    • Neglect embedded styles and inline styles too.
    • Push style sheet inclusion into the head.
    • User perception of the page loading faster is important
  • Placing scripts
    • Move script inclusion as low as possible
    • Don’t scatter inline scripts
    • Progressive rendering.
    • Scripts don’t download parallely. But in IE, it can be achieved by Dom inlucde.
      • window.onload = function () {
      • var script = document.createElement(“script”);
      • script.src = ...;
      • document.body.appendChild(script);
      • };
  • Avoid CSS Expressions
    • Option available only in IE.
      • width:expression(document.body.clientWidth < 550 ? “450px” : “100%” );
    • Use event handlers instead.
      • Eg: element.addEventListener(‘<event>’, <handler to call>, <capturing/bubbling>).
      • Eg: window.addEventListener(‘resize’, changeWidth, true).
      • element.removeEventListener is used to remove the event.
      • In IE, attachEvent must be used instead.
  • Make JS &CSS external
    • Inline – Using <@include> or import make the html doc big.
    • External using <script> and <link> tags
      • Increases Http requests (bad)
      • Helps caching (good)
  • Minification
    • Minify external javascript
      • Remove comments and spaces
    • Minify inline scripts
    • Obfuscation- Not recommended. Not safe
    • Let the dev code not be minified. Should have comments/spaces for maintainability. Use Tools before moving code to production.
      • Js Min
      • YUI Compressor.
  • Make Ajax cacheable
    • No synchronous requests.
    • Use GET for AJAX Requests
      • Post is a two step process (Sending the headers first and then sending data) ‏
    • Favor JSON over XML as your data exchange format.
    • AJAX pattern:
        • Update the UI when the request gets sent.
        • Lock the UI/data structures with the finest possible granularity.
        • Let the user know that something is happening.
        • Let the user know why a UI object is locked.
        • Unlock the UI/data structures when the outcome is successful.
        • Handle error cases gracefully.
    • Lazy loading - http://ajaxpatterns.org/On-Demand_Javascript
  • Miscellaneous Tips
    • Optimize Table Layout
        • Goal: allow the rendering engine to start rendering a table before it has received all the data
        • Use table-layout:fixed
        • Explicitly define a COL element for each column
        • Set the WIDTH attribute on each col
    • Close Your HTML Tags to Speed Up Parsing
    • Regular expression
        • Use regular expression literals.
          • Eg: if (/loaded|complete/.test(status)) {...}
        • Stick to simple patterns
    • In IE, Use Array.join(“”) rather than string concatenation
  • Miscellaneous Tips
    • In case of changing lot of styles in js, try swapping styleclasses.
      • More maintainable: change the CSS class name of an element. obj.className=‘<class>’;
    • Consider using the onmousedown event instead of the onclick event
    • Document Tree Modification.
      • InnerHTML Way is Faster than Usal Way
  • Speed Up Javascript
  • There are four main reasons why a script can take too long to execute
    • Too much happening in a loop.
    • Too much happening in a function.
    • Too much recursion.
    • Too much DOM interaction.
  • Too much happening in a loop
    • for(var i=0; i < items.length; i++){
    • process(items[i]);
    • }
    • function chunk(array, process, context){
    • var items = array.concat(); //clone the array
    • setTimeout(function(){
    • var item = items.shift();
    • process.call(context, item);
    • if (items.length > 0){
    • setTimeout(arguments.callee, 100);
    • }
    • }, 100);
    • }
  • Too much happening in a function
    • function bubbleSort(items){ for (var i=items.length-1; i >= 0; i--){ for (var j=i; j >= 0; j--){ if (items[j] < items[j-1]){ var temp = items[j]; items[j] = items[j-1]; items[j-1] = temp; } } } }
    • function bubbleSort(array, onComplete){ var pos = 0; (function(){ var j, value; for (j=array.length; j > pos; j--){ if (array[j] < array[j-1]){ value = data[j]; data[j] = data[j-1]; data[j-1] = value; } } pos++; if (pos < array.length){ setTimeout(arguments.callee,10); } else { onComplete(); } })(); }
  • Too much happening in a function
    • function fibonacci (n) { return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); };
    • function memoizer(memo, fundamental) { var shell = function (n) { var result = memo[n]; if (typeof result !== 'number') { result = fundamental(shell, n); memo[n] = result; } return result; }; return shell; };
    • var fibonacci = memoizer([0, 1], function (recur, n) { return recur(n - 1) + recur(n - 2); });
    • fibonacci(40);
  • Too much recursion
    • function merge(left, right){ var result = []; while (left.length > 0 && right.length > 0){ if (left[0] < right[0]){ result.push(left.shift()); } else { result.push(right.shift()); } } return result.concat(left).concat(right); }
    • //recursive merge sort algorithm
    • function mergeSort(items){ if (items.length == 1) { return items; } var middle = Math.floor(items.length / 2), left = items.slice(0, middle), right = items.slice(middle); return merge(mergeSort(left), mergeSort(right)); }
    • //iterative merge sort algorithm
    • function mergeSort(items){ if (items.length == 1) { return items; } var work = []; for (var i=0, len=items.length; i < len; i++){ work.push([items[i]]); } work.push([]); //in case of odd number of items for (var lim=len; lim > 1; lim = (lim+1)/2){ for (var j=0,k=0; k < lim; j++, k+=2){ work[j] = merge(work[k], work[k+1]); } work[j] = []; //in case of odd number of items } return work[0]; }
  • Too much DOM interaction
    • Reflow happens at various points in time:
      • Initial page load.
      • Browser window resize.
      • DOM nodes added or removed. (When you add or remove a DOM node. )
      • Layout styles applied. (When you apply a style dynamically (such as element.style.width=&quot;10px&quot;).)
      • Layout information retrieved. (When you retrieve a measurement that must be calculated, such as accessing offsetWidth, clientHeight, or any computed CSS value (via getComputedStyle() in DOM-compliant browsers or currentStyle in IE), while DOM changes are queued up to be made.)
  • perform as many changes as possible outside of the live DOM structure
    • for (var i=0; i < items.length; i++){ var item = document.createElement(&quot;li&quot;); item.appendChild(document.createTextNode(&quot;Option &quot; + i); list.appendChild(item); }
    • var fragment = document.createDocumentFragment(); for (var i=0; i < items.length; i++){ var item = document.createElement(&quot;li&quot;); item.appendChild(document.createTextNode(&quot;Option &quot; + i); fragment.appendChild(item); } list.appendChild(fragment);
  • remove a node from the live DOM before operating on it
    • list.style.display = &quot;none&quot;;
    • for (var i=0; i < items.length; i++){
    • var item = document.createElement(&quot;li&quot;); item.appendChild(document.createTextNode(&quot;Option &quot; + i);
    • list.appendChild(item); }
    • list.style.display = &quot;&quot;;
    • change the class using JavaScript rather than applying individual style changes manually
    • element.style.backgroundColor = &quot;blue&quot;; element.style.color = &quot;red&quot;; element.style.fontSize = &quot;12em&quot;;
    • element.className = &quot;newStyle&quot;;
    • cache results that you retrieve from the DOM
    • document.getElementById(&quot;myDiv&quot;).style.left = document.getElementById(&quot;myDiv&quot;).offsetLeft + document.getElementById(&quot;myDiv&quot;).offsetWidth + &quot;px&quot;;
    • var myDiv = document.getElementById(&quot;myDiv&quot;); myDiv.style.left = myDiv.offsetLeft + myDiv.offsetWidth + &quot;px&quot;;
  • Proccess the HTMLCollection type
    • var divs = document.getElementsByTagName(&quot;div&quot;);
    • for (var i=0; i < divs.length; i++){ //infinite loop document.body.appendChild(document.createElement(&quot;div&quot;)); }
    • var divs = document.getElementsByTagName(&quot;div&quot;);
    • for (var i=0, len=divs.length; i < len; i++){ //not an infinite loop document.body.appendChild(document.createElement(&quot;div&quot;)); }
  • Fastest way to build an HTML string
    • String concat
    • var arr = ['item 1', 'item 2', 'item 3', ...], list = '';   for (var i = 0, l = arr.length; i < l; i++) { list += '<li>' + arr[i] + '</li>'; }   list = '<ul>' + list + '</ul>';
    • Array pushing
    • var arr = ['item 1', 'item 2', 'item 3', ...], list = [];   for (var i = 0, l = arr.length; i < l; i++) { list[list.length] = '<li>' + arr[i] + '</li>'; }   list = '<ul>' + list.join('') + '</ul>';
    • Native join
    • var arr = ['item 1', 'item 2', 'item 3', ...];   var list = '<ul><li>' + arr.join('</li><li>') + '</li></ul>';
  • Javascript good practice
    • Always use “var” for declaration.
    • Feature detect rather that browser detect.
    • Use Object literal notation:
        • Var order = {
        • mode: ‘default’,
        • obj : { id:’1’, val:’10’},
        • array1 : [‘1’, ‘2’, ‘3’],
        • show : function(elToshow) {
        • }
        • }
    • Use square bracket notation
      • MyObject[“property”] rather than MyObject.property
      • Use dot notation for standard properties of objects
      • Square bracket notation to access properties which are defined as objects in the page.
        • Good: document.forms[“formname”].elements[“input”].value
        • Bad : document.formname.inputname
  • Javascript good practice
    • Avoid eval. Use JSON.parse(jsontext, reviver);
    • Use === and !== in place of == and !=. Because of type coercion.
    • Cache variables.
    • Falsy values in js.
      • If (“”), if (0), if (null), if (undefined), if(NaN) are false.
    • The Unary + Operator To TypeConvert To Number
      • Eg: var input1 = document.getElementById(‘text1’).value;
      • var input2 = document.getElementById(‘text2’).value;
      • var value1 = (+input1)+(+input2) or var value1 = (input1-0)+(input2-0);
    • Avoid Cluttering The Global Namespace. Use object literals.
    • Avoid “with”
    • Use JSON instead of XML
    • Use Correct <script> Tags
      • <script type=“text/javascript” src=”..”>, Language tag is deprecated.
    More On http://www.javascripttoolbox.com/bestpractices/
  • Minify HTML
  • Minify HTML
    • Placing Inline Elements Inside Block Elements
    • Using <strong> and <em> instead of <b> and <i> for Bolding and Italicizing
    • Using <del> and <ins> instead of <s> and <strike> for showing deleted and inserting text
    • Using Less Line Breaks
    • Avoid using inline styling
    • Inline Images data:URL scheme ---- disobedient
  • Css Guidelines
  • Css Guidelines
    • What’s the key selector?
    • a > img {//props} div > p
    • How the Style System Matches Rules
    • Style Computation – R to L
    • Four types of css
      • ID Rules button#backButton { } 、 #urlBar[type=“autocomplete”] { } treeitem > treerow > treecell 、 #myCell:active { }
      • Class Rules button.toolbarButton { } 、 .fancyText { } 、 menuitem > .menu-left[checked=&quot;true&quot;] { }
      • Tag Rules td { } 、 treeitem > treerow { } 、 input[type=&quot;checkbox&quot;] { }
      • Universal Rules [hidden=“true”] { } 、 * { } 、 tree > [collapsed=&quot;true&quot;] { }
  • Guidelines for Efficient CSS
    • Avoid Universal Rules!.
    • Don’t qualify ID/class-categorized rules with tag/class names BAD - button#backButton { } GOOD - #backButton { }
    • Tag-categorized rules should never contain a child selector! BAD - treehead > treerow > treecell { } BEST - .treecell-header { }
    • Rely on inheritance! BAD - #bookmarkMenuItem > .menu-left { list-style-image: url(blah); } GOOD - #bookmarkMenuItem { list-style-image: url(blah); }
    https://developer.mozilla.org/en/Writing_Efficient_CSS
  • Tools of Analyzing Performance
    • YSlow (YAHOO!)
    • http:// developer.yahoo.com/yslow /
    • Page Speed (Google) http://code.google.com/speed/page-speed/
    • Firebug
    • http://getfirebug.com/
    • Fasterfox
    • http:// fasterfox.mozdev.org
  • Thanks!