Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Doris Chen Ph.D.
Senior Developer Evangelist
Microsoft
doris.chen@microsoft.com
@doristchen
Meet Doris Chen| @doristchen
• Senior Technology Evangelist, Microsoft
• Focus on Web technologies, JavaScript, and HTML5
• Blogging at http://blogs.msdn.com/b/dorischen/
• Speaks at numerous international conferences and user groups
including O’Reilly OSCON, Fluent, Dev Nexus, HTML5 Dev
Conference, JavaOne, and worldwide User Groups
• Received her Ph.D. from the University of California at Los
Angeles (UCLA) in computer engineering
Agenda
• Performance Overview
• What to measure
• Tools
• Optimization Tips
– Document Object Model (DOM)
• Layout Thrashing
• List Virtualization
– CSS, Images, Animation, JavaScript
– Garage Collection
• Event Bubbling
• Memory Leaks
Performance Overview
Apache Cordova apps are written in HTML, CSS, and JavaScript
that can also access native device capabilities.
Cordova apps are web
applications that run inside a
native application.
This allows you to use HTML,
CSS, and JavaScript to build
your app while still having
access to your device’s
hardware capabilities!
Native Wrapper
<webview>
Your JavaScript App
Cordova Plugin JS API
What does it mean for something
to be fast and responsive?
Interaction Classes
Interaction Classes
What we care about!
What to Measure
Performance Cost
• Startup cost
• Memory cost
• Communication cost
• Resume cost
• Web cost
Devices
• Compared performance on three nice, but aging devices with
similar hardware profiles:
• Nexus 7 2013 (Android)
• iPad Mini 3 (iOS)
• Lumia 928 (WP)
Startup Cost
Platform
Cordova
Cold
Native
Cold
Cordova
Warm
Native
Warm
Android
4.4
3425 ms 557 ms 3358 ms 454 ms
iOS 8 3142 ms 5825 ms 1921 ms 2000 ms
WP 8.0 2433 ms 1667 ms 1083 ms 1098 ms
0
1
2
3
4
5
6
7
Android Cold Android Warm iOS Cold iOS Warm WP Cold WP Warm
SECONDS
Startup Time
Native Cordova
Because Cordova apps run inside a webview, they incur overhead
from both the browser layout and scripting engine. This means you
have a web application running inside a native app. That’s the tax.
0
10
20
30
40
50
60
70
Android iOS Windows Store Windows Phone
Memory(MB)
Native App
0
10
20
30
40
50
60
70
Android iOS Windows Store Windows Phone
Memory(MB)
Native App Browser
0
10
20
30
40
50
60
70
Android iOS Windows Store Windows Phone
Memory(MB)
Native App Browser Cordova App
To access device capabilities, Cordova apps must also
communicate with the native application via asynchronous calls
(XHR).
Communication Cost
Items 1 2,000 20,000 200,000
Android 4.4 4 ms 22 ms 157 ms 1121 ms
iOS 8.0 3 ms 45 ms 135 ms 1120 ms
WP 8.1 1 ms 27 ms 139 ms 877 ms
Communication Cost
0
200
400
600
800
1000
1200
1400
1600
1800
0 50000 100000 150000 200000 250000 300000
Time(ms)
Number of elements to transfer
Time of data transfer
iOS Android WP (C#) WP (js)
Tools
What’s Right for me?
Which Tool When to Use
Developer Tools –
CPU Profiler
Identify which JavaScript code is taking the most
time to run
Developer Tools –
Timeline (UI) Profiler
Identify whether JavaScript or rendering
performance may be the bottleneck
JavaScript timing APIs
Measure the duration of specific scenarios with
clear start and end points
Visually timing
Measure scenarios that are hard to time with code,
like startup or navigation, or “time to glass”
loading/update that require precise timing
Profiling iOS devices by using Safari
https://developer.apple.com/safari/tools
Profiling Android devices from Chrome
https://developer.chrome.com/devtools
Profiling Windows Phone from Visual Studio
http://blogs.msdn.com/b/visualstudioalm/archive/2013/07/12/performance-and-diagnostics-hub-in-visual-studio-2013.aspx
DEMO
Profiling Windows Phone from Visual Studio
Measuring performance via JavaScript
var start = performance.now();
someCodeToTime();
var end = performance.now();
console.log("someCodeToTime took " + (end-start) + "ms");
Note, Safari on iOS still doesn't support performance.now(), so you'll want to polyfill
Practical tipsmakemobilefaster oscon2016
Optimization Tips
Document Object Model (DOM)
Simple DOM vs. Complex DOM
<ul>
<!-- Two elements -->
<li><a href=“dosomething1.html”>Alpha</a></li>
</ul>
<ul>
<!-- One element = less layout, simpler DOM -->
<li aria-role=“button” onclick=“dosomething(a)”>Alpha</li>
</ul>
Good
Bad
Reduce your element count
The more elements you have on the page, the
slower your page will be
Layout Thrashing
When you make modifications to certain CSS style properties or
parent DOM elements, the rendering engine will cause the layout
of the entire document to refresh.
Sometimes, this refreshing occurs repeatedly…and noticeably if you
have a lot of UI elements displayed!
DEMO
Layout Thrashing
Bad
for (var i = b.children.length - 1; i >= 0; i--) {
b.children[i].style.left = b.children[i].offsetLeft + "px";
b.children[i].style.top = b.children[i].offsetTop + "px";
}
Good
for (var i = b.children.length - 1; i >= 0; i--) {
topPx[i] = b.children[i].offsetTop;
leftPx[i] = b.children[i].offsetLeft;
}
for (var i = b.children.length - 1; i >= 0; i--) {
b.children[i].style.left = leftPx[i] + "px";
b.children[i].style.top = topPx[i] + "px";
}
Batch Layout Operations Together
Batch the read/change operations on element
properties in a loop that affects layout
Fast List Scrolling
• Displaying a list of data is a common scenario for many apps. To
ensure your data displays smoothly – especially when scrolling,
ensure you fetch only the data you want and render only the
content that is going to be necessary.
• This is commonly known as virtualization.
DEMO
List Virtualization
0
50
100
150
200
250
300
350
Virtualized Not Virtualized
Usage(MBs)
Memory Usage: Virtualized List vs. Non-Virtualized List
Use virtualization
When working with large amounts of data, only work
with the data you need to display content on the
screen.
(Popular control frameworks like WinJS, Ionic, Onsen UI, Kendo UI
and others help handle this for you)
CSS, Images
You can specify gradients to blend multiple colors together in a
single region. In HTML and CSS, you have several ways of
specifying them. You can use an image or you can specify a
gradient in CSS itself.
Let’s look at which one is faster!
Gradients
Gradients: CSS vs. Image
Bad
.css_gradient {
background: -webkit-linear-gradient(top,rgb(84, 1, 1),rgb(0,
84, 119)); /*Safari 5.1-6*/
background: -o-linear-gradient(top,rgb(84, 1, 1),rgb(0, 84,
119)); /*Opera 11.1-12*/
background: -moz-linear-gradient(tp,rgb(84, 1, 1),rgb(0, 84,
119)); /*Fx 3.6-15*/
background: linear-gradient(top, rgb(84, 1, 1),rgb(0, 84,
119)); /*Standard*/
}
Good
.image_gradient {
background: url('../images/gradient.png');
}
• Use Images for Gradients & Shadows
CSS gradients are very convenient, but the browser
is more efficient rendering bitmaps
• Gradients implemented via images result in faster
performance
With the progression of CSS filters and better support
for them, this may change in the future
CSS, Animation, JavaScript
Setting Element Position
• Because handheld devices are CPU bound, you want to defer as
much work to your device’s GPU as you can. This can be easily
ensured by setting the appropriate CSS properties.
Bad
@keyframes bobble {
0% {
left: 50px;
animation-timing-function: ease-in;
}
50% {
left: 50px;
top: 50px;
animation-timing-function: ease-out;
}
100% {
left: 50px;
top: 40px;
}
}
Good@keyframes bobble {
0% {
transform: translate3d(50px, 40px, 0px);
animation-timing-function: ease-in;
}
50% {
transform: translate3d(50px, 50px, 0px);
animation-timing-function: ease-out;
}
100% {
transform: translate3d(50px, 40px, 0px);
}
}
Use translate3d for Animating Position
When moving elements around, use the transform
property’s translate3d function as opposed to setting
the position property directly.
CSS vs. JavaScript
Animations created in CSS use a built-in loop. Animations created
in JavaScript can use a custom loop that you build. Let’s see which
is faster.
Paint as much as your users can see
Align timers to display frames
setInterval(animate, 0);
setTimeout(animate, 0);
requestAnimationFrame(animate);
setInterval(animate, 1000 / 60);
setTimeout(animate, 1000 / 60);
MORE WORK LESS WORK
Results
Save CPU cycles
75% 65%
setTimeout(animate, 0); requestAnimationFrame(animate);
Use CSS
For the smoothest animations, use CSS animations or CSS
transitions. If you need to use JavaScript, ensure your animation
loop is defined using the requestAnimationFrame function.
Garbage Collection
The garbage collector is responsible for managing the lifecycle of
the objects in your apps. It keeps track of which ones to keep
around and which ones to destroy to free up memory.
While the garbage collector runs automatically, there are things
you can do to optimize its behavior.
Bad
function createElements() {
for (var i = 0; i < 100; ++i) {
var xBtn = document.createElement('button');
xBtn.setAttribute('value', 'AA');
xBtn.addEventListener('click', hi, false);
containerDiv.appendChild(xBtn);
xBtn = null;
}
}
function clearElements() {
containerDiv.innerHTML = "";
}
Goodfunction createElements() {
for (var i = 0; i < 100; ++i) {
var xBtn = document.createElement('button');
xBtn.setAttribute('value', 'AA');
xBtn.addEventListener('click', hi, false);
containerDiv.appendChild(xBtn);
xBtn = null;
}
}
function clearElements() {
var els = containerDiv.childNodes;
for (var i = 0; i < els.length; i++) {
els[i].removeEventListener('click', hi, false);
containerDiv.removeChild(els[i]);
}
}
Be Either Proactive or Be Patient
Use removeEventListener to remove event references before
deleting elements. If you remove elements without removing your
event listener, the memory footprint will steadily increase until the
next garbage collection.
Minimize Unnecessary Event Listeners
If you are listening for events on multiple elements that share the
same ancestor element, don’t assign an event handler to each
element. Instead, just assign one event handler to the ancestor
element.
/* bad */ /* good */
Let’s say you want to listen to a click
event on the elements with the id
value of one, two, three, four, and
five.
Note:
They share a common parent with
the theDude element!
DEMO
Handling Events for Multiple Elements with a Common
Ancestor
Handling Events for Multiple Elements
Handling Events for Multiple Elements
Bad
// ONE FUNCTION FOR EACH EVENT LISTENER
for (i = 0; i < 100; i++){
img[i].addEventListener("click", function() {
var clickedItem = e.target.id;
alert("Hello " + clickedItem);
});
}
Bad
// ONE FUNCTION FOR EACH EVENT LISTENER
for (i = 0; i < 100; i++){
img[i].addEventListener("click", function clickListener(e) {
var clickedItem = e.target.id;
alert("Hello " + clickedItem);
});
}
Handling Events for Multiple Elements
Good
var theParent = document.querySelector("#theDude");
theParent.addEventListener("click", doSomething, false);
function doSomething(e) {
if (e.target !== e.currentTarget) {
var clickedItem = e.target.id;
alert("Hello " + clickedItem);
}
e.stopPropagation();
}
Handling Events for Multiple Elements
Take Advantage of Event Bubbling
Having one event as opposed to many events reduces the amount
of memory each UI element takes up. For scenarios where you
have many elements and a common ancestor, use the technique
described here
Pay Attention to Memory Leaks
When you are making DOM manipulations, simply removing an
element from the tree doesn’t ensure the element gets garbage
collected. You will need to be more proactive about telling
JavaScript to re-claim the memory.
Memory Leaks Demo
Bad
// el is in the global scope, so it persists with the document
var el;
function doSomething() {
el = document.createElement('div');
parent.appendChild(el);
}
function empty() {
parent.innerHTML = "";
}
Memory Leaks
Good
// el is in the local scope, so expires with the function
function doSomething() {
var el = document.createElement('div');
parent.appendChild(el);
}
function empty() {
parent.innerHTML = "";
}
Memory Leaks
Destroy Unused Objects
When you remove DOM elements from the tree or clear out
variables that store a lot of data, be sure to also clear or destroy
any objects that may be referencing them as well. Otherwise, the
elements will avoid getting garbage collected.
Practical tipsmakemobilefaster oscon2016
1. Your UI is considered fast when it reacts to user actions in
under 100ms.
2. The less elements you have on your page, the faster and less
memory-intensive your app.
3. Use virtualization to manage the size of your DOM
4. Batch layout operations to avoid duplicate reads/writes on
layout properties
Practical Tips (1/3)
5. Implement gradients & shadows as images rather than CSS
6. Use CSS transform: translate3D for animating position
7. Create fast animations in CSS or by using
requestAnimationFrame in JavaScript
Practical Tips (2/3)
8. Use removeEventListener to remove event references from
elements – even if the element is about to be deleted.
9. Reduce the amount of event listeners in your app by relying on
event bubbling
10. Destroy unused elements and objects to save memory.
Practical Tips (3/3)

More Related Content

Practical tipsmakemobilefaster oscon2016

  • 1. Doris Chen Ph.D. Senior Developer Evangelist Microsoft doris.chen@microsoft.com @doristchen
  • 2. Meet Doris Chen| @doristchen • Senior Technology Evangelist, Microsoft • Focus on Web technologies, JavaScript, and HTML5 • Blogging at http://blogs.msdn.com/b/dorischen/ • Speaks at numerous international conferences and user groups including O’Reilly OSCON, Fluent, Dev Nexus, HTML5 Dev Conference, JavaOne, and worldwide User Groups • Received her Ph.D. from the University of California at Los Angeles (UCLA) in computer engineering
  • 3. Agenda • Performance Overview • What to measure • Tools • Optimization Tips – Document Object Model (DOM) • Layout Thrashing • List Virtualization – CSS, Images, Animation, JavaScript – Garage Collection • Event Bubbling • Memory Leaks
  • 5. Apache Cordova apps are written in HTML, CSS, and JavaScript that can also access native device capabilities.
  • 6. Cordova apps are web applications that run inside a native application. This allows you to use HTML, CSS, and JavaScript to build your app while still having access to your device’s hardware capabilities! Native Wrapper <webview> Your JavaScript App Cordova Plugin JS API
  • 7. What does it mean for something to be fast and responsive?
  • 11. Performance Cost • Startup cost • Memory cost • Communication cost • Resume cost • Web cost
  • 12. Devices • Compared performance on three nice, but aging devices with similar hardware profiles: • Nexus 7 2013 (Android) • iPad Mini 3 (iOS) • Lumia 928 (WP)
  • 13. Startup Cost Platform Cordova Cold Native Cold Cordova Warm Native Warm Android 4.4 3425 ms 557 ms 3358 ms 454 ms iOS 8 3142 ms 5825 ms 1921 ms 2000 ms WP 8.0 2433 ms 1667 ms 1083 ms 1098 ms
  • 14. 0 1 2 3 4 5 6 7 Android Cold Android Warm iOS Cold iOS Warm WP Cold WP Warm SECONDS Startup Time Native Cordova
  • 15. Because Cordova apps run inside a webview, they incur overhead from both the browser layout and scripting engine. This means you have a web application running inside a native app. That’s the tax.
  • 16. 0 10 20 30 40 50 60 70 Android iOS Windows Store Windows Phone Memory(MB) Native App
  • 17. 0 10 20 30 40 50 60 70 Android iOS Windows Store Windows Phone Memory(MB) Native App Browser
  • 18. 0 10 20 30 40 50 60 70 Android iOS Windows Store Windows Phone Memory(MB) Native App Browser Cordova App
  • 19. To access device capabilities, Cordova apps must also communicate with the native application via asynchronous calls (XHR).
  • 20. Communication Cost Items 1 2,000 20,000 200,000 Android 4.4 4 ms 22 ms 157 ms 1121 ms iOS 8.0 3 ms 45 ms 135 ms 1120 ms WP 8.1 1 ms 27 ms 139 ms 877 ms
  • 21. Communication Cost 0 200 400 600 800 1000 1200 1400 1600 1800 0 50000 100000 150000 200000 250000 300000 Time(ms) Number of elements to transfer Time of data transfer iOS Android WP (C#) WP (js)
  • 22. Tools
  • 23. What’s Right for me? Which Tool When to Use Developer Tools – CPU Profiler Identify which JavaScript code is taking the most time to run Developer Tools – Timeline (UI) Profiler Identify whether JavaScript or rendering performance may be the bottleneck JavaScript timing APIs Measure the duration of specific scenarios with clear start and end points Visually timing Measure scenarios that are hard to time with code, like startup or navigation, or “time to glass” loading/update that require precise timing
  • 24. Profiling iOS devices by using Safari https://developer.apple.com/safari/tools
  • 25. Profiling Android devices from Chrome https://developer.chrome.com/devtools
  • 26. Profiling Windows Phone from Visual Studio http://blogs.msdn.com/b/visualstudioalm/archive/2013/07/12/performance-and-diagnostics-hub-in-visual-studio-2013.aspx
  • 27. DEMO Profiling Windows Phone from Visual Studio
  • 28. Measuring performance via JavaScript var start = performance.now(); someCodeToTime(); var end = performance.now(); console.log("someCodeToTime took " + (end-start) + "ms"); Note, Safari on iOS still doesn't support performance.now(), so you'll want to polyfill
  • 32. Simple DOM vs. Complex DOM
  • 33. <ul> <!-- Two elements --> <li><a href=“dosomething1.html”>Alpha</a></li> </ul> <ul> <!-- One element = less layout, simpler DOM --> <li aria-role=“button” onclick=“dosomething(a)”>Alpha</li> </ul> Good Bad
  • 34. Reduce your element count The more elements you have on the page, the slower your page will be
  • 35. Layout Thrashing When you make modifications to certain CSS style properties or parent DOM elements, the rendering engine will cause the layout of the entire document to refresh. Sometimes, this refreshing occurs repeatedly…and noticeably if you have a lot of UI elements displayed!
  • 37. Bad for (var i = b.children.length - 1; i >= 0; i--) { b.children[i].style.left = b.children[i].offsetLeft + "px"; b.children[i].style.top = b.children[i].offsetTop + "px"; }
  • 38. Good for (var i = b.children.length - 1; i >= 0; i--) { topPx[i] = b.children[i].offsetTop; leftPx[i] = b.children[i].offsetLeft; } for (var i = b.children.length - 1; i >= 0; i--) { b.children[i].style.left = leftPx[i] + "px"; b.children[i].style.top = topPx[i] + "px"; }
  • 39. Batch Layout Operations Together Batch the read/change operations on element properties in a loop that affects layout
  • 40. Fast List Scrolling • Displaying a list of data is a common scenario for many apps. To ensure your data displays smoothly – especially when scrolling, ensure you fetch only the data you want and render only the content that is going to be necessary. • This is commonly known as virtualization.
  • 42. 0 50 100 150 200 250 300 350 Virtualized Not Virtualized Usage(MBs) Memory Usage: Virtualized List vs. Non-Virtualized List
  • 43. Use virtualization When working with large amounts of data, only work with the data you need to display content on the screen. (Popular control frameworks like WinJS, Ionic, Onsen UI, Kendo UI and others help handle this for you)
  • 45. You can specify gradients to blend multiple colors together in a single region. In HTML and CSS, you have several ways of specifying them. You can use an image or you can specify a gradient in CSS itself. Let’s look at which one is faster! Gradients
  • 47. Bad .css_gradient { background: -webkit-linear-gradient(top,rgb(84, 1, 1),rgb(0, 84, 119)); /*Safari 5.1-6*/ background: -o-linear-gradient(top,rgb(84, 1, 1),rgb(0, 84, 119)); /*Opera 11.1-12*/ background: -moz-linear-gradient(tp,rgb(84, 1, 1),rgb(0, 84, 119)); /*Fx 3.6-15*/ background: linear-gradient(top, rgb(84, 1, 1),rgb(0, 84, 119)); /*Standard*/ }
  • 49. • Use Images for Gradients & Shadows CSS gradients are very convenient, but the browser is more efficient rendering bitmaps • Gradients implemented via images result in faster performance With the progression of CSS filters and better support for them, this may change in the future
  • 51. Setting Element Position • Because handheld devices are CPU bound, you want to defer as much work to your device’s GPU as you can. This can be easily ensured by setting the appropriate CSS properties.
  • 52. Bad @keyframes bobble { 0% { left: 50px; animation-timing-function: ease-in; } 50% { left: 50px; top: 50px; animation-timing-function: ease-out; } 100% { left: 50px; top: 40px; } }
  • 53. Good@keyframes bobble { 0% { transform: translate3d(50px, 40px, 0px); animation-timing-function: ease-in; } 50% { transform: translate3d(50px, 50px, 0px); animation-timing-function: ease-out; } 100% { transform: translate3d(50px, 40px, 0px); } }
  • 54. Use translate3d for Animating Position When moving elements around, use the transform property’s translate3d function as opposed to setting the position property directly.
  • 55. CSS vs. JavaScript Animations created in CSS use a built-in loop. Animations created in JavaScript can use a custom loop that you build. Let’s see which is faster.
  • 56. Paint as much as your users can see Align timers to display frames setInterval(animate, 0); setTimeout(animate, 0); requestAnimationFrame(animate); setInterval(animate, 1000 / 60); setTimeout(animate, 1000 / 60); MORE WORK LESS WORK
  • 57. Results Save CPU cycles 75% 65% setTimeout(animate, 0); requestAnimationFrame(animate);
  • 58. Use CSS For the smoothest animations, use CSS animations or CSS transitions. If you need to use JavaScript, ensure your animation loop is defined using the requestAnimationFrame function.
  • 60. The garbage collector is responsible for managing the lifecycle of the objects in your apps. It keeps track of which ones to keep around and which ones to destroy to free up memory. While the garbage collector runs automatically, there are things you can do to optimize its behavior.
  • 61. Bad function createElements() { for (var i = 0; i < 100; ++i) { var xBtn = document.createElement('button'); xBtn.setAttribute('value', 'AA'); xBtn.addEventListener('click', hi, false); containerDiv.appendChild(xBtn); xBtn = null; } } function clearElements() { containerDiv.innerHTML = ""; }
  • 62. Goodfunction createElements() { for (var i = 0; i < 100; ++i) { var xBtn = document.createElement('button'); xBtn.setAttribute('value', 'AA'); xBtn.addEventListener('click', hi, false); containerDiv.appendChild(xBtn); xBtn = null; } } function clearElements() { var els = containerDiv.childNodes; for (var i = 0; i < els.length; i++) { els[i].removeEventListener('click', hi, false); containerDiv.removeChild(els[i]); } }
  • 63. Be Either Proactive or Be Patient Use removeEventListener to remove event references before deleting elements. If you remove elements without removing your event listener, the memory footprint will steadily increase until the next garbage collection.
  • 64. Minimize Unnecessary Event Listeners If you are listening for events on multiple elements that share the same ancestor element, don’t assign an event handler to each element. Instead, just assign one event handler to the ancestor element.
  • 65. /* bad */ /* good */
  • 66. Let’s say you want to listen to a click event on the elements with the id value of one, two, three, four, and five. Note: They share a common parent with the theDude element!
  • 67. DEMO Handling Events for Multiple Elements with a Common Ancestor
  • 68. Handling Events for Multiple Elements
  • 69. Handling Events for Multiple Elements
  • 70. Bad // ONE FUNCTION FOR EACH EVENT LISTENER for (i = 0; i < 100; i++){ img[i].addEventListener("click", function() { var clickedItem = e.target.id; alert("Hello " + clickedItem); }); }
  • 71. Bad // ONE FUNCTION FOR EACH EVENT LISTENER for (i = 0; i < 100; i++){ img[i].addEventListener("click", function clickListener(e) { var clickedItem = e.target.id; alert("Hello " + clickedItem); }); }
  • 72. Handling Events for Multiple Elements
  • 73. Good var theParent = document.querySelector("#theDude"); theParent.addEventListener("click", doSomething, false); function doSomething(e) { if (e.target !== e.currentTarget) { var clickedItem = e.target.id; alert("Hello " + clickedItem); } e.stopPropagation(); }
  • 74. Handling Events for Multiple Elements
  • 75. Take Advantage of Event Bubbling Having one event as opposed to many events reduces the amount of memory each UI element takes up. For scenarios where you have many elements and a common ancestor, use the technique described here
  • 76. Pay Attention to Memory Leaks When you are making DOM manipulations, simply removing an element from the tree doesn’t ensure the element gets garbage collected. You will need to be more proactive about telling JavaScript to re-claim the memory.
  • 78. Bad // el is in the global scope, so it persists with the document var el; function doSomething() { el = document.createElement('div'); parent.appendChild(el); } function empty() { parent.innerHTML = ""; }
  • 80. Good // el is in the local scope, so expires with the function function doSomething() { var el = document.createElement('div'); parent.appendChild(el); } function empty() { parent.innerHTML = ""; }
  • 82. Destroy Unused Objects When you remove DOM elements from the tree or clear out variables that store a lot of data, be sure to also clear or destroy any objects that may be referencing them as well. Otherwise, the elements will avoid getting garbage collected.
  • 84. 1. Your UI is considered fast when it reacts to user actions in under 100ms. 2. The less elements you have on your page, the faster and less memory-intensive your app. 3. Use virtualization to manage the size of your DOM 4. Batch layout operations to avoid duplicate reads/writes on layout properties Practical Tips (1/3)
  • 85. 5. Implement gradients & shadows as images rather than CSS 6. Use CSS transform: translate3D for animating position 7. Create fast animations in CSS or by using requestAnimationFrame in JavaScript Practical Tips (2/3)
  • 86. 8. Use removeEventListener to remove event references from elements – even if the element is about to be deleted. 9. Reduce the amount of event listeners in your app by relying on event bubbling 10. Destroy unused elements and objects to save memory. Practical Tips (3/3)