Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
前端代碼Review主要關(guān)注以下幾個(gè)方面:
1、代碼質(zhì)量:代碼是否簡(jiǎn)潔、易讀、易維護(hù)。是否遵循了一致的編碼風(fēng)格和規(guī)范,例如ESLint、Prettier等。
2、功能實(shí)現(xiàn):代碼是否實(shí)現(xiàn)了預(yù)期的功能,是否有潛在的bug或邏輯錯(cuò)誤。
3、性能優(yōu)化:代碼是否進(jìn)行了必要的性能優(yōu)化,例如避免不必要的渲染、使用了合適的數(shù)據(jù)結(jié)構(gòu)和算法等。
4、安全性:代碼是否存在可能的安全風(fēng)險(xiǎn),例如XSS攻擊、CSRF攻擊等。5、可測(cè)試性:代碼是否易于測(cè)試,是否有單元測(cè)試和集成測(cè)試。
6、可讀性:代碼是否易于理解,是否有足夠的注釋和文檔。
7、可復(fù)用性:代碼是否有高度的模塊化和復(fù)用性。
8、兼容性:代碼是否兼容不同的瀏覽器和設(shè)備。
助記:功性讀復(fù)全兼測(cè)
前端代碼中一些典型的、肉眼可見(jiàn)的需要性能優(yōu)化的地方包括:
1、過(guò)度渲染:如果你的應(yīng)用在沒(méi)有必要的情況下進(jìn)行了過(guò)多的渲染,這可能會(huì)導(dǎo)致性能問(wèn)題。例如,在React中,如果你的組件在props沒(méi)有改變的情況下進(jìn)行了重新渲染,那么你可能需要使用shouldComponentUpdate/SCU或React.PureComponent或useEffect來(lái)避免不必要的渲染。
2、大量DOM操作:頻繁的DOM操作是非常耗費(fèi)性能的。如果你的代碼中有大量的DOM操作,你可能需要考慮使用虛擬DOM或其他優(yōu)化技術(shù)(例如DocumentFragment)。
3、大量的網(wǎng)絡(luò)請(qǐng)求:如果你的應(yīng)用發(fā)送了大量的網(wǎng)絡(luò)請(qǐng)求,這可能會(huì)導(dǎo)致性能問(wèn)題。你可能需要考慮使用緩存、預(yù)加載、懶加載等技術(shù)來(lái)減少網(wǎng)絡(luò)請(qǐng)求。
4、大型JavaScript文件:如果你的JavaScript文件過(guò)大,這可能會(huì)導(dǎo)致加載和解析時(shí)間過(guò)長(zhǎng)。你可能需要考慮使用代碼分割、懶加載等技術(shù)來(lái)減小文件大小。
5、未優(yōu)化的圖片和媒體文件:如果你的網(wǎng)站使用了大量的未優(yōu)化的圖片和媒體文件,這可能會(huì)導(dǎo)致加載時(shí)間過(guò)長(zhǎng)。你可能需要考慮使用圖片壓縮、適當(dāng)?shù)奈募袷健DN等技術(shù)來(lái)優(yōu)化你的媒體文件。
6、阻塞渲染的CSS和JavaScript:如果你的CSS和JavaScript阻塞了頁(yè)面的渲染,這可能會(huì)導(dǎo)致用戶體驗(yàn)不佳。你可能需要考慮使用非阻塞的加載技術(shù),如異步加載、延遲加載等。
阻塞渲染的CSS和JavaScript是一個(gè)常見(jiàn)的前端性能優(yōu)化問(wèn)題。當(dāng)瀏覽器加載網(wǎng)頁(yè)時(shí),它會(huì)按照HTML文檔的順序解析每個(gè)元素。當(dāng)遇到<link>或<script>標(biāo)簽時(shí),瀏覽器會(huì)停止HTML解析,去下載和執(zhí)行CSS或JavaScript文件,這就是所謂的“阻塞渲染”。
以下是一些優(yōu)化阻塞渲染的CSS和JavaScript的策略:
1、異步加載JavaScript:使用async屬性可以使瀏覽器異步加載JavaScript,即在下載JavaScript文件的同時(shí),瀏覽器可以繼續(xù)解析HTML。但是,這可能會(huì)導(dǎo)致JavaScript在DOM還未完全解析時(shí)就開(kāi)始執(zhí)行,因此只適用于那些不依賴DOM的JavaScript文件。
2、延遲加載JavaScript:使用defer屬性可以使瀏覽器延遲執(zhí)行JavaScript,即在DOM解析完畢后,再執(zhí)行JavaScript。這適用于那些依賴DOM的JavaScript文件。
3、內(nèi)聯(lián)關(guān)鍵CSS:將關(guān)鍵的CSS(即渲染首屏內(nèi)容所需的CSS)內(nèi)聯(lián)到HTML中,可以避免瀏覽器等待CSS文件的下載和解析。但是,這可能會(huì)增加HTML文件的大小,因此只適用于小量的CSS。
4、媒體查詢:使用媒體查詢可以讓瀏覽器只下載適用于當(dāng)前設(shè)備的CSS,從而減少不必要的下載;本質(zhì)是一種CSS的按需加載技術(shù)
以上就是優(yōu)化阻塞渲染的CSS和JavaScript的一些策略。
關(guān)注一下以下要點(diǎn):
正在review的這段代碼可復(fù)用性如何,高的話是否可以:
在前端代碼的安全性Review中,主要關(guān)注以下幾個(gè)方面:
1、跨站腳本攻擊(XSS):檢查代碼中是否正確地對(duì)用戶輸入進(jìn)行了轉(zhuǎn)義,以防止插入惡意的JavaScript代碼。例如,當(dāng)使用React時(shí),它默認(rèn)會(huì)轉(zhuǎn)義所有的用戶輸入,但如果你使用dangerouslySetInnerHTML(或Vue中的v-html),則需要特別小心。
2、跨站請(qǐng)求偽造(CSRF):檢查是否在所有的POST請(qǐng)求中使用了CSRF令牌,以防止攻擊者偽造用戶的請(qǐng)求。
3、點(diǎn)擊劫持:檢查是否使用了適當(dāng)?shù)腍TTP頭,如X-Frame-Options,來(lái)防止點(diǎn)擊劫持攻擊。
4、內(nèi)容篡改:檢查是否所有的HTTP請(qǐng)求都使用了HTTPS,以防止混合內(nèi)容問(wèn)題,這可能會(huì)導(dǎo)致用戶的數(shù)據(jù)被竊取(傳輸過(guò)程中被抓包)。
5、輸入驗(yàn)證:檢查是否在客戶端和服務(wù)器端都進(jìn)行了輸入驗(yàn)證,以防止注入攻擊,圖形或字符驗(yàn)證碼、短信驗(yàn)證、CSRF-token等的本質(zhì)都是加入隨機(jī)真人校驗(yàn)機(jī)制,狠重要!
6、敏感信息泄露:檢查代碼中是否有可能泄露敏感信息的地方,如在URL、錯(cuò)誤消息或日志中包含敏感信息。
7、依賴的安全性:檢查所有的第三方依賴是否都是最新的,是否有已知的安全漏洞。
X-Frame-Options 是一個(gè)HTTP響應(yīng)頭,用于控制網(wǎng)頁(yè)是否可以被其他網(wǎng)頁(yè)通過(guò)、或等元素嵌入。這個(gè)響應(yīng)頭的主要目的是為了防止點(diǎn)擊劫持/Clickjacking攻擊。
X-Frame-Options有三個(gè)可能的值:
1. DENY:此頁(yè)面不能被嵌入到任何其他頁(yè)面中。
2. SAMEORIGIN:只有同源的頁(yè)面(即,URL的協(xié)議、域名和端口都相同)才能嵌入此頁(yè)面。
3. ALLOW-FROM uri:只有指定的頁(yè)面可以嵌入此頁(yè)面。但是,這個(gè)值已經(jīng)被廢棄,不再被大多數(shù)現(xiàn)代瀏覽器支持。
如果沒(méi)有設(shè)置X-Frame-Options頭,或者設(shè)置的值不是上述三個(gè)值之一,那么任何頁(yè)面都可以嵌入此頁(yè)面。因此,為了防止點(diǎn)擊劫持攻擊,建議總是設(shè)置X-Frame-Options頭。
在前端代碼的兼容性Review中,主要關(guān)注以下幾個(gè)方面:
1、瀏覽器兼容性:檢查代碼是否能在所有支持的瀏覽器中正常工作。這包括檢查是否使用了某些瀏覽器可能不支持的JavaScript特性或CSS屬性,以及是否正確地使用了polyfill和前綴。
2、設(shè)備兼容性:檢查代碼是否能在所有支持的設(shè)備中正常工作,包括不同的操作系統(tǒng)、屏幕大小和分辨率。
3、響應(yīng)式設(shè)計(jì):檢查代碼是否適應(yīng)了不同的屏幕大小,包括手機(jī)、平板和桌面。
4、無(wú)障礙性:檢查代碼是否遵循了無(wú)障礙性標(biāo)準(zhǔn),如WAI-ARIA,以確保所有用戶,包括那些使用輔助技術(shù)的用戶,都能使用你的應(yīng)用。
5、國(guó)際化和本地化:檢查代碼是否支持多種語(yǔ)言和地區(qū),包括正確地使用了日期、時(shí)間和數(shù)字的格式。
6、性能:檢查代碼在低性能的設(shè)備或網(wǎng)絡(luò)環(huán)境下是否還能正常工作。
即充分考慮不同瀏覽器、不同設(shè)備、不同屏幕、不同國(guó)家、不同人群。
以上就是配置polyfill的一個(gè)示例。需要注意的是,這只是一個(gè)基本的配置,實(shí)際的配置可能會(huì)更復(fù)雜,取決于你的具體需求和環(huán)境。
在前端代碼的可測(cè)試性Review中,主要關(guān)注以下幾個(gè)方面:
1、單元測(cè)試:檢查代碼是否易于進(jìn)行單元測(cè)試。這包括檢查函數(shù)是否是純函數(shù)(即,相同的輸入總是產(chǎn)生相同的輸出,沒(méi)有副作用),以及是否避免了全局狀態(tài)。
2、集成測(cè)試:檢查代碼是否易于進(jìn)行集成測(cè)試。這包括檢查組件是否正確地使用了props和state,以及是否避免了直接操作DOM。
3、端到端測(cè)試:檢查代碼是否易于進(jìn)行端到端測(cè)試。這包括檢查頁(yè)面是否有易于定位的元素(如有特定id或data-test屬性的元素),以及是否有清晰的用戶流程。
4、測(cè)試覆蓋率:檢查代碼的測(cè)試覆蓋率是否足夠。這包括檢查是否所有的函數(shù)和分支都有對(duì)應(yīng)的測(cè)試。
5、模擬和打樁:檢查代碼是否易于進(jìn)行模擬和打樁。這包括檢查函數(shù)是否避免了直接調(diào)用復(fù)雜的依賴(如網(wǎng)絡(luò)請(qǐng)求或數(shù)據(jù)庫(kù)操作),以及是否提供了足夠的接口來(lái)替換這些依賴。
6、錯(cuò)誤處理:檢查代碼是否正確地處理了可能的錯(cuò)誤。這包括檢查是否有錯(cuò)誤處理函數(shù)或catch塊,以及是否有對(duì)應(yīng)的錯(cuò)誤測(cè)試。
1、安裝Cypress:首先,你需要在你的項(xiàng)目中安裝Cypress。你可以使用npm或yarn來(lái)安裝:
2、編寫(xiě)測(cè)試:然后,你可以在cypress/integration目錄下編寫(xiě)你的E2E測(cè)試。以下是一個(gè)簡(jiǎn)單的測(cè)試示例,它測(cè)試了用戶是否能正確地登錄:
3、運(yùn)行測(cè)試:最后,你可以使用Cypress的CLI來(lái)運(yùn)行你的測(cè)試:
這將會(huì)打開(kāi)Cypress的測(cè)試運(yùn)行器,你可以在這里選擇你要運(yùn)行的測(cè)試。
以上就是在React應(yīng)用中進(jìn)行E2E測(cè)試的基本步驟。需要注意的是,這只是一個(gè)基本的示例,實(shí)際的E2E測(cè)試可能會(huì)更復(fù)雜,包括測(cè)試更多的用戶交互和應(yīng)用狀態(tài)。
功性讀復(fù)全兼測(cè)! OVER,收工干飯!
原文鏈接:https://juejin.cn/post/7283748394601840680
者:magentaqin,騰訊前端開(kāi)發(fā)工程師
說(shuō)到 Code Review,經(jīng)常有同學(xué)會(huì)問(wèn),究竟從哪些方面下手?除了一些抽象的 Review 原則,有沒(méi)有更細(xì)化的實(shí)施準(zhǔn)則來(lái)指導(dǎo)實(shí)踐?
PCG 代碼委員會(huì)曾推出過(guò)通道晉級(jí)代碼檢查報(bào)告。筆者打算在這些報(bào)告基礎(chǔ)上,從代碼格式、代碼錯(cuò)誤、代碼習(xí)慣、代碼優(yōu)化四個(gè)角度,并結(jié)合騰訊醫(yī)典前端 Code Review 過(guò)程中遇到的一些 bad case,逐一列出更細(xì)化的實(shí)施準(zhǔn)則。希望對(duì)各位有一定的參考價(jià)值。
代碼格式問(wèn)題完全可以通過(guò)自動(dòng)化工具來(lái)解決。 標(biāo)準(zhǔn)的 eslint 規(guī)則( 如Airbnb或公司統(tǒng)一推出的eslint規(guī)則) + husky( 本地pre-commit校驗(yàn) ) + 遠(yuǎn)端 CI 流水線 eslint 校驗(yàn)(開(kāi)啟cache,增量校驗(yàn))就可以解決。
對(duì)于 SPA 應(yīng)用,用戶無(wú)需刷新瀏覽器,所以要想確保垃圾回收生效,我們需要在組件對(duì)應(yīng)生命周期里做主動(dòng)銷(xiāo)毀。
全局變量,除非你關(guān)閉窗口或者刷新頁(yè)面,才會(huì)被釋放,如果緩存大量數(shù)據(jù),很可能導(dǎo)致內(nèi)存泄露。 比如,我們之前就遇到過(guò)把 IM SDK放在全局window上,但在頁(yè)面卸載時(shí)卻沒(méi)有解除引用。
mounted () {
window.im=TWebLive.createIM({ SDKAppID });
}
解決方案:在頁(yè)面卸載時(shí)解除該全局引用。
destroyed () {
window.im=null;
}
其實(shí)該 im 實(shí)例也不需要掛在window上,直接綁定在vue實(shí)例上即可,組件銷(xiāo)毀時(shí)該實(shí)例也會(huì)銷(xiāo)毀;但沒(méi)有綁定在vue實(shí)例上的一定要主動(dòng)銷(xiāo)毀。
來(lái)看一個(gè)容易忽視的閉包引發(fā)內(nèi)存泄漏的例子。 outer函數(shù)內(nèi)部定義了兩個(gè)函數(shù): unused 和 foo。雖然inner函數(shù)中并沒(méi)有使用outer函數(shù)中的變量,但是由于unsed函數(shù)使用了outer函數(shù)的bar變量,bar也不會(huì)被釋放,所以foo相當(dāng)于隱式持有了bar。每次執(zhí)行outer,bar都會(huì)指向上一次的foo;而foo也會(huì)隱式持有bar,這樣的引用關(guān)系導(dǎo)致bar和foo都無(wú)法釋放。
let foo=null;
function outer() {
let bar=foo;
// 該函數(shù)歷史原因,調(diào)用方被注釋掉。并無(wú)調(diào)用
function unused () {
doSomething();
console.log(`unused ${bar}`)
}
// foo賦值
foo={
bigData: new Array(10000),
inner: function () {
doSomething();
}
}
}
for (let i=0; i < 1000; i++) {
outer();
}
解決方案:在 outer 執(zhí)行完畢時(shí)手動(dòng)釋放bar。這樣,隱式持有 bar 的 foo 也沒(méi)有其他變量引用,也會(huì)被回收了。
let foo=null;
function outer() {
let bar=foo;
// 該函數(shù)歷史原因,調(diào)用方被注釋掉。并無(wú)調(diào)用
function unused () {
doSomething();
console.log(`unused ${bar}`)
}
// foo賦值
foo={
bigData: new Array(10000),
inner: function () {
doSomething();
}
}
bar=null; // 手動(dòng)釋放bar
}
for (let i=0; i < 1000; i++) {
outer();
}
常見(jiàn)的情況是mounted設(shè)置了定時(shí)任務(wù),但卻沒(méi)有及時(shí)清理。
mounted () {
this.timer=setTimeout(()=> {
doSomething();
}, 300)
}
參考寫(xiě)法,頁(yè)面銷(xiāo)毀時(shí)需清理定時(shí)器:
destroyed () {
if (this.timer) {
clearTimeout(this.timer)
}
}
window/body 等事件需要解綁:
mounted() {
window.addEventListener(‘resize’, this.func)
}
beforeDestroy () {
window.removeEventListener('resize', this.func);
}
destroyed () {
this.eventBus.off()
}
拿 vue 官網(wǎng)避免內(nèi)存泄漏 的例子來(lái)看下。
v-if 指令只是控制虛擬DOM的添加和移除,但是由 Choices.js 添加的 DOM 片段并沒(méi)有被移除。
<template>
<div id="app">
<button v-if="showChoices" @click="hide">Hide</button>
<button v-if="!showChoices" @click="show">Show</button>
<div v-if="showChoices">
<select id="choices-single-default"></select>
</div>
</div>
</template>
<script>
new Vue({
el: "#app",
data: function () {
return {
showChoices: true
}
},
mounted: function () {
this.initializeChoices()
},
methods: {
initializeChoices: function () {
let list=[]
for (let i=0; i < 1000; i++) {
list.push({
label: "Item " + i,
value: i
})
}
new Choices("#choices-single-default", {
searchEnabled: true,
removeItemButton: true,
choices: list
})
},
show: function () {
this.showChoices=true
this.$nextTick(()=> {
this.initializeChoices()
})
},
hide: function () {
this.showChoices=false
}
}
})
</script>
解決辦法是在hide方法里調(diào)用 Choices.js 的API來(lái)清理DOM片段:
hide: function() {
this.choicesSelect.destroy();
}
以下是優(yōu)化前、后的 JS Heap 對(duì)比圖:
異步操作拿接口請(qǐng)求來(lái)說(shuō),大家都知道的是,使用 promise 時(shí)要有.catch 處理。但使用 async/await 時(shí),有.catch 處理的,也有try...catch處理的使用方法。這里推薦使用.catch。原因在于:
// CASE 1: 接口報(bào)錯(cuò),阻塞業(yè)務(wù)邏輯執(zhí)行
async fetchList() {
const res=await someApi().catch(error=> {
// error處理邏輯
})
if (res) {
doA();
}
}
// CASE 2: 接口報(bào)錯(cuò),不阻塞業(yè)務(wù)邏輯執(zhí)行
async fetchList() {
const res=await someApi().catch(error=> {
// error處理邏輯
})
doA();
}
// CASE 3:使用try...catch的情況
async fetchList() {
try {
const res=await someApi()
doA();
} catch (error) {
// 接口請(qǐng)求出錯(cuò) + 接口響應(yīng)成功后業(yè)務(wù)邏輯處理出錯(cuò)都會(huì)進(jìn)入catch block。需要進(jìn)一步區(qū)分錯(cuò)誤類(lèi)型
if (error.bizcode !==0 || error.retcode !==0) {
reportApiError(error)
} else {
reportBusinessError(error)
}
}
}
拿醫(yī)典3月中下旬的錯(cuò)誤日志來(lái)說(shuō),這類(lèi)錯(cuò)誤在錯(cuò)誤日志中占了1/3。
如果項(xiàng)目里已經(jīng)全量使用了Typescript,這類(lèi)錯(cuò)誤應(yīng)該都可以避免。 但如果項(xiàng)目里還存在 js 代碼,可以使用lodash.get來(lái)做空判斷,在調(diào)用函數(shù)之前要對(duì)函數(shù)做類(lèi)型判斷。
無(wú)意義的if else代碼塊,指的不僅是空的if else 代碼塊,還有只寫(xiě)了console.log 的情況。 另外,也存在條件判斷過(guò)于復(fù)雜,else情況考慮不全,導(dǎo)致邏輯沒(méi)有正常處理的情況。
// else 代碼塊里只寫(xiě)了console.log
if (a) {
} else {
console.log('something')
}
// 條件判斷過(guò)于復(fù)雜,else情況考慮不全,導(dǎo)致邏輯不能正常處理
if ((a && (b || c)) || d || (e && (f || g))) {
} else {
doSomething()
}
解決辦法: 開(kāi)啟eslint no-empty 規(guī)則,不允許有空的block。但這個(gè)插件的問(wèn)題在于,如果是無(wú)效的代碼塊,比如在else代碼塊只做了console.log操作,并不會(huì)檢測(cè)出來(lái)。 另外,較為復(fù)雜的條件判斷盡量拆成單獨(dú)的變量,并分別配上注釋說(shuō)明,這樣可以防止邏輯處理漏。
和無(wú)意義的 else 代碼塊一樣,也存在空catch代碼塊、只有console.log的catch代碼塊的情況。
// bad case
try {
doSomething();
} catch (e) {
}
// bad case
try {
doSomething();
} catch (e) {
console.log(e);
}
// bad case
somePromise().then(()=> {
doSomething()
}).catch(()=> {
})
somePromise().then(()=> {
doSomething()
}).catch((e)=> {
console.log(e)
})
為了解決這個(gè)問(wèn)題,醫(yī)典這邊做了一個(gè)eslint插件@tencent/eslint-plugin-medical,能夠檢查try catch里的catch代碼塊、promise 的catch代碼塊,是否為空,是否只有console調(diào)用。cuow當(dāng)然,有些時(shí)候,并不需要對(duì)異常邏輯進(jìn)行額外業(yè)務(wù)邏輯處理,catch里可以加一個(gè)上報(bào)。
這一步可以在流水線里接入安全風(fēng)險(xiǎn)檢測(cè)插件進(jìn)行處理。以下是醫(yī)典接入后的一個(gè)示例分析
確實(shí)存在一些誤判,比如會(huì)把mixin關(guān)鍵字當(dāng)做泄露人名來(lái)進(jìn)行告警,開(kāi)發(fā)人員可以對(duì)照分析是否需要處理。
An
前端常見(jiàn)的硬編碼場(chǎng)景有:
// 請(qǐng)求參數(shù)硬編碼
getCommentsApi({ doctorId: 1 }).then((res)=> {
doSomething()
}).catch(()=> {
handleError();
})
也出現(xiàn)過(guò)ABtest接口,開(kāi)發(fā)同學(xué)本地模擬返回對(duì)象,忘記刪除硬編碼的情況
fetchABTestApi().then((res)=> {
// res.data
const obj={
imgSrc: 'xxx',
name: 'qinmu'
}
})
接口mock的硬編碼,完全可以通過(guò)使用mock平臺(tái)來(lái)解決。推薦使用專(zhuān)業(yè)的接口管理平臺(tái)來(lái)進(jìn)行接口管理、mock等,這里我們使用的是騰訊內(nèi)部接口管理平臺(tái)tolstoy。該產(chǎn)品還未正式開(kāi)源,歡迎提前關(guān)注。
// bad case 硬編碼1001
const isActive=this.$route.query.id==='1001'
// good case 寫(xiě)到配置信息中。這樣,id和狀態(tài)的對(duì)應(yīng)關(guān)系一目了然,便于管理和維護(hù)。
const idConfig={
1001: STATUS.ACTIVE
}
const isActive=idConfig[this.$route.query.id]===STATUS.ACTIVE
輸入框的校驗(yàn)規(guī)則除了滿足產(chǎn)品需求,比如多少字符以內(nèi)、允許哪些字符,還有一個(gè)點(diǎn):前后端需要校驗(yàn)規(guī)則保持一致。最好用統(tǒng)一的正則表達(dá)式,不然容易造成前端校驗(yàn)通過(guò)、后端校驗(yàn)不通過(guò)的情況。
上傳文件,前后端需求校驗(yàn)文件格式、文件大小。尤其是后端,需要對(duì) content-type 為 text/html 的加以限制,防止出現(xiàn)安全問(wèn)題。我們已經(jīng)有過(guò)此類(lèi)安全問(wèn)題的工單了。
拒絕面條代碼,減少代碼中各種結(jié)構(gòu)的嵌套,例如 if-else、try-catch、循環(huán)等。盡量控制在三層以內(nèi),增加可讀性、降低圈層復(fù)雜度。 你肯定不愿意維護(hù)這樣辣眼睛的代碼:
async getConfig(id, type='', isReset=false) {
try {
if (liveid) {
const res=await someApi(id);
if (res && res.info) {
const { status }=res.info
status===2 && doA({id, type});
if (status===1 || status===2 || status===4) {
this.setData({
info: res.info,
status,
})
if (isReset) {
this.setData({
current: 0,
index: 0
})
status===2 && doB();
}
return { code: 0};
}
return doC();
} else if (isReset) {
resetSomething();
} else if (isReset && type===someType) {
handleType();
}
return wx.showModal({ //... })
}
} catch (error) {
if (error.code===1001) {
reportA();
} else {
reportB();
doD();
}
}
}
邏輯相同或相似的代碼,應(yīng)封裝為函數(shù)進(jìn)行調(diào)用。
// bad case 都有展示modal的邏輯,開(kāi)發(fā)同學(xué)直接復(fù)制粘貼
function handleA(msg) {
wx.showModal({
title: '提示',
content: msg,
showCancel: false,
confirmText: '確定',
confirmColor: '#02BACC',
success: (res)=> {
if (res.confirm) {
doA();
}
},
});
}
function handleB(msg) {
wx.showModal({
title: '提示',
content: msg,
showCancel: false,
confirmText: '確定',
confirmColor: '#02BACC',
success: (res)=> {
if (res.confirm) {
doB();
}
},
});
}
function handleC(msg) {
wx.showModal({
title: '提示',
content: msg,
showCancel: false,
confirmText: '確定',
confirmColor: '#02BACC',
success: (res)=> {
if (res.confirm) {
doC();
}
},
});
}
解決方案,封裝showModal函數(shù)。
function showModal (msg) {
return new Promise((resolve, reject)=> {
wx.showModal({
title: '提示',
content: msg,
showCancel: false,
confirmText: '確定',
confirmColor: '#02BACC',
success: (res)=> {
if (res.confirm) resolve()
},
fail: (err)=> {
reject(err)
}
})
})
}
funtion handleA(msg) {
showModal(msg).then(
doA();
).catch(()=> { catchHandler();})
}
funtion handleB(msg) {
showModal(msg).then(
doB();
).catch(()=> { catchHandler();})
}
funtion handleC(msg) {
showModal(msg).then(
doC();
).catch(()=> { catchHandler();})
}
在Object.prototype上定義方法就相當(dāng)于C++里定義宏, 而且還是 #define private public 這種。 從可靠性來(lái)說(shuō),多人協(xié)作很容易出現(xiàn)沖突。 從兼容性來(lái)說(shuō),你不能保證后續(xù)推出的原生方法實(shí)現(xiàn)和你現(xiàn)有的一致,也不能保證多個(gè)庫(kù)之間對(duì)該方法的實(shí)現(xiàn)一致。比較有名的故事是 prototype庫(kù)的getElementsByClassName。在還沒(méi)有這個(gè)原生方法之前,prototype這個(gè)庫(kù)實(shí)現(xiàn)的是返回Array,并且加了“each”方法:document.getElementsByClassName('myclass').each(doSomething);但原生方法出來(lái)后,返回的是NodeList,并沒(méi)有each方法;所以就悲劇了。 詳細(xì)說(shuō)明可以看:Nicholas C. Zakas 的 Maintainable JavaScript: Don’t modify objects you don’t own
減少回調(diào)的嵌套,避免產(chǎn)生callback hell:
fs.readdir(source, function (err, files) {
if (err) {
console.log('Error finding files: ' + err)
} else {
files.forEach(function (filename, fileIndex) {
console.log(filename)
gm(source + filename).size(function (err, values) {
if (err) {
console.log('Error identifying file size: ' + err)
} else {
console.log(filename + ' : ' + values)
aspect=(values.width / values.height)
widths.forEach(function (width, widthIndex) {
height=Math.round(width / aspect)
console.log('resizing ' + filename + 'to ' + height + 'x' + height)
this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
if (err) console.log('Error writing file: ' + err)
})
}.bind(this))
}
})
})
}
})
建議使用promise、async/await 的方式讓代碼更為清晰可讀;也可以將callback要做的事拆成獨(dú)立的function,并分別對(duì)err進(jìn)行處理。
函數(shù)盡量精簡(jiǎn)在80行以內(nèi),并且以小function進(jìn)行組織,方便維護(hù)、復(fù)用。
除了知道下面的邏輯是在繪制canvas,其他邏輯你能看懂嗎?
function doSomething() {
let count;
if ((count=width * height / 1000000) > 1) {
count=~~(Math.sqrt(count) + 1);
const nw=~~(width / count);
const nh=~~(height / count);
const tCanvas=document.createElement('canvas');
const tctx=tCanvas.getContext('2d');
tCanvas.width=nw;
tCanvas.height=nh;
for (let i=0; i < count; i++) {
for (let j=0; j < count; j++) {
tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
}
}
} else {
ctx.drawImage(img, 0, 0, width, height);
}
}
常用的注釋分類(lèi)有這些,建議參考 JSDoc:
1)文件注釋
2)變量注釋
3)常量注釋
4)函數(shù)注釋
5)枚舉注釋
6)類(lèi)的注釋
7)類(lèi)的屬性注釋
這一條在團(tuán)隊(duì)里是出現(xiàn)過(guò)現(xiàn)網(wǎng)bug的。
故事背景是開(kāi)發(fā)M在重構(gòu)代碼時(shí),設(shè)置底部欄狀態(tài)這一邏輯已經(jīng)封裝出來(lái),所以根據(jù)注釋?zhuān)旅鎺仔写a做的事情也是設(shè)置底部欄狀態(tài),開(kāi)發(fā)M就把這幾行代碼都刪掉了。但是注釋下面的代碼,除了做設(shè)置底部欄狀態(tài)的事情,還有一個(gè)setBanner 函數(shù),是為了設(shè)置banner位的,也被連同刪掉,進(jìn)而導(dǎo)致了bug。
追溯原因,設(shè)置底部欄狀態(tài)是A同學(xué)做的,設(shè)置 banner 位是B同學(xué)做的,B同學(xué)在沒(méi)有看注釋的情況下,直接把setBanner放在了錯(cuò)誤的位置上。
function fetchData() {
// ...
doManythings();
// 設(shè)置底部欄狀態(tài)
setBanner();
fetchStatusApi().then(res=> {
// ...
}).catch(()=> {
// ...
})
}
git的版本管理能幫我們回溯之前的代碼。如果項(xiàng)目里存在大量注釋掉的代碼,會(huì)降低可讀性。
雖然console.log調(diào)試日志在生產(chǎn)環(huán)境構(gòu)建時(shí)不會(huì)輸出,但就本地開(kāi)發(fā)環(huán)境來(lái)說(shuō),代碼里慘雜過(guò)多console.log調(diào)試日志,控制臺(tái)滿屏的調(diào)試日志,對(duì)于每個(gè)接手的開(kāi)發(fā)都是噩夢(mèng)。另外,就像上面說(shuō)的一樣,catch處理或else分支里存在只打console.log而不做任何處理的情況。盡量避免少使用console.log,也可以減少這類(lèi)意外的發(fā)生。
所以,日常開(kāi)發(fā)調(diào)試建議使用瀏覽器sources tab的斷點(diǎn)調(diào)試;另外,就算要輸出調(diào)試日志,也不止有console.log可以使用,參考這篇文章。你可以使用console.table等來(lái)格式化輸出
我能想到的允許 eslint-disable的場(chǎng)景只有一種,那就是解構(gòu)后端返回對(duì)象。后端返回對(duì)象屬性名是下劃線,這個(gè)時(shí)候可能需要 // eslint-disable-next-line camelcase。其他情況我都不建議使用 eslint-disable,尤其是整個(gè)文件全局eslint-disable。
之前遇到過(guò)某文件全局禁用"no-undef"規(guī)則,結(jié)果代碼里使用了未定義的變量,導(dǎo)致現(xiàn)網(wǎng)bug。如果你有全局定義的變量,建議寫(xiě)在eslintrc.js的globals字段里。當(dāng)然,就正如上文代碼錯(cuò)誤-內(nèi)存泄露提到的一樣,非必要情況,不建議使用全局變量。
為了增強(qiáng)可讀性,建議使用空行對(duì)代碼分組。
常見(jiàn)的不規(guī)范命名有這些,會(huì)讓之后維護(hù)的同學(xué)很懵逼:
// bad case 1
function doctor () {}
// bad case 2
computed: {
getUserInfo() {}
}
// bad case 3
close=false;
同學(xué),就不能好好寫(xiě)代碼嗎?
// good case 1
function getDoctorInfo() {}
// good case 2
computed: {
getUserInfo() {}
}
// good case 3
closed=false
如果在業(yè)務(wù)邏輯里摻雜太多的上報(bào),后續(xù)理解業(yè)務(wù)邏輯時(shí)需要看上報(bào)邏輯,查上報(bào)邏輯的時(shí)候也需要理解大量的業(yè)務(wù)代碼。 點(diǎn)擊埋點(diǎn)和曝光埋點(diǎn)都可以以屬性的形式掛在元素上,通過(guò)冒泡,統(tǒng)一進(jìn)行處理。
<button
data-exposurename="test-exposure"
:data-exposureval="{event:'bottom.btn'} | jsonStringify"
data-eventname="button.click"
:data-eventval="{id: buttonId} | jsonStringify"
/>
如果你上報(bào)的參數(shù)需要根據(jù)不同渠道來(lái)配置,建議封裝出來(lái),不要和業(yè)務(wù)邏輯耦合了。
除了項(xiàng)目的READMD,每個(gè)模塊都應(yīng)該有各自的README,說(shuō)明這個(gè)模塊的功能點(diǎn)、技術(shù)實(shí)現(xiàn)方案等。看個(gè)人習(xí)慣,你也可以寫(xiě)在iwiki里,在README放一個(gè)iwiki的鏈接。
export default 有兩個(gè)問(wèn)題: 1)不利于tree shaking 2)如果使用了一個(gè)導(dǎo)出對(duì)象上不存在的屬性,要運(yùn)行時(shí)才能發(fā)現(xiàn)。
直接操作DOM的性能損耗至少有兩個(gè)地方:進(jìn)行DOM操作的時(shí)候上下文切換 + DOM操作引起的頁(yè)面重繪
delete 操作符并不會(huì)釋放內(nèi)存,而且會(huì)使得附加到對(duì)象上的hidden class失效,讓對(duì)象變成slow object。 (hidden class是V8為了優(yōu)化屬性訪問(wèn)時(shí)間而創(chuàng)建的隱藏類(lèi)) 來(lái)看一下執(zhí)行速度對(duì)比:undefined > delete > omit 。
比如做一個(gè)簡(jiǎn)單圖表的需求,不選輕量的庫(kù),非要整一個(gè)echarts;或者實(shí)現(xiàn)一個(gè)簡(jiǎn)單的代碼編輯器,monaco-editor有min版本不使用,非要引用一整個(gè)monaco-editor。還有,lodash沒(méi)法做tree-shaking,要么引用一個(gè)具體的子包lodash.get,要么引用lodash-es,非要引用一整個(gè)lodash。
如果代碼里引用的是本地圖片,構(gòu)建打包會(huì)有耗時(shí)。可以在引用之前就把圖片傳到cdn上,代碼里直接使用cdn地址。
以上就是CR的細(xì)則了。
手都寫(xiě)麻了。當(dāng)然,肯定還有很多遺漏的點(diǎn),歡迎補(bǔ)充。
信圍觀的讀者不是初來(lái)乍到的小白,在這里不多贅述亞馬遜review的歷史變遷以及重要性。一段時(shí)間以來(lái)我們集中處理amazon review問(wèn)題,時(shí)至今日有了亞馬遜測(cè)評(píng)系統(tǒng)(以下簡(jiǎn)稱(chēng)系統(tǒng))也有了一些明確思路。一路走來(lái),也參加了市面上大大小小的review課程,但這些review攻略偏灰色,不成體系。今天的終極攻略希望能從亞馬遜review的整體布局思路和具體方法上給予讀者一定的啟發(fā)和幫助。通過(guò)本篇文章,你將獲得:
1.亞馬遜review維護(hù)全局框架
2.多渠道多策略建立亞馬遜測(cè)評(píng)體系
3.不同補(bǔ)評(píng)(測(cè)評(píng))策略時(shí)效性,安全性,可持續(xù)性以及成本對(duì)比分析
4.真人測(cè)評(píng)與刷單上評(píng)的識(shí)別與開(kāi)發(fā)
5.新品LISTING安全快速補(bǔ)評(píng)方法
6.如何通過(guò)自動(dòng)化補(bǔ)評(píng)規(guī)則提高評(píng)價(jià)維護(hù)效率
溫馨提示:
為了避諱一些敏感字眼,賓果博客內(nèi)定義所有人為干預(yù)的上評(píng)行為均稱(chēng)為補(bǔ)評(píng),所有人為干預(yù)的出單行為均稱(chēng)為補(bǔ)單
影響亞馬遜關(guān)鍵詞排名因素千千萬(wàn),相關(guān)性、轉(zhuǎn)化率與用戶反饋(review)至關(guān)重要。在review方面(本文不講轉(zhuǎn)化率):新品,我們希望短時(shí)間內(nèi)有足夠高質(zhì)量和足夠數(shù)量的review上線,既是為了在新品扶持期內(nèi)加快新品推廣進(jìn)展,也是為了規(guī)避差評(píng)風(fēng)險(xiǎn)。老品,我們希望零差評(píng)的同時(shí)每個(gè)月都有成比例的好評(píng)上線。滿懷期待,但有時(shí)卻力不從心,把以下四項(xiàng)策略堅(jiān)持執(zhí)行到位即可解決亞馬遜review中的90%的問(wèn)題:
1.亞馬遜review差評(píng)預(yù)防
在產(chǎn)品Listing的評(píng)分里,1個(gè)差評(píng)可以抹掉5個(gè)好評(píng),換句話說(shuō)5個(gè)好評(píng)只可以抹掉1個(gè)差評(píng)。對(duì)很多從事亞馬遜運(yùn)營(yíng)的賣(mài)家來(lái)說(shuō),差評(píng)本身不易移除,這將會(huì)對(duì)抵抗力不強(qiáng)的LISTING銷(xiāo)量帶來(lái)毀滅性打擊。亞馬遜review差評(píng)的危害巨大,一定是以預(yù)防為主。
2.亞馬遜review差評(píng)移除
兵來(lái)將擋,水來(lái)土掩。差評(píng)來(lái)了也莫怕,據(jù)相關(guān)經(jīng)驗(yàn),亞馬遜review差評(píng)有30%-50%移除的概率,當(dāng)然有很多深圳大賣(mài)能做到50%或更高。
3.亞馬遜測(cè)評(píng)(快速補(bǔ)評(píng))
今天的一個(gè)重頭戲,相信也是各位讀者最想了解的一部分。本文將從時(shí)效性.安全性.可持續(xù)性以及成本四個(gè)維度展開(kāi)不同測(cè)評(píng)渠道的講解。前期建議以服務(wù)商的真人測(cè)評(píng)放單為主,同時(shí)快速建立起自己的測(cè)評(píng)體系。等體系建立后,用自己的方法更安全。
4.自動(dòng)化補(bǔ)評(píng)規(guī)則
我們需要更高的測(cè)評(píng)效率,不僅僅是打通測(cè)評(píng)渠道更要建立自動(dòng)化的測(cè)評(píng)管理。在不人為干預(yù)的情況下,評(píng)價(jià)維護(hù)負(fù)責(zé)人即使不懂亞馬遜運(yùn)營(yíng)也明白什么時(shí)間該對(duì)什么產(chǎn)品補(bǔ)評(píng)了,哪些產(chǎn)品需要優(yōu)先處理等等。這對(duì)多賬戶多Listing操作的賣(mài)家有很大幫助。
接下來(lái)從策略到方法,從方法到執(zhí)行,一步步分解亞馬遜review維護(hù)。
亞馬遜review差評(píng)預(yù)防攻略
1.采購(gòu)端
第一,明確質(zhì)檢方向讓懂產(chǎn)品的人做質(zhì)檢工作。特別注意的一點(diǎn)是應(yīng)考慮產(chǎn)品在亞馬遜上經(jīng)常遇到的差評(píng)內(nèi)容,讓懂產(chǎn)品的人做有針對(duì)性的質(zhì)檢工作。第二,100%質(zhì)檢。按照亞馬遜0.5%-1%的留評(píng)率計(jì)算,如果100件商品內(nèi)有1件的瑕疵品,意味著所有的自然留評(píng)全是差評(píng),夠恐怖吧。但傳統(tǒng)大貿(mào)環(huán)境下,工廠都是習(xí)慣進(jìn)行抽檢工作,很難保證0.5%內(nèi)的瑕疵率。所以當(dāng)從事亞馬遜B2C電商與工廠打交道時(shí),務(wù)必確認(rèn)100%的質(zhì)檢率。哪怕每件多付1元的質(zhì)檢費(fèi)用,也要保證不出現(xiàn)因?yàn)樯唐焚|(zhì)量瑕疵帶來(lái)的差評(píng)。
案例:2018年4月上架了一批魚(yú)竿產(chǎn)品,通過(guò)推廣陸陸續(xù)續(xù)有了穩(wěn)定的訂單。時(shí)間進(jìn)入5月,接連出現(xiàn)差評(píng)和退貨,處理差評(píng)和上評(píng)的速度跟不上差評(píng)的速度(那時(shí)也沒(méi)有一套完整評(píng)價(jià)維護(hù)體系),結(jié)果可想而知。后來(lái)找到原因:本批次魚(yú)竿采用了分體輪座的技術(shù),好處是讓魚(yú)竿更輕但是因?yàn)檩喿煮w很容易導(dǎo)致漁輪和輪座卡不緊。魚(yú)竿體積比較大,沒(méi)經(jīng)過(guò)自己的倉(cāng)庫(kù)直接運(yùn)輸?shù)礁劭诔鲐洠己鲆暳速|(zhì)檢。
2.銷(xiāo)售端
文案嚴(yán)謹(jǐn),說(shuō)明注意事項(xiàng)。文案描述不要夸大產(chǎn)品,避免因與用戶期望值不符帶來(lái)的差評(píng)。同時(shí)更要描述清楚產(chǎn)品的適用范圍、適用人群,注意事項(xiàng),避免誤解誤用帶來(lái)的差評(píng)。
案例:一段時(shí)間發(fā)現(xiàn)有些客戶反映某些魚(yú)竿的輪座和他們的漁輪不適配。后來(lái)發(fā)現(xiàn):原來(lái)是文案和圖片描述說(shuō)本產(chǎn)品適用于多種漁輪,一是給用戶的錯(cuò)覺(jué)是適用于所有漁輪,至少適用于他手中的漁輪。二是,既然提出魚(yú)竿漁輪適配情況卻未給出嚴(yán)謹(jǐn)?shù)谋磉_(dá)。所以當(dāng)用戶用不上自己的漁輪時(shí),心情很不爽。
3.客服端
如果前面1&2沒(méi)有做到位,還有差評(píng)預(yù)防的補(bǔ)救措施:在用戶很不爽的時(shí)候第一時(shí)間能找到最簡(jiǎn)單快捷的發(fā)泄渠道。而作者認(rèn)為感謝卡,產(chǎn)品以及包裝上的聯(lián)系方式最為方便客戶聯(lián)系到你,這樣用戶就會(huì)聯(lián)系你發(fā)泄不滿代替登錄后臺(tái)留差評(píng)。用了這個(gè)方法后,在ins或者facebook上陸陸續(xù)續(xù)接到了客戶的一些不滿反饋,極大降低了留差評(píng)的可能性,不僅如此通過(guò)提供解決方案還得到了用戶的認(rèn)可,愿意留好評(píng)!
總結(jié):能把差評(píng)堵在萌芽中,省心省錢(qián)!差評(píng)預(yù)防中,細(xì)節(jié)即大事!
亞馬遜review差評(píng)移除攻略
在review差評(píng)移除中可以很好的用“快,準(zhǔn),狠”三個(gè)字形容:出現(xiàn)差評(píng)反應(yīng)要快,移除方法切入點(diǎn)要準(zhǔn),雙管齊下力道要狠。那么如何做到快速反應(yīng),切入要害,雙管齊下呢,我們首先看一下差評(píng)移除的幾個(gè)重要方法:服務(wù)商移除,溝通移除,亞馬遜移除。
1.服務(wù)商移除
服務(wù)商移除差評(píng)作者很少用,一是因?yàn)闇贤ㄒ瞥蛠嗰R遜移除的效果還可以,二是因?yàn)橘M(fèi)用高,三是因?yàn)楦鱾€(gè)服務(wù)商移除差評(píng)的方法層出不窮自己沒(méi)法控制過(guò)程風(fēng)險(xiǎn)比較高。之所以在這里提出,是給到大家一個(gè)應(yīng)急的方法:既然出來(lái)做差評(píng)服務(wù),我想在時(shí)效上和成功率上應(yīng)該都不錯(cuò)。當(dāng)差評(píng)嚴(yán)重影響自己的時(shí)候可以考慮使用。
2.溝通移除 (此方法本身不難,難點(diǎn)在時(shí)間節(jié)點(diǎn)控制和郵件內(nèi)容)
溝通移除是指獲取用戶真實(shí)郵箱后,通過(guò)幫助解決問(wèn)題或者給予一定補(bǔ)償?shù)玫接脩粽徑夂驼J(rèn)可,繼而要求刪掉/修改差評(píng)的過(guò)程。
@節(jié)點(diǎn)1.記錄所留差評(píng),記錄時(shí)間。力保第一時(shí)間發(fā)現(xiàn)差評(píng),快速獲取真實(shí)郵箱。
@節(jié)點(diǎn)2.記錄真實(shí)郵箱,記錄獲取的時(shí)間。市面上有很多獲取真實(shí)郵箱的途徑,15-25元不等。2個(gè)工作日內(nèi)獲取郵箱,不要拖太久。
@節(jié)點(diǎn)3.發(fā)送郵件聯(lián)系,記錄發(fā)送時(shí)間。獲取郵箱后,按照制定好的標(biāo)準(zhǔn)郵件內(nèi)容發(fā)送。
@節(jié)點(diǎn)4.獲得客戶反饋,記錄反饋時(shí)間 。到此步,收到反饋進(jìn)入下一步。經(jīng)常收不到反饋需要考慮重新編輯郵件內(nèi)容,偶爾收不到反饋考慮用戶可能沒(méi)有看到郵件,在跟一封“Friendly reminder”
@節(jié)點(diǎn)5.根據(jù)郵件要求,給予問(wèn)題解決或給予補(bǔ)償操作。
@節(jié)點(diǎn)6.按用戶要求完成后,用戶自己知道要?jiǎng)h除評(píng)價(jià)。
除時(shí)間節(jié)點(diǎn)跟蹤好外,此方法最有技術(shù)含量的是節(jié)點(diǎn)3的郵件內(nèi)容。做好郵件內(nèi)容的要點(diǎn),一是郵件主旨內(nèi)容(直奔主題就好):愿意為review做出補(bǔ)償。這一點(diǎn)非常重要。只要用戶回復(fù),意味著用戶默許了你的建議,只要做了補(bǔ)償,用戶就得處理差評(píng)。二是補(bǔ)償建議:必須有方案,給到用戶A與B的選擇,要知道用戶是沒(méi)時(shí)間給你瞎掰的,除非你的產(chǎn)品貨值很高。三是郵件Title:能不能打開(kāi)你的郵件,就看你的TITLE用不用心了。通過(guò)以上幾點(diǎn)反復(fù)斟酌自己的郵件內(nèi)容,一定會(huì)事半功倍。
3.亞馬遜移除(此方法難點(diǎn)在找準(zhǔn)切入點(diǎn))
亞馬遜有review留評(píng)的明確條文,凡是不符合亞馬遜規(guī)則的評(píng)價(jià)都將予以刪除,并不允許在此LISTING再次留評(píng)。我們要做的是合理利用亞馬遜規(guī)則,向亞馬遜客服提出所處理差評(píng)的不合理性。鏈接www.amazon*com/gp/help/customer/display.html?nodeId=201929730是亞馬遜review的一些規(guī)則,空了可以細(xì)細(xì)品讀。根據(jù)以上規(guī)則和實(shí)戰(zhàn)經(jīng)驗(yàn)總結(jié)如下:
@規(guī)則1.review與feedback混淆。review僅是涉及物流客服包裝等服務(wù)方面的內(nèi)容。
@規(guī)則2.含誹謗,騷擾,威脅,煽動(dòng)性,淫穢,色情或猥褻內(nèi)容
@規(guī)則3.含個(gè)人隱私內(nèi)容
@規(guī)則4:含促銷(xiāo)內(nèi)容
@規(guī)則5:差評(píng)專(zhuān)業(yè)戶留評(píng)
@規(guī)則6:內(nèi)容積極但星級(jí)是差評(píng)
…………..
找準(zhǔn)切入點(diǎn)后有3處提交入口;1是Report Abuse , 2是后臺(tái)幫助中的amazon review板塊 ,3是community-help*amazon.com.為了達(dá)到更好的效果,溝通移除與亞馬遜移除同步進(jìn)行,雙管齊下,收效更好!
本章亞馬遜review維護(hù)攻略梳理到這里,下個(gè)章節(jié)將詳述市面上主流的亞馬遜測(cè)評(píng)渠道補(bǔ)評(píng)方法并從時(shí)效性、安全性、可持續(xù)性和費(fèi)用四個(gè)維度進(jìn)行分析,最后帶給大家如何建立快速補(bǔ)評(píng)自動(dòng)化規(guī)則。
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。