转贴:https://10up.github.io/Engineering-Best-Practices/javascript/#performance

Performance

Writing performant code is absolutely critical. Poorly written JavaScript can significantly slow down and even crash the browser. On mobile devices, it can prematurely drain batteries and contribute to data overages. Performance at the browser level is a major part of user experience which is part of the 10up mission statement.

Only Load Libraries You Need

JavaScript libraries should only be loaded on the page when needed. jquery-1.11.1.min.js is 96 KB. This isn't a huge deal on desktop but can add up quickly on mobile when we start adding a bunch of libraries. Loading a large number of libraries also increases the chance of conflictions.

Use jQuery Wisely

jQuery is a JavaScript framework that allows us easily accomplish complex tasks such as AJAX and animations. jQuery is great for certain situations but overkill for others. For example, let's say we want to hide an element:

document.getElementById( 'element' ).style.display = 'none';

vs.

jQuery( '#element' ).hide();

The non-jQuery version is much faster and is still only one line of code.

Try to Pass an HTMLElement or HTMLCollection to jQuery Instead of a Selection String

When we create a new jQuery object by passing it a selection string, jQuery uses it's selection engine to select those element(s) in the DOM:

jQuery( '#menu' );

We can pass our own HTMLCollection or HTMLElement to jQuery to create the same object. Since jQuery does a lot of magic behind the scenes on each selection, this will be faster:

jQuery( document.getElementById( 'menu' ) );

Cache DOM Selections

It's a common JavaScript mistake to reselect something unnecessarily. For example, every time a menu button is clicked, we do not need to reselect the menu. Rather, we select the menu once and cache it's selector. This applies whether you are using jQuery or not. For example:

non-jQuery Uncached:

var hideButton = document.getElementsByClassName( 'hide-button' )[0];
hideButton.onclick = function() {
var menu = document.getElementById( 'menu' );
menu.style.display = 'none';
}

non-jQuery Cached:

var menu = document.getElementById( 'menu' );
var hideButton = document.getElementsByClassName( 'hide-button' )[0];
hideButton.onclick = function() {
menu.style.display = 'none';
}

jQuery Uncached:

var $hideButton = jQuery( '.hide-button' );
$hideButton.on( 'click', function() {
var $menu = jQuery( '#menu' );
$menu.hide();
});

jQuery Cached:

var $menu = jQuery( '#menu' );
var $hideButton = jQuery( '.hide-button' );
$hideButton.on( 'click', function() {
$menu.hide();
});

Notice how in cached versions we are pulling the menu selection out of the event handler so it only happens once. Non-jQuery cached is not surprisingly the fastest way to handle this situation.

Event Delegation

Event delegation is the act of adding one event listener to a parent node to listen for events bubbling up from children. This is much more performant than adding one event listener for each child element. Here is an example:

Without jQuery:

document.getElementById( 'menu' ).addEventListener( 'click', function( event ) {
if( event.target && event.target.nodeName === 'LI' ) {
// Do stuff!
}
});

With jQuery:

jQuery( '#menu' ).on( 'click', 'li', function() {
// Do stuff!
});

The non-jQuery method is as usual more performant. You may be wondering why we don't just add one listener to <body> for all our events. Well, we want the event to bubble up the DOM as little as possible for performance reasons. This would also be pretty messy code to write.

Design Patterns back to top

Standardizing the way we structure our JavaScript allows us to collaborate more effectively with one another. Using intelligent design patterns improves maintainability, code readability, and even helps to prevent bugs.

Don't Pollute the Window Object

Adding methods or properties to the window object or the global namespace should be done carefully. window object pollution can result in collisions with other scripts. We should wrap our scripts in closures and expose methods and properties to window decisively.

When a script is not wrapped in a closure, the current context or this is actuallywindow:

window.console.log( this === window ); // true
for ( var i = 0; i < 9; i++ ) {
// Do stuff
}
var result = true;
window.console.log( window.result === result ); // true
window.console.log( window.i === i ); // true

When we put our code inside a closure, our variables are private to that closure unless we expose them:

( function() {
for ( var i = 0; i < 9; i++ ) {
// Do stuff
} window.result = true;
})(); window.console.log( typeof window.result !== 'undefined' ); // true
window.console.log( typeof window.i !== 'undefined' ); // false

Notice how i was not exposed to the window object.

Use Modern Functions, Methods, and Properties

It's important we use language features that are intended to be used. This means not using deprecated functions, methods, or properties. Whether we are using a JavaScript or a library such as jQuery or Underscore, we should not use deprecated features. Using deprecated features can have negative effects on performance, security, maintainability, and compatibility.

For example, in jQuery jQuery.live() is a deprecated method:

jQuery( '.menu' ).live( 'click', function() {
// Clicked!
});

We should use jQuery.on() instead:

jQuery( '.menu' ).on( 'click', function() {
// Clicked!
});

Another example in JavaScript is escape() and unescape(). These functions were deprecated. Instead we should use encodeURI()encodeURIComponent(),decodeURI(), and decodeURIComponent().

Code Style & Documentation back to top

We conform to WordPress JavaScript coding standards.

In the absence of an adopted core standard for JavaScript documentation, we follow the JSDoc3 standards.

Unit and Integration Testing back to top

At 10up, we generally employ unit and integration tests only when building applications that are meant to be distributed. Writing tests for client themes usually does not offer a huge amount of value (there are of course exceptions to this). When we do write tests, we use QUnit which is a WordPress standard.

Libraries back to top

There are many JavaScript libraries available today. Many of them directly compete with each other. We try to stay consistent with what WordPress uses. The following is a list of primary libraries used by 10up.

DOM Manipulation

jQuery - Our and WordPress's library of choice for DOM manipulation.

Utility

Underscore - Provides a number of useful utility functions such as clone(),each(), and extend(). WordPress core uses this library quite a bit.

Frameworks

Backbone - Provides a framework for building complex JavaScript applications. Backbone is based on the usage of models, views, and collections. WordPress core relies heavily on Backbone especially in the media library. Backbone requires Underscore and a DOM manipulation library (jQuery)

Performance js的更多相关文章

  1. You Don't Know JS: Scope & Closures(翻译)

    Chapter 1: What is Scope? 第一章:什么是作用域 One of the most fundamental paradigms of nearly all programming ...

  2. iOS-监听原生H5性能数据window.performance

    WebKit-WKWebView iOS8开始苹果推荐使用WKWebview作为H5开发的核心组件,以替代原有的UIWebView,以下是webkit基本介绍介绍: 介绍博客 Webkit H5 - ...

  3. 页面性能监控之performance

    页面性能监测之performance author: @TiffanysBear 最近,需要对业务上的一些性能做一些优化,比如降低首屏时间.减少核心按钮可操作时间等的一些操作:在这之前,需要建立的就是 ...

  4. Performance --- 前端性能监控

    阅读目录 一:什么是Performance? 二:使用 performance.timing 来计算值 三:前端性能如何优化? 四:Performance中方法 五:使用performane编写小工具 ...

  5. 基于HTML5实现3D热图Heatmap应用

    Heatmap热图通过众多数据点信息,汇聚成直观可视化颜色效果,热图已广泛被应用于气象预报.医疗成像.机房温度监控等行业,甚至应用于竞技体育领域的数据分析. http://www.hightopo.c ...

  6. 基于HTML5实现的Heatmap热图3D应用

    Heatmap热图通过众多数据点信息,汇聚成直观可视化颜色效果,热图已广泛被应用于气象预报.医疗成像.机房温度监控等行业,甚至应用于竞技体育领域的数据分析. 已有众多文章分享了生成Heatmap热图原 ...

  7. drupal笔记

    $app_root :网站根目录 安装 汉化:1将汉化包放置drupal8\sites\default\files\translations下安装:2极简版的话需要在extend(扩展)中安装Inte ...

  8. [React] 10 - Tutorial: router

    Ref: REACT JS TUTORIAL #6 - React Router & Intro to Single Page Apps with React JS Ref: REACT JS ...

  9. 测开之路七十六:性能测试蓝图之html

    <!-- 继承base模板 -->{% extends 'base.html' %} {% block script %} <!-- 从cdn引入ace edter的js --> ...

随机推荐

  1. ALV tree DUMP 问题处理-20180328

    Category ABAP Programming Error Runtime Errors MESSAGE_TYPE_X ABAP Program SAPLOLEA Application Comp ...

  2. 重新编写equals()方法,hashCode()方法,以及toString(),提供自定义的相等标准,以及自描述方法

    下面给出一个实例,重新编写equals()方法,提供自定义的相等标准 public class PersonTest { public static void main(String[] args) ...

  3. CCF 201312-4 有趣的数[dp][难]

    问题描述 试题编号: 201312-4 试题名称: 有趣的数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, ...

  4. pytorch rnn 2

    import torch import torch.nn as nn import numpy as np import torch.optim as optim class RNN(nn.Modul ...

  5. 手把手教 GitHub + Hexo 搭建博客

    前言 在很久以前,博主就想着要有自主的博客专栏或者网站.经历了博客园这个需要所谓的编辑审核,一直比较困惑,这些编辑是什么出身,怎么知道技术博客的价值性. 接下来找到了开源中国,这个可以自由发言的地方. ...

  6. 命令查看java的class字节码文件

    源代码: public class Math { public static void main(String[] args){ int a=1; int b=2; int c=(a+b)*10; } ...

  7. 2017 Multi-University Training Contest - Team 4 hdu6071 Lazy Running

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6071 题目: Lazy Running Time Limit: 2000/1000 MS (J ...

  8. iOS 绘制一个表盘时钟,秒针效果可以“扫秒/游走”

    最近自己 也尝试写了一个表盘时钟,初衷源于等车时候一个老奶奶问时间,我打开手机,时间数字对我来说相对敏感,但是老奶奶是看不清的,我想识别 还是看表盘 老远 看时针分针角度就可以识别当前时间. 于是我想 ...

  9. I.MX6中PC连接开发板问题

    修改板端的文件 添加登录密码: passwd  vi /etc/network/interrfaces 在auto eth0下增加auto eth1 如果采用固定ip方式可以在后面增加一段固定ip设置 ...

  10. Python面试题之Python生成器

    首先说明一下生成器也是迭代器,也有迭代器的那些优点. 那为什么要生成器呢?因为到目前为止都 不是你写的迭代器,都是别人定义好的.那如何自己去造一个迭代器呢?下面的内容就会给你答案. 想要自己造一个迭代 ...