前端關於性能優化的9大策略和6大指標


平時大家認為性能優化是一種無序的應用場景,但在我看來它是一種有序的應用場景且很多性能優化都是互相鋪墊甚至一帶一路。從過程趨勢來看,性能優化可分為網絡層面渲染層面;從結果趨勢來看,性能優化可分為時間層面體積層面。簡單來說就是要在訪問網站時使其快准狠地立馬呈現在用戶眼前

性能優化.png

所有的性能優化都圍繞着兩大層面兩小層面實現,核心層面是網絡層面渲染層面,輔助層面是時間層面體積層面,而輔助層面則充滿在核心層面里。於是筆者通過本文整理出關於前端性能優化九大策略六大指標。當然這些策略指標都是筆者自己定義,方便通過某種方式為性能優化做一些規范。

因此在工作或面試時結合這些特征就能完美地詮釋性能優化所延伸出來的知識了。前方高能,不看也得收藏,走起!!!

所有代碼示例為了凸顯主題,只展示核心配置代碼,其他配置並未補上,請自行腦補
復制代碼

九大策略

網絡層面

網絡層面的性能優化,無疑是如何讓資源體積更小加載更快,因此筆者從以下四方面做出建議。

  • 構建策略:基於構建工具(Webpack/Rollup/Parcel/Esbuild/Vite/Gulp)
  • 圖像策略:基於圖像類型(JPG/PNG/SVG/WebP/Base64)
  • 分發策略:基於內容分發網絡(CDN)
  • 緩存策略:基於瀏覽器緩存(強緩存/協商緩存)

上述四方面都是一步接着一步完成,充滿在整個項目流程里。構建策略圖像策略處於開發階段,分發策略緩存策略處於生產階段,因此在每個階段都可檢查是否按順序接入上述策略。通過這種方式就能最大限度增加性能優化應用場景。

構建策略

該策略主要圍繞webpack做相關處理,同時也是接入最普遍的性能優化策略。其他構建工具的處理也是大同小異,可能只是配置上不一致。說到webpack性能優化,無疑是從時間層面體積層面入手。

筆者發現目前webpack v5整體兼容性還不是特別好,某些功能配合第三方工具可能出現問題,故暫未升級到v5,繼續使用v4作為生產工具,故以下配置均基於v4,但總體與v5的配置出入不大
復制代碼

筆者對兩層面分別做出6個性能優化建議總共12個性能優化建議,為了方便記憶均使用四字詞語概括,方便大家消化。⏱表示減少打包時間,📦表示減少打包體積

  • 減少打包時間縮減范圍緩存副本定向搜索提前構建並行構建可視結構
  • 減少打包體積分割代碼搖樹優化動態墊片按需加載作用提升壓縮資源

⏱縮減范圍

配置include/exclude縮小Loader對文件的搜索范圍,好處是避免不必要的轉譯node_modules目錄的體積這么大,那得增加多少時間成本去檢索所有文件啊?

include/exclude通常在各大Loader里配置,src目錄通常作為源碼目錄,可做如下處理。當然include/exclude可根據實際情況修改。

export default { // ... module: { rules: [{ exclude: /node_modules/, include: /src/, test: /\.js$/, use: "babel-loader" }] } }; 

⏱緩存副本

配置cache緩存Loader對文件的編譯副本,好處是再次編譯時只編譯修改過的文件。未修改過的文件干嘛要隨着修改過的文件重新編譯呢?

大部分Loader/Plugin都會提供一個可使用編譯緩存的選項,通常包含cache字眼。以babel-loadereslint-webpack-plugin為例。

import EslintPlugin from "eslint-webpack-plugin"; export default { // ... module: { rules: [{ // ... test: /\.js$/, use: [{ loader: "babel-loader", options: { cacheDirectory: true } }] }] }, plugins: [ new EslintPlugin({ cache: true }) ] }; 

⏱定向搜索

配置resolve提高文件的搜索速度,好處是定向指定必須文件路徑。若某些第三方庫以常規形式引入可能報錯或希望程序自動索引特定類型文件都可通過該方式解決。

alias映射模塊路徑,extensions表明文件后綴,noParse過濾無依賴文件。通常配置aliasextensions就足夠。

export default { // ... resolve: { alias: { "#": AbsPath(""), // 根目錄快捷方式 "@": AbsPath("src"), // src目錄快捷方式 swiper: "swiper/js/swiper.min.js" }, // 模塊導入快捷方式 extensions: [".js", ".ts", ".jsx", ".tsx", ".json", ".vue"] // import路徑時文件可省略后綴名 } }; 

⏱提前構建

配置DllPlugin將第三方依賴提前打包,好處是將DLL與業務代碼完全分離且每次只構建業務代碼。這是一個古老配置,在webpack v2時已存在,不過現在webpack v4+已不推薦使用該配置,因為其版本迭代帶來的性能提升足以忽略DllPlugin所帶來的效益。

DLL意為動態鏈接庫,指一個包含可由多個程序同時使用的代碼庫。在前端領域里可認為是另類緩存的存在,它把公共代碼打包為DLL文件並存到硬盤里,再次打包時動態鏈接DLL文件就無需再次打包那些公共代碼,從而提升構建速度,減少打包時間。

配置DLL總體來說相比其他配置復雜,配置流程可大致分為三步。

首先告知構建腳本哪些依賴做成DLL並生成DLL文件DLL映射表文件

import { DefinePlugin, DllPlugin } from "webpack"; export default { // ... entry: { vendor: ["react", "react-dom", "react-router-dom"] }, mode: "production", optimization: { splitChunks: { cacheGroups: { vendor: { chunks: "all", name: "vendor", test: /node_modules/ } } } }, output: { filename: "[name].dll.js", // 輸出路徑和文件名稱 library: "[name]", // 全局變量名稱:其他模塊會從此變量上獲取里面模塊 path: AbsPath("dist/static") // 輸出目錄路徑 }, plugins: [ new DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") // DLL模式下覆蓋生產環境成開發環境(啟動第三方依賴調試模式) }), new DllPlugin({ name: "[name]", // 全局變量名稱:減小搜索范圍,與output.library結合使用 path: AbsPath("dist/static/[name]-manifest.json") // 輸出目錄路徑 }) ] }; 

然后在package.json里配置執行腳本且每次構建前首先執行該腳本打包出DLL文件

{
    "scripts": { "dll": "webpack --config webpack.dll.js" } } 

最后鏈接DLL文件並告知webpack可命中的DLL文件讓其自行讀取。使用html-webpack-tags-plugin在打包時自動插入DLL文件

import { DllReferencePlugin } from "webpack"; import HtmlTagsPlugin from "html-webpack-tags-plugin"; export default { // ... plugins: [ // ... new DllReferencePlugin({ manifest: AbsPath("dist/static/vendor-manifest.json") // manifest文件路徑 }), new HtmlTagsPlugin({ append: false, // 在生成資源后插入 publicPath: "/", // 使用公共路徑 tags: ["static/vendor.dll.js"] // 資源路徑 }) ] }; 

為了那幾秒鍾的時間成本,筆者建議配置上較好。當然也可使用autodll-webpack-plugin代替手動配置。

⏱並行構建

配置Thread將Loader單進程轉換為多進程,好處是釋放CPU多核並發的優勢。在使用webpack構建項目時會有大量文件需解析和處理,構建過程是計算密集型的操作,隨着文件增多會使構建過程變得越慢。

運行在Node里的webpack是單線程模型,簡單來說就是webpack待處理的任務需一件件處理,不能同一時刻處理多件任務。

文件讀寫計算操作無法避免,能不能讓webpack同一時刻處理多個任務,發揮多核CPU電腦的威力以提升構建速度呢?thread-loader來幫你,根據CPU個數開啟線程。

在此需注意一個問題,若項目文件不算多就不要使用該性能優化建議,畢竟開啟多個線程也會存在性能開銷。

import Os from "os"; export default { // ... module: { rules: [{ // ... test: /\.js$/, use: [{ loader: "thread-loader", options: { workers: Os.cpus().length } }, { loader: "babel-loader", options: { cacheDirectory: true } }] }] } }; 

⏱可視結構

配置BundleAnalyzer分析打包文件結構,好處是找出導致體積過大的原因。從而通過分析原因得出優化方案減少構建時間。BundleAnalyzerwebpack官方插件,可直觀分析打包文件的模塊組成部分、模塊體積占比、模塊包含關系、模塊依賴關系、文件是否重復、壓縮體積對比等可視化數據。

可使用webpack-bundle-analyzer配置,有了它,我們就能快速找到相關問題。

import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer"; export default { // ... plugins: [ // ... BundleAnalyzerPlugin() ] }; 復制代碼

📦分割代碼

分割各個模塊代碼,提取相同部分代碼,好處是減少重復代碼的出現頻率webpack v4使用splitChunks替代CommonsChunksPlugin實現代碼分割。

splitChunks配置較多,詳情可參考官網,在此筆者貼上常用配置。

export default { // ... optimization: { runtimeChunk: { name: "manifest" }, // 抽離WebpackRuntime函數 splitChunks: { cacheGroups: { common: { minChunks: 2, name: "common", priority: 5, reuseExistingChunk: true, // 重用已存在代碼塊 test: AbsPath("src") }, vendor: { chunks: "initial", // 代碼分割類型 name: "vendor", // 代碼塊名稱 priority: 10, // 優先級 test: /node_modules/ // 校驗文件正則表達式 } }, // 緩存組 chunks: "all" // 代碼分割類型:all全部模塊,async異步模塊,initial入口模塊 } // 代碼塊分割 } }; 

📦搖樹優化

刪除項目中未被引用代碼,好處是移除重復代碼和未使用代碼搖樹優化首次出現於rollup,是rollup的核心概念,后來在webpack v2里借鑒過來使用。

搖樹優化只對ESM規范生效,對其他模塊規范失效。搖樹優化針對靜態結構分析,只有import/export才能提供靜態的導入/導出功能。因此在編寫業務代碼時必須使用ESM規范才能讓搖樹優化移除重復代碼和未使用代碼。

webpack里只需將打包環境設置成生產環境就能讓搖樹優化生效,同時業務代碼使用ESM規范編寫,使用import導入模塊,使用export導出模塊。

export default { // ... mode: "production" }; 

📦動態墊片

通過墊片服務根據UA返回當前瀏覽器代碼墊片,好處是無需將繁重的代碼墊片打包進去。每次構建都配置@babel/preset-envcore-js根據某些需求將Polyfill打包進來,這無疑又為代碼體積增加了貢獻。

@babel/preset-env提供的useBuiltIns可按需導入Polyfill

  • false:無視target.browsers將所有Polyfill加載進來
  • entry:根據target.browsers將部分Polyfill加載進來(僅引入有瀏覽器不支持的Polyfill,需在入口文件import "core-js/stable")
  • usage:根據target.browsers和檢測代碼里ES6的使用情況將部分Polyfill加載進來(無需在入口文件import "core-js/stable")

在此推薦大家使用動態墊片動態墊片可根據瀏覽器UserAgent返回當前瀏覽器Polyfill,其思路是根據瀏覽器的UserAgentbrowserlist查找出當前瀏覽器哪些特性缺乏支持從而返回這些特性的Polyfill。對這方面感興趣的同學可參考polyfill-librarypolyfill-service的源碼。

在此提供兩個動態墊片服務,可在不同瀏覽器里點擊以下鏈接看看輸出不同的Polyfill。相信IExplore還是最多Polyfill的,它自豪地說:我就是我,不一樣的煙火

使用html-webpack-tags-plugin在打包時自動插入動態墊片

import HtmlTagsPlugin from "html-webpack-tags-plugin"; export default { plugins: [ new HtmlTagsPlugin({ append: false, // 在生成資源后插入 publicPath: false, // 使用公共路徑 tags: ["https://polyfill.alicdn.com/polyfill.min.js"] // 資源路徑 }) ] }; 

📦按需加載

將路由頁面/觸發性功能單獨打包為一個文件,使用時才加載,好處是減輕首屏渲染的負擔。因為項目功能越多其打包體積越大,導致首屏渲染速度越慢。

首屏渲染時只需對應JS代碼而無需其他JS代碼,所以可使用按需加載webpack v4提供模塊按需切割加載功能,配合import()可做到首屏渲染減包的效果,從而加快首屏渲染速度。只有當觸發某些功能時才會加載當前功能的JS代碼

webpack v4提供魔術注解命名切割模塊,若無注解則切割出來的模塊無法分辨出屬於哪個業務模塊,所以一般都是一個業務模塊共用一個切割模塊的注解名稱。

const Login = () => import( /* webpackChunkName: "login" */ "../../views/login"); const Logon = () => import( /* webpackChunkName: "logon" */ "../../views/logon"); 復制代碼

運行起來控制台可能會報錯,在package.jsonbabel相關配置里接入@babel/plugin-syntax-dynamic-import即可。

{
    // ... "babel": { // ... "plugins": [ // ... "@babel/plugin-syntax-dynamic-import" ] } } 

📦作用提升

分析模塊間依賴關系,把打包好的模塊合並到一個函數中,好處是減少函數聲明和內存花銷作用提升首次出現於rollup,是rollup的核心概念,后來在webpack v3里借鑒過來使用。

在未開啟作用提升前,構建后的代碼會存在大量函數閉包。由於模塊依賴,通過webpack打包后會轉換成IIFE,大量函數閉包包裹代碼會導致打包體積增大(模塊越多越明顯)。在運行代碼時創建的函數作用域變多,從而導致更大的內存開銷。

在開啟作用提升后,構建后的代碼會按照引入順序放到一個函數作用域里,通過適當重命名某些變量以防止變量名沖突,從而減少函數聲明和內存花銷。

webpack里只需將打包環境設置成生產環境就能讓作用提升生效,或顯式設置concatenateModules

export default { // ... mode: "production" }; // 顯式設置 export default { // ... optimization: { // ... concatenateModules: true } }; 

📦壓縮資源

壓縮HTML/CSS/JS代碼,壓縮字體/圖像/音頻/視頻,好處是更有效減少打包體積。極致地優化代碼都有可能不及優化一個資源文件的體積更有效。

針對HTML代碼,使用html-webpack-plugin開啟壓縮功能。

import HtmlPlugin from "html-webpack-plugin"; export default { // ... plugins: [ // ... HtmlPlugin({ // ... minify: { collapseWhitespace: true, removeComments: true } // 壓縮HTML }) ] }; 

針對CSS/JS代碼,分別使用以下插件開啟壓縮功能。其中OptimizeCss基於cssnano封裝,UglifyjsTerser都是webpack官方插件,同時需注意壓縮JS代碼需區分ES5ES6

import OptimizeCssAssetsPlugin from "optimize-css-assets-webpack-plugin"; import TerserPlugin from "terser-webpack-plugin"; import UglifyjsPlugin from "uglifyjs-webpack-plugin"; const compressOpts = type => ({ cache: true, // 緩存文件 parallel: true, // 並行處理 [`${type}Options`]: { beautify: false, compress: { drop_console: true } } // 壓縮配置 }); const compressCss = new OptimizeCssAssetsPlugin({ cssProcessorOptions: { autoprefixer: { remove: false }, // 設置autoprefixer保留過時樣式 safe: true // 避免cssnano重新計算z-index } }); const compressJs = USE_ES6 ? new TerserPlugin(compressOpts("terser")) : new UglifyjsPlugin(compressOpts("uglify")); export default { // ... optimization: { // ... minimizer: [compressCss, compressJs] // 代碼壓縮 } }; 

針對字體/音頻/視頻文件,還真沒相關Plugin供我們使用,就只能拜托大家在發布項目到生產服前使用對應的壓縮工具處理了。針對圖像文件,大部分Loader/Plugin封裝時均使用了某些圖像處理工具,而這些工具的某些功能又托管在國外服務器里,所以導致經常安裝失敗。具體解決方式可回看筆者曾經發布的《聊聊NPM鏡像那些險象環生的坑》一文尋求答案。

鑒於此,筆者花了一點小技巧開發了一個Plugin用於配合webpack壓縮圖像,詳情請參考tinyimg-webpack-plugin

import TinyimgPlugin from "tinyimg-webpack-plugin"; export default { // ... plugins: [ // ... TinyimgPlugin() ] }; 

上述構建策略都集成到筆者開源的bruce-cli里,它是一個React/Vue應用自動化構建腳手架,其零配置開箱即用的優點非常適合入門級、初中級、快速開發項目的前端同學使用,還可通過創建brucerc.js文件覆蓋其默認配置,只需專注業務代碼的編寫無需關注構建代碼的編寫,讓項目結構更簡潔。詳情請戳這里,使用時記得查看文檔,支持一個Star哈!

圖像策略

該策略主要圍繞圖像類型做相關處理,同時也是接入成本較低的性能優化策略。只需做到以下兩點即可。

  • 圖像選型:了解所有圖像類型的特點及其何種應用場景最合適
  • 圖像壓縮:在部署到生產環境前使用工具或腳本對其壓縮處理

圖像選型一定要知道每種圖像類型的體積/質量/兼容/請求/壓縮/透明/場景等參數相對值,這樣才能迅速做出判斷在何種場景使用何種類型的圖像。

類型 體積 質量 兼容 請求 壓縮 透明 場景
JPG 有損 不支持 背景圖、輪播圖、色彩豐富圖
PNG 無損 支持 圖標、透明圖
SVG 無損 支持 圖標、矢量圖
WebP 兼備 支持 看兼容情況
Base64 看情況 無損 支持 圖標

圖像壓縮可在上述構建策略-壓縮資源里完成,也可自行使用工具完成。由於現在大部分webpack圖像壓縮工具不是安裝失敗就是各種環境問題(你懂的),所以筆者還是推薦在發布項目到生產服前使用圖像壓縮工具處理,這樣運行穩定也不會增加打包時間。

好用的圖像壓縮工具無非就是以下幾個,若有更好用的工具麻煩在評論里補充喔!

工具 開源 收費 API 免費體驗
QuickPicture ✖️ ✔️ ✖️ 可壓縮類型較多,壓縮質感較好,有體積限制,有數量限制
ShrinkMe ✖️ ✖️ ✖️ 可壓縮類型較多,壓縮質感一般,無數量限制,有體積限制
Squoosh ✔️ ✖️ ✔️ 可壓縮類型較少,壓縮質感一般,無數量限制,有體積限制
TinyJpg ✖️ ✔️ ✔️ 可壓縮類型較少,壓縮質感很好,有數量限制,有體積限制
TinyPng ✖️ ✔️ ✔️ 可壓縮類型較少,壓縮質感很好,有數量限制,有體積限制
Zhitu ✖️ ✖️ ✖️ 可壓縮類型一般,壓縮質感一般,有數量限制,有體積限制

若不想在網站里來回拖動圖像文件,可使用筆者開源的圖像批處理工具img-master代替,不僅有壓縮功能,還有分組功能、標記功能和變換功能。目前筆者負責的全部項目都使用該工具處理,一直用一直爽!

圖像策略也許處理一張圖像就能完爆所有構建策略,因此是一種很廉價但極有效的性能優化策略

分發策略

該策略主要圍繞內容分發網絡做相關處理,同時也是接入成本較高的性能優化策略,需足夠資金支持。

雖然接入成本較高,但大部分企業都會購買一些CDN服務器,所以在部署的事情上就不用過分擔憂,盡管使用就好。該策略盡量遵循以下兩點就能發揮CDN最大作用。

  • 所有靜態資源走CDN:開發階段確定哪些文件屬於靜態資源
  • 把靜態資源與主頁面置於不同域名下:避免請求帶上Cookie

內容分發網絡簡稱CDN,指一組分布在各地存儲數據副本並可根據就近原則滿足數據請求的服務器。其核心特征是緩存回源,緩存是把資源復制到CDN服務器里,回源是資源過期/不存在就向上層服務器請求並復制到CDN服務器里。

使用CDN可降低網絡擁塞,提高用戶訪問響應速度和命中率。構建在現有網絡基礎上的智能虛擬網絡,依靠部署在各地服務器,通過中心平台的調度、負載均衡、內容分發等功能模塊,使用戶就近獲取所需資源,這就是CDN的終極使命。

基於CDN就近原則所帶來的優點,可將網站所有靜態資源全部部署到CDN服務器里。那靜態資源包括哪些文件?通常來說就是無需服務器產生計算就能得到的資源,例如不常變化的樣式文件腳本文件多媒體文件(字體/圖像/音頻/視頻)等。

若需單獨配置CDN服務器,可考慮阿里雲OSS網易樹帆NOS七牛雲Kodo,當然配置起來還需購買該產品對應的CDN服務。由於篇幅問題,這些配置在購買后會有相關教程,可自行體會,在此就不再敘述了。

筆者推薦大家首選網易樹帆NOS,畢竟對自家產品還是挺有信心的,不小心給自家產品打了個小廣告了,哈哈!

緩存策略

該策略主要圍繞瀏覽器緩存做相關處理,同時也使接入成本最低的性能優化策略。其顯著減少網絡傳輸所帶來的損耗,提升網頁訪問速度,是一種很值得使用的性能優化策略

通過下圖可知,為了讓瀏覽器緩存發揮最大作用,該策略盡量遵循以下五點就能發揮瀏覽器緩存最大作用。

  • 考慮拒絕一切緩存策略Cache-Control:no-store
  • 考慮資源是否每次向服務器請求Cache-Control:no-cache
  • 考慮資源是否被代理服務器緩存Cache-Control:public/private
  • 考慮資源過期時間Expires:t/Cache-Control:max-age=t,s-maxage=t
  • 考慮協商緩存Last-Modified/Etag

緩存判斷機制

同時瀏覽器緩存也是高頻面試題之一,筆者覺得上述涉及到的名詞在不同語序串聯下也能完全理解才能真正弄懂瀏覽器緩存性能優化里起到的作用。

緩存策略通過設置HTTP報文實現,在形式上分為強緩存/強制緩存協商緩存/對比緩存。為了方便對比,筆者將某些細節使用圖例展示,相信你有更好的理解。

強緩存.png

協商緩存.png

整個緩存策略機制很明了,先走強緩存,若命中失敗才走協商緩存。若命中強緩存,直接使用強緩存;若未命中強緩存,發送請求到服務器檢查是否命中協商緩存;若命中協商緩存,服務器返回304通知瀏覽器使用本地緩存,否則返回最新資源

有兩種較常用的應用場景值得使用緩存策略一試,當然更多應用場景都可根據項目需求制定。

  • 頻繁變動資源:設置Cache-Control:no-cache,使瀏覽器每次都發送請求到服務器,配合Last-Modified/ETag驗證資源是否有效
  • 不常變化資源:設置Cache-Control:max-age=31536000,對文件名哈希處理,當代碼修改后生成新的文件名,當HTML文件引入文件名發生改變才會下載最新文件

渲染層面

渲染層面的性能優化,無疑是如何讓代碼解析更好執行更快。因此筆者從以下五方面做出建議。

  • CSS策略:基於CSS規則
  • DOM策略:基於DOM操作
  • 阻塞策略:基於腳本加載
  • 回流重繪策略:基於回流重繪
  • 異步更新策略:基於異步更新

上述五方面都是編寫代碼時完成,充滿在整個項目流程的開發階段里。因此在開發階段需時刻注意以下涉及到的每一點,養成良好的開發習慣,性能優化也自然而然被使用上了。

渲染層面性能優化更多表現在編碼細節上,而並非實體代碼。簡單來說就是遵循某些編碼規則,才能將渲染層面性能優化發揮到最大作用。

回流重繪策略渲染層面性能優化里占比較重,也是最常規的性能優化之一。上年筆者發布的掘金小冊《玩轉CSS的藝術之美》使用一整章講解回流重繪,本章已開通試讀,更多細節請戳這里

CSS策略
  • 避免出現超過三層的嵌套規則
  • 避免為ID選擇器添加多余選擇器
  • 避免使用標簽選擇器代替類選擇器
  • 避免使用通配選擇器,只對目標節點聲明規則
  • 避免重復匹配重復定義,關注可繼承屬性
DOM策略
  • 緩存DOM計算屬性
  • 避免過多DOM操作
  • 使用DOMFragment緩存批量化DOM操作
阻塞策略
  • 腳本與DOM/其它腳本的依賴關系很強:對<script>設置defer
  • 腳本與DOM/其它腳本的依賴關系不強:對<script>設置async
回流重繪策略
  • 緩存DOM計算屬性
  • 使用類合並樣式,避免逐條改變樣式
  • 使用display控制DOM顯隱,將DOM離線化
異步更新策略
  • 異步任務中修改DOM時把其包裝成微任務

六大指標

筆者根據性能優化的重要性和實際性划分出九大策略六大指標,其實它們都是一條條活生生的性能優化建議。有些性能優化建議接不接入影響都不大,因此筆者將九大策略定位高於六大指標。針對九大策略還是建議在開發階段和生產階段接入,在項目復盤時可將六大指標的條條框框根據實際應用場景接入。

六大指標基本囊括大部分性能優化細節,可作為九大策略的補充。筆者根據每條性能優化建議的特征將指標划分為以下六方面。

  • 加載優化:資源在加載時可做的性能優化
  • 執行優化:資源在執行時可做的性能優化
  • 渲染優化:資源在渲染時可做的性能優化
  • 樣式優化:樣式在編碼時可做的性能優化
  • 腳本優化:腳本在編碼時可做的性能優化
  • V8引擎優化:針對V8引擎特征可做的性能優化
加載優化

六大指標-加載優化.png

執行優化

六大指標-執行優化.png

渲染優化

六大指標-渲染優化.png

樣式優化

六大指標-樣式優化.png

腳本優化

六大指標-腳本優化.png

V8引擎優化

六大指標-V8引擎優化.png

總結

性能優化作為老生常談的知識,必然會在工作或面試時遇上。很多時候不是想到某條性能優化建議就去做或答,而是要對這方面有一個整體認知,知道為何這樣設計,這樣設計的目的能達到什么效果。

性能優化不是通過一篇文章就能全部講完,若詳細去講可能要寫兩本書的篇幅才能講完。本文能到給大家的就是一個方向一種態度,學以致用唄,希望閱讀完本文會對你有所幫助。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM