下面大可能是從前端工程化的角度給出的優化建議,若是須要了解語法上的優化,能夠參考:css
原生 css 動畫要比 js 實現的動畫要高效不少,因此在可能的狀況下儘可能用原生 css 動畫。html
能夠參考:前端
由於第三方庫不可避免的會增大打包文件的體積,而且有不少咱們用不着的代碼和性能的損失,因此在可能的狀況下儘可能用原生 js 的 api,代替第三方庫的 api,好比 jquery、lodash、underscore、moment 等。jquery
能夠參考:webpack
有些第三方庫會比較大,若是提供單個模塊的使用方式,就儘可能使用子模塊代替使用整個包,好比 lodash、jquery-ui 等。git
以 lodash
爲例:es6
// 不推薦 import _ from 'lodash'; _.forEach(); _.defaults(); // 推薦 import forEach from 'lodash/forEach'; import defaults from 'lodash/defaults'; forEach(); defaults();
若是相同的功能能夠有多種選擇,應當儘可能使用高效的一種方案。github
好比:web
document.getElementById, document.getElementsByClassName, document.getElementsByTagName
代替 document.querySelector, document.querySelectorAll
el.innerHTML
代替 document.createElement, el.appendChild
避免無用的閉包、無用的塊做用域,儘可能是代碼結構扁平化。segmentfault
好比:
// 低效的實現 const urlParams = (() => { const params = {}; if (location.search) { location.search.slice(1).split('&').forEach(item => { const [key, value = ''] = item.split('='); urlParams[key] = value; }); } return params; })(); // 更高效的實現 const urlParams = {}; if (location.search) { location.search.slice(1).split('&').forEach(item => { const [key, value = ''] = item.split('='); urlParams[key] = value; }); }
如今 js
的模塊化主要是 commonjs
與 es6
模塊化規範,可是在開發的時候,建議是用 es6
的模塊化規範,由於 es6
的模塊化可使用 Tree Shaking
的功能。
這個功能可以在構建工具打包代碼時,對代碼進行分析,只有真正用到的代碼會被打包,沒有用到的則不會。
// one.js export const smile = {}; export const cry = []; // two.js import { smile } from './one'; export default smile;
上面的代碼以 two.js
爲入口進行打包,則 one.js
中只有 export const smile = {}
會被打包,而 export const cry = []
不會。
關於 Tree Shaking
,能夠參考:
代碼的合併與壓縮是前端的必修課,若是使用 webpack
來打包,webpack
會自動幫咱們完成,通常無需關心。
另外,在有些時候,代碼是須要作分割的,由於 webpack
會把代碼都打包到一個文件中,當這個文件很大的時候,就須要分割成多個小文件。通常建議 bundle 文件最大不超過 350k
。
對於 webpack
,能夠用 DllPlugin 或 SplitChunksPlugin 作文件分割。
對於不少應用來講,特別是 SPA 應用,有些資源是不必在首屏就加載出來的,而是等到要用的時候才加載,這就是按需加載。按需加載能夠減少首屏加載文件的體積,達到提升響應速度的目的。
// about.js export default render; // main.js document.getElementById('about').addEventListener('click', e => { import('./about').then(({default: render}) => { // 渲染頁面 render(); }); }, !1);
上面的代碼中只有當點擊了 #about
元素後,纔會加載 about.js
文件。
能夠參考:
前端性能的優化除了從語法、http 協議、工程結構方向以外,構建工具也是一個能夠優化的方向。
對於前端開發者來講,基本上都用 webpack
來打包項目,但 webpack
帶給咱們強大功能的同時,也會有一些反作用產生,就是會產生不少冗餘的代碼(若是你有查看過 webpack 的 bundle 文件,便會發現)。
若是你的項目不須要處理靜態資源(如圖片),也不須要按需加載,並追求前端高性能的話,能夠嘗試 rollup。
好比:
源代碼
# 目錄 |-- src/ |-- index.js |-- prefix.js |-- suffix.js # prefix.js const prefix = 'prefix'; export default str => `${prefix} | ${str}`; # suffix.js const suffix = 'suffix'; export default str => `${str} | ${suffix}`; # index.js import prefix from './prefix'; import suffix from './suffix'; export default str => suffix(prefix(str));
rollup
打包後的代碼:
'use strict'; const prefix = 'prefix'; var prefix$1 = str => `${prefix} | ${str}`; const suffix = 'suffix'; var suffix$1 = str => `${str} | ${suffix}`; var index = str => suffix$1(prefix$1(str)); module.exports = index;
webpack
打包後的代碼:
module.exports = /******/ (function(modules) { // webpackBootstrap /******/ /******/ 中間有 100 行代碼被省略 /******/ /******/ ]);
能夠參考:
前端性能的優化還有一個方向,就是預編譯腳本,即把本來在運行階段才解析的代碼經過工具預執行,而後只留下結果。
prepack 即是這樣的一個工具,它的思路大體是這樣:
把不依賴外部環境的邏輯提早進行運算,並把運算結果替換到相應的源碼處,而後從源碼中移除這段邏輯。
源代碼
(() => { const secondsOfOneDay = 24 * 60 * 60; window.getSecondsOfDays = days => days * secondsOfOneDay; })();
編譯後的代碼
(function () { var _$0 = this; var _1 = days => { return days * 86400; }; _$0.getSecondsOfDays = _1; }).call(this);
能夠參考:
對於前端來講,css
對性能影響比較小,因此,這裏只提一點最多見、也是最有效果的建議:選擇器不要嵌套太深。
通常建議選擇器層級在 2 級之內,最多不超過 3 級。
// 下面是 less, scss, css 語法 // 很差 .one { .two { .three { .four {} } } } // 不推薦 .one { .two { .three {} } } // 好 .one .two {} .one {}
更多博客,查看 https://github.com/senntyou/blogs
版權聲明:自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證)