Javascript – 挨踢攻城獅學習之路 https://blog.cwlove.idv.tw 不太詳細紀錄 Sat, 20 May 2023 15:06:27 +0000 zh-TW hourly 1 Google Apps Script: 與 Oracle VPS JavaScript 簡易效能測試 https://blog.cwlove.idv.tw/free-gas-and-vps-js-test/ https://blog.cwlove.idv.tw/free-gas-and-vps-js-test/#respond Sun, 05 Feb 2023 15:36:05 +0000 https://blog.cwlove.idv.tw/?p=2542 Google Apps Script 運行速度不佳嗎?

一直覺得 Google Apps Script 寫出來的程式在組資料時速度不佳,直到今天想說用個簡單的測試來跑跑看…

參與的選手

  • Google Apps Script 免費
  • Oracle VPS 免費: AMD EPYC 7551 32-Core Processor 2 個 AMD 型運算 VM (各有 1/8 個 OCPU** 和 1 GB 記憶體),大概 2 核心 * 0.125 可使用
  • 我的電腦 要錢:AMD Ryzen 5 2400G

Google Apps Script 跑 for loop 塞 obj 測試

// 數值加總
function forSumTest() {
  let start = Date.now();
  let sum = 0
  for (let i = 0; i < 1000000000; i++) {
    sum += i
  }
  Logger.log(`加總值為:${sum}`)
  let end = Date.now();
  Logger.log(`Execution time: ${end - start} ms`);
}
// 1705 + 1666 + 1075 + 1598 + 1604 + 1683 + 1528 + 1459 + 1093 + 1023 = 14,434 ms
// 平均 1,443.4 ms

// obj 賦值
function forObjTest() {
  let sum = 0
  let iRound = 10
  let jRound = 100000000
  for (let i = 0; i < iRound; i++) {
    let start = Date.now();
    let obj = {}
    for (let j = 0; j < jRound; j++) {
      obj[j] = j
    }
    let end = Date.now();
    Logger.log(`Execution time: ${end - start} ms`);
    sum += end - start
  }
  Logger.log(`Avg time: ${sum / iRound} ms`);
}
// 平均 5312.3 ms

Oracle VPS Node.js 環境裝起來

安裝 nvm 工具來管理 Node.js
$ curl https://raw.githubusercontent.com/creationix/nvm/v0.39.3/install.sh | bash
$ source ~/.bash_profile 
查看有哪些版本可以安裝
$ nvm ls-remote
...
v16.19.0   (Latest LTS: Gallium)
...
v18.14.0   (Latest LTS: Hydrogen)
...
v19.6.0
裝最新的 LTS 版
$ nvm install v18.14.0
or
$ nvm install --lts
查看
$ nvm list
切換版本(如有裝其他版本)
$ nvm use v16.19
切換最新的 LTS 版本
$ nvm use --lts
設定預設版本(如有裝其他版本)
$ nvm alias default v16.19

Oracle VPS 跑 for loop 塞 obj 測試

// 數字加總
let start = Date.now();
let sum = 0
for (let i = 0; i < 1000000000; i++) {
  sum += i
}
console.log(`加總值為:${sum}`)
let end = Date.now();
console.log(`Execution time: ${end - start} ms`);
// Oracle VPS
// 3273 + 3141 + 3667 + 3197 + 3203 + 3192 + 3197 + 3183 + 3722 + 3203 = 32,978 ms
// 平均 3,297.8 ms

// obj 賦值
let sum = 0
let iRound = 10
let jRound = 100000000
for (let i = 0; i < iRound; i++) {
  let start = Date.now();
  let obj = {}
  for (let j = 0; j < jRound; j++) {
    obj[j] = j
  }
  let end = Date.now();
  console.log(`Execution time: ${end - start} ms`);
  sum += end - start
}
console.log(`Avg time: ${sum / iRound} ms`);
// JavaScript heap out of memory 炸了

AMD Ryzen5 2400G 跑 for loop 塞 obj 測試

let start = Date.now();
let sum = 0
for (let i = 0; i < 1000000000; i++) {
  sum += i
}
console.log(`加總值為:${sum}`)
let end = Date.now();
console.log(`Execution time: ${end - start} ms`);
// AMD 2400G 效能模式
// 858 + 868 + 857 + 900 + 862 + 858 + 860 + 869 + 859 + 870 = 8,661 ms
// 平均 866.1 ms

let sum = 0
let iRound = 10
let jRound = 100000000
for (let i = 0; i < iRound; i++) {
  let start = Date.now();
  let obj = {}
  for (let j = 0; j < jRound; j++) {
    obj[j] = j
  }
  let end = Date.now();
  console.log(`Execution time: ${end - start} ms`);
  sum += end - start
}
console.log(`Avg time: ${sum / iRound} ms`);
// 平均 3174.5 ms

大出意料之外,是我 Code 寫不好,錯怪他了。但發布出來的 Web App 前端在調用 GAS 不做任何邏輯直接 return 出來還是會有 700 ~ 1,000 ms 的等待 response 時間,GAS 讀試算表 400 筆資料不做任何處理要 300 ms ~ 700 ms,在初始頁面時也慢,適合寫工具就好。

Google Apps ScriptOracle VPSAMD Ryzen5 2400G
加總1,443.4 ms3,297.8 ms866.1 ms
obj 賦值5312.3 ms— 炸了 —3174.5 ms
]]>
https://blog.cwlove.idv.tw/free-gas-and-vps-js-test/feed/ 0
Tampermonkey:網頁表單自動輸入簡易相加的計算驗證碼 https://blog.cwlove.idv.tw/tampermonkey-simple-form-input-calc-add/ https://blog.cwlove.idv.tw/tampermonkey-simple-form-input-calc-add/#respond Sun, 17 Oct 2021 05:18:35 +0000 https://blog.cwlove.idv.tw/?p=2244 公司的訂便當系統登入都要輸入提示的計算相加的結果做為驗證

帳號、密碼瀏覽器會幫忙自動帶入了,但計算驗證要自己填
其實問題都是很簡單的數字相加,懶人的想寫腳本自動填入快速登入,頭次嘗鮮覺得很有趣
先分享一下網友做的 Tampermonkey 範例教學,依樣畫葫蘆寫了

// ==UserScript==
// @name         calcDinBenDon
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
//// @include      https://dinbendon.net/*
// @match        https://dinbendon.net/do/login
// @icon         https://www.google.com/s2/favicons?domain=dinbendon.net
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
     let anwser = "got Error"
     let question = document.querySelectorAll(".alignRight")[2].innerText;
     anwser = question.match(/\d+/g).map(Number).reduce((a, b) => a + b);
     document.querySelector('input[name="result"]').value = anwser
})();

很簡單的就是去抓取網頁上的字串文字,取出數字為陣列再轉換型別加總,最後填入表格內

]]>
https://blog.cwlove.idv.tw/tampermonkey-simple-form-input-calc-add/feed/ 0
Javascript:IOS 14 Safari window.open 沒有提示彈跳視窗 https://blog.cwlove.idv.tw/js-ios-14-safari-window-open/ https://blog.cwlove.idv.tw/js-ios-14-safari-window-open/#respond Thu, 04 Mar 2021 14:44:47 +0000 https://blog.cwlove.idv.tw/?p=2158 原先寫法是

this.getLink(ID).then(res => {
  window.open(res, '_blank', 'height=800,width=1050');
});

在 PC、Mobile 的 Safari、Chrome 都會顯示有彈跳視窗需允許才能打開,這沒什麼問題,允許就好
但在 IOS 14 的 Safari 連提示都沒有,只能從設定裡去動,但不可能教使用者都要去改手機設定
因此找了下解法找到這篇:window.open在Safari中不能打开的问题

改成以下寫法就解決了,可直接彈出新視窗不需按允許

var winRef = window.open('', '_blank', 'height=800,width=1050');
this.getLink(ID).then(res => (winRef.location = res));
]]>
https://blog.cwlove.idv.tw/js-ios-14-safari-window-open/feed/ 0
Javascript:關閉分頁、瀏覽器事件動作 https://blog.cwlove.idv.tw/js-event-close-tab-browser-beacon-api/ https://blog.cwlove.idv.tw/js-event-close-tab-browser-beacon-api/#respond Thu, 04 Mar 2021 14:30:09 +0000 https://blog.cwlove.idv.tw/?p=2151 網站需求要在關閉分頁、瀏覽器後,將用戶登出。因此需要
1.有個事件監聽,能在各大 PC、Mobile 瀏覽器在關閉分頁或瀏覽器後執行程式
2.該程式要能成功打 API 告知後端該用戶要登出

踩坑踩很久,先分享一下找到的文章,快速出坑

首先第一篇發送 HTTP Request 諸多方法,除了作者提到 Service Worker 本身比較麻煩,我看了文件還真是很麻煩,故沒有測
其他測過結果 Beacon API 瀏覽器相容最好,因此有此需求,請直接用它吧。

再來分享事件監聽我嘗試過下列寫法,電腦版 Safari、Chrome、Firefox、手機版 Chrome、Firefox 都能生效,
唯獨手機版 Safari 不行(IOS 版本12、14 都測過)。這網站可以測事件有無觸發,測完放棄治療IOS Safari。

// let isIOS = navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/iPhone/i);
// eventName = isIOS ? 'pagehide' : 'beforeunload'

// 電腦版 Safari 能生效
window.addEventListener('pagehide', e => this.beforeUnload()); 
// 電腦版 Safari、Chrome、Firefox 能生效
window.addEventListener('beforeunload' 或 'unload', e => this.beforeUnload());
// 手機版 Chrome、Firefox 能生效
document.addEventListener('visibilitychange', e => this.beforeUnload()); 

再來第二篇 Beacon API 照可能會碰到跨域問題,而開發環境已經設 * 還是不能跑,參考第四篇得到以下改法可以參考一下

let blog = new Blob(
  [
    JSON.stringify({
      Status: status,
      Account: account,
    }),
  ],
  // { type: 'application/json; charset=UTF-8' }
  { type: 'text/plain; charset=UTF-8' }
);

navigator.sendBeacon(
  apiHost + '/api/demoUpdateLoginStatus',
  blog
);

以上參考。

]]>
https://blog.cwlove.idv.tw/js-event-close-tab-browser-beacon-api/feed/ 0
Vue.js:已經重裝Node.js,Vue Create 仍失敗 https://blog.cwlove.idv.tw/vue-create-rejected-by-your-operating-system/ https://blog.cwlove.idv.tw/vue-create-rejected-by-your-operating-system/#respond Thu, 12 Mar 2020 05:06:56 +0000 https://blog.cwlove.idv.tw/?p=1898 Vue CLI v4.2.2,公司電腦 Create Project 時,都會跳出如下錯誤的結尾

npm ERR! The operation was rejected by your operating system.
npm ERR! It's possible that the file was already in use (by a text editor or antivirus),
npm ERR! or that you lack permissions to access it.
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

使用yarn也會跳錯,已經clean cache、更新npm、更換npm source、reboot電腦
重裝nodejs、vue、vue-cli,清除所有npm、npm-cache、刪除 .vuerc檔都無法解決
A同事也發生一樣狀況,但B同事可以成功,最後檢查到.vuerc 有差異

我的預設內容是

{
  "useTaobaoRegistry": true,
  "packageManager": "npm"
}

將 “useTaobaoRegistry” 改為 false 就可以了。

> notepad %USERPROFILE%\.vuerc
{
  "useTaobaoRegistry": false,
  "packageManager": "npm"
}
]]>
https://blog.cwlove.idv.tw/vue-create-rejected-by-your-operating-system/feed/ 0
Vue.js:解決Vuex重新整理頁面,State就被清掉問題 https://blog.cwlove.idv.tw/vue-vuex-refresh-state-session-storage/ https://blog.cwlove.idv.tw/vue-vuex-refresh-state-session-storage/#respond Thu, 05 Mar 2020 05:31:16 +0000 https://blog.cwlove.idv.tw/?p=1887 使用 Vuex 儲存使用者登入資訊時,因重新整理會導致 Vuex 狀態被清除而網頁回到登出狀態,
故要先將狀態儲存到 Session Storage,頁面載入時再取回來

來源:解決vuex重新整理頁面就恢復初始化的方法之一

       created(){
        //在頁面載入時讀取sessionStorage裡的狀態資訊
            if (sessionStorage.getItem("store") ) {
                this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store"))))
            }

            //在頁面重新整理時將vuex裡的資訊儲存到sessionStorage裡
            window.addEventListener("beforeunload",()=>{
                sessionStorage.setItem("store",JSON.stringify(this.$store.state))
            })
        },

記得登出時需要清除Session、Vuex,否則怎麼按登出資料都還在

]]>
https://blog.cwlove.idv.tw/vue-vuex-refresh-state-session-storage/feed/ 0
Vue.js:router出現 message: “Navigating to current location (XXX) is not allowed” https://blog.cwlove.idv.tw/vue-router-navigating-to-current-location-xxx-is-not-allowed/ https://blog.cwlove.idv.tw/vue-router-navigating-to-current-location-xxx-is-not-allowed/#respond Thu, 05 Mar 2020 05:24:39 +0000 https://blog.cwlove.idv.tw/?p=1885 印象是在設定使用者未登入,就導回首頁跳出以下錯誤

Navigating to current location ("/") is not allowed

解決辦法為在router.js裡加入

const routerPush = Router.prototype.push
Router.prototype.push = function push(location) {
  return routerPush.call(this, location).catch(error=> error)
}

就不會再跳錯

來源:解决vue项目路由出现message: “Navigating to current location (XXX) is not allowed”的问题

]]>
https://blog.cwlove.idv.tw/vue-router-navigating-to-current-location-xxx-is-not-allowed/feed/ 0
Vue.js:import axios報錯Cannot read property ‘protocol’ of undefined https://blog.cwlove.idv.tw/vue-import-axios-cannot-read-property-protocol-of-undefined/ https://blog.cwlove.idv.tw/vue-import-axios-cannot-read-property-protocol-of-undefined/#respond Wed, 26 Feb 2020 15:43:57 +0000 https://blog.cwlove.idv.tw/?p=1876 最近Console一直出現 Cannot read property ‘protocol’ of undefined 因為功能都正常,實在看不出什麼問題
同事就幫忙Google一下,原來是不能這樣引用

import Vue from 'vue’
import App from './App’
import router from './router’
import axios from ‘axios’

Vue.use(axios);

正解如下

import axios from 'axios';
Vue.prototype.$http = axios;

引用來源:关于import axios报错Cannot read property ‘protocol’ of undefined

]]>
https://blog.cwlove.idv.tw/vue-import-axios-cannot-read-property-protocol-of-undefined/feed/ 0
Vue.js:npm run dev 跳錯 Module build failed: TypeError: Cannot read property ‘length’ of null https://blog.cwlove.idv.tw/module-build-failed-typeerror-cannot-read-property-length-of-null/ https://blog.cwlove.idv.tw/module-build-failed-typeerror-cannot-read-property-length-of-null/#respond Sat, 15 Feb 2020 02:45:04 +0000 https://blog.cwlove.idv.tw/?p=1858 初學vue在建完專案就出錯了

npm run dev

碰到

ERROR  Failed to compile with 1 errors     10:17:50 
Module build failed: TypeError: Cannot read property 'length' of null

Google到對岸資源,看起來跟ESLint有關,暫時用這個方法解決。

npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm i [email protected]

引用自:babel eslint TypeError: Cannot read property ‘range’ of null淘宝 NPM 镜像
不是每次都會碰到,其他專案就沒這問題…

]]>
https://blog.cwlove.idv.tw/module-build-failed-typeerror-cannot-read-property-length-of-null/feed/ 0
WordPress:Elementor在IE 11、Edge踩坑2-背景圖設為固定,滑動時圖片抖動 https://blog.cwlove.idv.tw/elementor-ie11-background-image-fixed/ https://blog.cwlove.idv.tw/elementor-ie11-background-image-fixed/#respond Sat, 13 Apr 2019 15:38:46 +0000 https://blog.cwlove.idv.tw/?p=1547 Elementor將背景圖片設為固定,但IE、EDGE上下滑動時,圖會抖看的很不舒服
這段程式碼是由這裡找的:为什么在IE上滚动时固定的背景图像会移动?
雖然沒有很懂,但套用下面這段程式碼解決。

 if(navigator.userAgent.match(/Trident\/7\./)) {
    $('body').on("mousewheel", function () {
        event.preventDefault();

        var wheelDelta = event.wheelDelta;

        var currentScrollPosition = window.pageYOffset;
        window.scrollTo(0, currentScrollPosition - wheelDelta);
    });

    $('body').keydown(function (e) {

        var currentScrollPosition = window.pageYOffset;

        switch (e.which) {

            case 38: // up
                e.preventDefault(); // prevent the default action (scroll / move caret)
                window.scrollTo(0, currentScrollPosition - 120);
                break;

            case 40: // down
                e.preventDefault(); // prevent the default action (scroll / move caret)
                window.scrollTo(0, currentScrollPosition + 120);
                break;

            default: return; // exit this handler for other keys
        } 
    });
}
]]>
https://blog.cwlove.idv.tw/elementor-ie11-background-image-fixed/feed/ 0