//tips
//smart contract
useEffectを使う時、実行中のプログラムが確保したメモリ領域の解放を忘れたまま放置してしまうこと。 これにより擬似的にメモリ領域がいっぱいの状況になってバグの元になる。
Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
サーバからResponseが来る時間が長くなり、その間にコンポーネントがUnmountされた(画面でそのcomponentを使用しなくなった)とした場合、コンポーネントは消えたが、依然としてRequestは待機中で、Responseが来たら、setPostにpostデータをセットすることになる。
これを避けるためにlet isMounted = trueをfetch前に設定し、その後にreturnでfalseにすれば良さそう。
.then(results => {
if (isMounted) {
setMedium(results)
}
}
)
return () => {
isMounted = false
}
[id]内のmediumの表示の部分でエラーが生じているのでそちらの対処。
if(mymedium){
for(var i=0; i <= mymedium.items.length-1; i++){
ここのlengthが読み込めないというもの。
mymediumがない段階で読み込まれている可能性がある。
if(!mymedium===undefined&&!mymedium===null){
こちらにて解決。
遷移時の重さを解消するために認証状態の変化通知を一旦コメントアウト。
// onAuthStateChanged(auth,(user)=>{
// console.log('user status changed:',user)
// })
やはり[id]表示が遅い。
コンソールログを見てみるとmedium部分でエラーが出ており、カードが表示されなくなっている。
Mediumが読み込みを遅くしている問題なのか特定するために一旦medium箇所はコメントアウト。
遷移の遅さは変わらない。twitterの読み込みyoutube読み込み以外にも他にも下記のエラーが出ていたので確認。
[Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive. See
これはスクロールジャンクというスマホ操作などで画面のスクロールが指の動きについてこない現象を指しているよう。
スマホ側では、イベント関数を実行する際、スクロールを止める処理(preventDefault())をいれるようで、登録されたタッチイベントの中にpreventDefault()がないかをチェックし、無いことが確認できてからスクロールを開始する仕様になっているためpreventDefault()が確認できない場合スクロールが開始できないため処理が詰まるとのこと。
https://blog.jxck.io/entries/2016-06-09/passive-event-listeners.html
handleでe.preventDefault()を入れていないところに下記を挿入。
document.addEventListener('touchstart', handler, {passive: true});
これでもwarning表示は変わらない。
単純に重すぎてスクロールにラグが出るということなのかもしれない。
こちらはコンテンツ組み込みの問題なので先にmediumの方を処理する。
for(var i=0; i <= mymedium.items.length-1; i++){
がエラーとなるのはfetchで取得したものが
status: "error"
となっているからのように思われる。
遡っていくとベースとなるninjaからの
if(Item.mediumid !=null||Item.mediumid !=undefined){
if(medi==undefined||medi==null){
setMedi(Item.mediumid)
console.log(Item.mediumid)
console.log('medi'+medi)
console.log('0000'+medi)
}
console.log(Item.mediumid)はNakithemagicで渡されいる一方でmediはundefinedになっている。
const [medi, setMedi] = useState();はきちんと存在している。
setMedi(Item.mediumid)での反映がconsole.log('0000'+medi)などではキャッチされないことがわかった。
このmediへのstate格納前に
{medi && (
<div>
<Grid item xs={12} md={6} lg={4} >
<Medium medi={medi}/>
</Grid>
</div>
)}
が呼ばれていることが問題かと思い{medi!=undefined && (としたがこれでもエラー。
<Medium medi={medi} 側でmediをきちんと引き渡されているか確認。ここで無事に引き渡しができていることが確認できた。
つまり、問題となっているのは.then(results => setMedium(results))できちんとMedium側で格納が行われていないこと。
きちんと機能するmediumurlも取得できている。
先にログで抽出状況を確認する。
.then(results => console.log(results))
//.then(results => setMedium(results))
Cannot download this RSS feed, make sure the Rss URL is correct.
ログの掃き出しが確認できない。一方でurlからはjsonが確認できる。
前後のログで下記の2つが発生している。
[Violation] 'requestAnimationFrame' handler took 54ms
GET https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/@Nakithemagic 500
上記はanimationFrameなのでtwitterやYouTube関連。
https://stackoverflow.com/questions/41218507/violation-long-running-javascript-task-took-xx-ms
下が500 Internal Server Errorでmediumjson取得できない直接の原因となっている。
https://knowledge.cpi.ad.jp/other/281/
500のエラーの詳細が知りたいので、
.then(results => {
if (results.ok) {
console.log(results)
}}
)
.catch(error => {
console.error('通信に失敗しました', error);
});
を実行してみる。
昨日まで表示は確認できていたのでパソコン負荷の問題か、chromeブラウザの更新などが問題か。
if(medi!=undefined||medi!=null){
const feed_url = "https://medium.com/feed/@"+medi;
console.log(feed_url)
fetch(
//'https://api.rss2json.com/v1/api.json?rss_url='+feed_url, {
`https://api.rss2json.com/v1/api.json?rss_url=${feed_url}`, {
headers:
{
'accept': 'application/json'
}
})
.then(res => res.json())
.then(results => {
if( !results.ok ) {
console.log(results.status)
console.log(results.statusText)
}
if (results.ok) {
setMedium(results)
}}
)
.then(() => console.log('resultsssss'))
//.then(results => setMedium(results))
}
}, [])
Chrome更新したり、パソコン再起動など色々するもダメなので、設計自体を変更するか考える。
まずLoginしてからのTOP→[id]→editの遷移の遅さが異常なため、youtubeの表示を一旦無くしてどうなるか観測してみる。
YouTubeを一旦無くしてみてもmediumの情報が取れないのは変わらない。
下記の取得urlをブラウザに入れてみると{"status":"error","message":"Cannot download this RSS feed, make sure the Rss URL is correct.”}が出てきた。
https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/@Nakithemagic
mediumがapiについて何かを変えたため従来のもので取れなくなったことに気づいた。勘弁してくれ。
https://api.rss2json.com/v1/api.json?が使えなくなっているのが原因のよう。
他の取り方を調べる。
https://api.medium.com/v1/users/Nakithemagic/publications
としてみると{"errors":[{"message":"An access token is required.","code":6000}]}、アクセストークンが必要と返ってきた。
この辺りでauthのトークンを都度入れてもらうのは面倒なのでrss2jsonのようなものがいい。
検索しても使えなくなったという情報は出回っていない。rss2jsonがサーバー攻撃を受けてサービスをストップしているかもしれないので一旦保留にしておく。
軽くする前にLoadingの際に進行状態を知りたいのでそれらがわかる仕組みを組み込む。
https://zenn.dev/yusugomori/articles/51e63a4aa9dc27e21124
https://stackoverflow.com/questions/68118383/next-js-loading-screen-while-the-dom-is-rendeing
https://qiita.com/onikan/items/98983d296fa16cf947de
また、どの処理にどれくらいの時間がかかっているかを調べたい。スクリプト単位ではわかるようだが、メソッド単位の計測はなさそうか。
https://nextjs-ja-translation-docs.vercel.app/docs/advanced-features/measuring-performance
https://t-yng.jp/post/nextjs-perf-improvement
時間がかかっているのはPassive event listenersのviolationが問題なのではないか。ここの該当箇所が分かる方法も探してみる。
その前にe.preventDefault();を全て入れてみるか。全部のイベント関数に入れてみてもまだ表示される。
https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
https://chromestatus.com/feature/5745543795965952
Twitter箇所とYouTube箇所を消して表示を行ってみたがページの表示時間がさほど変わらなかった。
要因は別にありそう。データベースのほうか、それともstateの数が関係しているのか。
Imageの部分をコメントアウトで試す。そこまで変わらないか。
むしろ通常ページに遷移させてみて、遷移時の問題かどうかを確認してみるか。
<Button variant="outlined" sx={{ fontSize: 25 }} onClick={()=>router.push('Create')}>遷移チェック</Button>
こちらでチェックしたところ問題なく通常ページには遷移できた。
試しに[id]のreturn内部の大部分をコメントアウトしてみる。1.5秒ぐらい変わったか。ただ、大部分は関数の処理部分に時間を使ってそう。