對于前端應用來說,JS錯誤的發生直接影響前端應用的質量,因此對于JS錯誤的定位及診斷顯得尤為重要。ARMS前端監控提供的JS錯誤診斷功能可以輔助排查JS錯誤,能夠做到精準定位、快速診斷。
前提條件
前端開發人員已使用構建工具生成Source Map。您可以在
頁面的高級設置頁簽上傳Source Map文件。背景信息
實際情況中,JS錯誤診斷經常會遇到以下困難。
復現困難。
假設您的一位用戶是A,當A訪問某網頁時,該頁面會加載在A本地的瀏覽器上。由于頁面的加載耗時受地域、網絡情況、瀏覽器或者運營商等因素影響,排查問題時無法復現A在訪問頁面時的具體情況。
缺少監控信息,無法深入排查。
大部分前端監控會通過PerformanceTiming對象來獲取完整的頁面加載耗時信息,這將缺失頁面靜態資源的加載情況,導致無法深入定位性能瓶頸。
ARMS前端監控可利用Source Map還原代碼真正的錯誤位置,還可以利用用戶行為回溯功能還原JS錯誤現場。這樣使得開發者能夠迅速定位出錯的源代碼位置以及相應的代碼塊。
Source Map是一個存儲源代碼與編譯代碼對應位置映射的信息文件,便于開發人員定位上述代碼錯誤。實際上,它就是一個JSON鍵值對,利用VLQ編碼與特定的規則存儲位置信息。簡而言之,可以理解為Source Map在處理前的代碼和處理后的代碼之間搭建了一座橋梁。
在配置文件webpack.config.js中設置devtool屬性即可生成Source Map文件。
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, devtool: "source-map" // devtool有13種不同取值,對應不同類型的Source Map。建議設為source-map。 };
var gulp = require('gulp'); var sourcemaps = require('gulp-sourcemaps'); gulp.task('javascript', function() { gulp.src('src/**/*.js') .pipe(sourcemaps.init()) .pipe(sourcemaps.write('../sourcemaps')) .pipe(gulp.dest('dist')); });
如果只使用grunt-contrib-uglify壓縮打包:
grunt.initConfig({ uglify: { options: { sourceMap: true } } });
如果使用grunt-usemin壓縮打包,由于grunt-usemin會依次調用grunt-contrib-concat和grunt-contrib-uglify對源碼進行打包和壓縮:
grunt.initConfig({ concat: { options: { sourceMap: true } }, uglify: { options: { sourceMap: true, sourceMapIn: function(uglifySource) { return uglifySource + '.map'; }, } } });
module.exports = function(grunt) { grunt.loadNpmTasks('grunt-jsmin-sourcemap'); grunt.initConfig({ 'jsmin-sourcemap': { all: { src: ['scripts/script.js'], dest: 'scripts/script.jsmin-grunt.js', destMap: 'scripts/script.jsmin-grunt.js.map' } } }); grunt.registerTask('default', 'jsmin-sourcemap'); };
ng build --prod --source-map --vendor-source-map
UglifyJS2是命令行工具,執行方法如下所示。單擊查看更多source-map選項。
$ uglifyjs app.js -o app.min.js --source-map app.min.js.map
SystemJS的SystemJS構建工具。
builder.bundle('app.js', 'app-outfile.js', { minify: true, sourceMaps: true });
步驟一:安裝探針
如需全方位監控前端應用,那么您首先需要為您的前端應用安裝ARMS探針。請根據實際需求選擇一種方式來安裝探針,具體操作,請參見前端監控接入概述。
步驟二:查看錯誤總覽
- 登錄ARMS控制臺,在左側導航欄選擇 。
- 在前端列表頁面頂部選擇目標地域,然后單擊目標應用名稱。
在左側導航欄,單擊JS錯誤診斷。
通過錯誤總覽查看總的錯誤數、JS錯誤率、影響用戶數及占比。
通過曲線圖判斷JS的錯誤趨勢。
通過高頻錯誤篩選出頻繁出現的錯誤。
通過頁面錯誤率排行、錯誤分布等信息對JS錯誤有一個全局的判斷。
步驟三:診斷具體錯誤
對全局錯誤信息有一個初步的判斷后,還需要排查具體的錯誤。進入ARMS前端監控中JS錯誤診斷的異常診斷有以下兩種方式:
單擊高頻錯誤頁簽的診斷直接進入異常診斷。
在錯誤曲線圖中下鉆到某個時刻的異常洞察彈出框,再進入到異常診斷。
本文以第二種方式為例。
觀察到錯誤曲線圖中某個時刻的錯誤率突然變高,將鼠標懸浮于該曲線拐點上,當鼠標顯示為手形指針時單擊拐點,可打開該時間點的異常洞察對話框。更多信息,請參見查看異常洞察。
單擊高頻錯誤Top 5頁簽,選擇其中一條錯誤,然后單擊操作列中的診斷。
進入錯誤詳情頁面。
步驟四:查看錯誤詳情
JS錯誤詳情信息包括首次發現時間、首次發現版本(可選上報指標)、錯誤名稱、錯誤類型、錯誤時間、設備、操作系統、瀏覽器、IP、網絡制式、地區、錯誤URL、錯誤所在文件及行列信息、應用版本號等。如下圖所示,可以從錯誤詳情信息中看出是實時大屏頁面的地圖模塊在更新時報了一個數據非法的異常,錯誤發生在第1行第79585列。
步驟五:定位錯誤代碼
通過查看JS錯誤詳情得到的信息不足以診斷問題,因為線上代碼一般是經過編譯、壓縮、混淆等處理,因此您看到的JS代碼不具備可讀性。雖然知道是第1行第79585列發生了錯誤,但這并不代表是源碼的實際位置。此時,就需要用到Source Map進行源碼映射。
在堆棧信息區域,單擊一條堆棧信息左側的圖標展開該行,并單擊選擇Source Map。
在Source Map文件對話框中選擇已有Source Map文件,或上傳新的Source Map文件,并單擊確定。
說明一次最多可以上傳5個。
ARMS前端監控將利用Source Map文件還原準確的JS錯誤位置,如果選擇的Source Map能夠匹配出源碼的錯誤,則原始錯誤位置將以紅色字體標注于源代碼區域中。如下圖所示,經過解析后就可以一目了然地看出是哪個文件里面的哪一行出現錯誤。除此之外,錯誤堆棧的每一行都可以使用Source Map做源碼映射。
步驟六:查看用戶行為回溯
雖然通過Source Map源碼映射,可以看到源碼報錯是創建地圖組件時,傳入了非法的數據導致的。但非法的數據可能性有很多,上述代碼中實際已經對數據做了判空容錯處理,但依然觸發了數據非法異常。如果能對報錯時的數據做一個快照,就能更準確地定位問題。實際上在全局異常捕獲中,現場數據一般無法獲取到,只能依賴用戶主動上報時附帶數據信息。
最好的輔助排查方式就是復現,ARMS前端監控把頁面上發生的各個事件節點定義為用戶行為,包括頁面加載、路由跳轉、頁面單擊、API請求、控制臺輸出等信息,按照時間順序將用戶行為串聯起來就是用戶的行為鏈路。通過出錯時的行為回溯可以幫助開發者復現問題。
如用戶行為回溯所示,通過出錯時用戶行為回溯可以看到出錯前有一個API請求,這個API請求試圖去請求數據實時更新地圖模塊,但是返回的數據是ConsoleNeedLogin,說明此時頁面已經退出登錄狀態了,這就是導致非法數據的根源。