diff --git a/editors/demo/src/Editoria/Editoria.js b/editors/demo/src/Editoria/Editoria.js
index 077d263caea7521a03fd5b9736ec17576c2fe699..e35f93c22ab3676f47c63ca8835efee49858f7f3 100644
--- a/editors/demo/src/Editoria/Editoria.js
+++ b/editors/demo/src/Editoria/Editoria.js
@@ -53,9 +53,9 @@ const Editoria = () => {
           value={demo}
           // readonly
           layout={layout}
-          onChange={debounce(source => {
-            console.log(source);
-          }, 200)}
+          // onChange={debounce(source => {
+          //   console.log(source);
+          // }, 200)}
           user={user}
           scrollMargin={200}
           scrollThreshold={200}
diff --git a/editors/demo/src/Editoria/config/config.js b/editors/demo/src/Editoria/config/config.js
index 1e0f83172e663ee599a6670a6727187af72b90fd..a7e8ea8a66a8aab1c05d250640879a33d6978db2 100644
--- a/editors/demo/src/Editoria/config/config.js
+++ b/editors/demo/src/Editoria/config/config.js
@@ -184,6 +184,8 @@ export default {
   },
   CommentsService: {
     // showTitle: true,
+    readOnlyPost: false,
+    readOnlyResolve: false,
     getComments,
     setComments,
     getMentionedUsers: (users, text) => {
@@ -211,7 +213,7 @@ export default {
   //   // eslint-disable-next-line no-restricted-globals
   //   connectionUrl: 'ws://localhost:5010',
   //   // connectionUrl: 'ws://0.tcp.ap.ngrok.io:17607',
-  //   docIdentifier: 'prosemirror-r5dw4q2fe2eedreeeeeweewwewerc',
+  //   docIdentifier: 'prosemirror-r5dw4dd5eeee344w22rq254werc',
   //   YjsType: 'prosemirror',
   // },
 
diff --git a/wax-prosemirror-services/src/CommentsService/components/ConnectedComment.js b/wax-prosemirror-services/src/CommentsService/components/ConnectedComment.js
index f4a8d6c4badb7ad89f5d53f4494ff9c7cf25dafa..2abab2df7d17c72bd12fc007ec13f29c1bb86792 100644
--- a/wax-prosemirror-services/src/CommentsService/components/ConnectedComment.js
+++ b/wax-prosemirror-services/src/CommentsService/components/ConnectedComment.js
@@ -51,8 +51,14 @@ export default ({
   };
 
   const commentConfig = app.config.get('config.CommentsService');
-  const isReadOnly =
-    commentConfig && commentConfig.readOnly ? commentConfig.readOnly : false;
+  const isReadOnlyResolve =
+    commentConfig && commentConfig.readOnlyResolve
+      ? commentConfig.readOnlyResolve
+      : false;
+  const isReadOnlyPost =
+    commentConfig && commentConfig.readOnlyPost
+      ? commentConfig.readOnlyPost
+      : false;
   const showTitle =
     commentConfig && commentConfig.showTitle ? commentConfig.showTitle : false;
   const usersMentionList =
@@ -170,7 +176,8 @@ export default ({
           active={isActive}
           commentData={conversation}
           commentId={commentId}
-          isReadOnly={isReadOnly}
+          isReadOnlyPost={isReadOnlyPost}
+          isReadOnlyResolve={isReadOnlyResolve}
           key={commentId}
           onClickBox={onClickBox}
           onClickPost={onClickPost}
diff --git a/wax-prosemirror-services/src/CommentsService/components/RightArea.js b/wax-prosemirror-services/src/CommentsService/components/RightArea.js
index b6a492f7cac960178ea6173a62c0f812a6fd0dbc..69d596b0dc75a546d227f463856c8c3dc6a2a1a0 100644
--- a/wax-prosemirror-services/src/CommentsService/components/RightArea.js
+++ b/wax-prosemirror-services/src/CommentsService/components/RightArea.js
@@ -1,3 +1,4 @@
+/* eslint-disable no-unused-expressions */
 /* eslint-disable no-param-reassign */
 /* eslint react/prop-types: 0 */
 import React, { useContext, useState, useMemo, useCallback } from 'react';
@@ -24,157 +25,131 @@ export default ({ area, users }) => {
   const trakChangePlugin = app.PmPlugins.get('trackChangePlugin');
 
   const [marksNodes, setMarksNodes] = useState([]);
-
   const [position, setPosition] = useState();
   const [isFirstRun, setFirstRun] = useState(true);
 
+  // Memoize the updateMarks function
+  const updateMarksMemoized = useMemo(() => {
+    return updateMarks(
+      pmViews,
+      CommentDecorationPluginKey?.getState(activeView.state)?.allCommentsList(),
+    );
+  }, [pmViews, activeView.state]);
+
   const setTops = useCallback(() => {
     const result = [];
-    let markNodeEl = null;
-    let annotationTop = 0;
-    let boxHeight = 0;
-    let top = 0;
-    let WaxSurface = {};
-    let WaxSurfaceMarginTop = '';
     const allCommentsTop = [];
-    let panelWrapper = {};
-    let panelWrapperHeight = {};
-    if (main) {
-      WaxSurface = main.dom.getBoundingClientRect();
-      WaxSurfaceMarginTop = window.getComputedStyle(main.dom).marginTop;
-    }
-
-    each(marksNodes[area], (markNode, pos) => {
-      let id = '';
-
-      if (markNode?.node?.attrs.id) {
-        id = markNode.node.attrs.id;
-      } else if (markNode?.attrs?.id) {
-        id = markNode.attrs.id;
-      } else {
-        id = markNode.id;
-      }
-
-      let activeTrackChange = null;
 
-      if (trakChangePlugin)
-        activeTrackChange = trakChangePlugin.getState(activeView.state)
-          .trackChange;
-
-      let isActive = false;
-      if (
+    // Cache DOM queries
+    const waxSurface = main?.dom.getBoundingClientRect();
+    const waxSurfaceMarginTop = main
+      ? window.getComputedStyle(main.dom).marginTop
+      : '';
+    const panelWrapper = document.getElementsByClassName('panelWrapper');
+    const panelWrapperHeight =
+      panelWrapper[0]?.getBoundingClientRect().height || 0;
+    const notesContainer = document.querySelector('#notes-container');
+    const waxContainer = document.querySelector('#wax-container');
+    const waxContainerTop = waxContainer?.getBoundingClientRect().top || 0;
+
+    // Cache active track change state
+    const activeTrackChange = trakChangePlugin?.getState(activeView.state)
+      .trackChange;
+
+    // Pre-calculate common values
+    const marginTopValue = parseInt(waxSurfaceMarginTop.slice(0, -2), 10) || 0;
+    const baseOffset =
+      area === 'main'
+        ? (waxSurface?.top || 0) + marginTopValue
+        : panelWrapperHeight + waxContainerTop + 50;
+
+    marksNodes[area]?.forEach((markNode, pos) => {
+      const id =
+        markNode?.node?.attrs?.id || markNode?.attrs?.id || markNode.id;
+      const isActive =
         (activeComment && id === activeComment.id) ||
-        (activeTrackChange && id === activeTrackChange.attrs.id)
-      )
-        isActive = true;
+        (activeTrackChange && id === activeTrackChange.attrs.id);
 
-      // annotation top
+      // Get annotation position
+      let annotationTop = 0;
       if (area === 'main') {
-        markNodeEl = document.querySelector(`[data-id="${id}"]`);
-        if (!markNodeEl && marksNodes[area][pos - 1]) {
-          markNodeEl = document.querySelector(
-            `[data-id="${marksNodes[area][pos - 1].id}"]`,
-          );
-        }
-
+        const markNodeEl =
+          document.querySelector(`[data-id="${id}"]`) ||
+          (pos > 0
+            ? document.querySelector(
+                `[data-id="${marksNodes[area][pos - 1].id}"]`,
+              )
+            : null);
         if (markNodeEl) {
-          annotationTop =
-            markNodeEl.getBoundingClientRect().top -
-            WaxSurface.top +
-            parseInt(WaxSurfaceMarginTop.slice(0, -2), 10);
+          annotationTop = markNodeEl.getBoundingClientRect().top - baseOffset;
         }
-      } else {
-        // Notes
-        panelWrapper = document.getElementsByClassName('panelWrapper');
-        panelWrapperHeight = panelWrapper[0].getBoundingClientRect().height;
-
-        markNodeEl = document
-          .querySelector('#notes-container')
-          .querySelector(`[data-id="${id}"]`);
+      } else if (notesContainer) {
+        const markNodeEl = notesContainer.querySelector(`[data-id="${id}"]`);
         if (markNodeEl) {
-          const WaxContainerTop = document
-            .querySelector('#wax-container')
-            .getBoundingClientRect().top;
-
-          annotationTop =
-            markNodeEl.getBoundingClientRect().top -
-            panelWrapperHeight -
-            WaxContainerTop -
-            50;
+          annotationTop = markNodeEl.getBoundingClientRect().top - baseOffset;
         }
       }
 
-      let boxEl = null;
-      // get height of this markNode box
-      if (markNodeEl) {
-        boxEl = document.querySelector(`div[data-box="${id}"]`);
-      }
-      if (boxEl) {
-        boxHeight = parseInt(boxEl.offsetHeight, 10);
-        // where the box should move to
-        top = annotationTop;
-      }
-      // if the above comment box has already taken up the height, move down
+      // Calculate box position
+      let top = annotationTop;
+      const boxEl = document.querySelector(`div[data-box="${id}"]`);
+      const boxHeight = boxEl ? parseInt(boxEl.offsetHeight, 10) : 0;
+
+      // Handle overlaps with previous boxes
       if (pos > 0) {
         const previousBox = marksNodes[area][pos - 1];
-        const previousEndHeight = previousBox.endHeight;
-        if (annotationTop < previousEndHeight) {
-          top = previousEndHeight + 2;
+        if (annotationTop < previousBox.endHeight) {
+          top = previousBox.endHeight + 2;
         }
       }
-      // store where the box ends to be aware of overlaps in the next box
+
+      // Store end height for next iteration
       markNode.endHeight = top + boxHeight + 4;
       result[pos] = top;
       allCommentsTop.push({ [id]: result[pos] });
 
-      // if active, move as many boxes above as needed to bring it to the annotation's height
+      // Handle active state positioning
       if (isActive) {
         markNode.endHeight = annotationTop + boxHeight + 3;
         result[pos] = annotationTop;
         allCommentsTop[pos][id] = result[pos];
-        let b = true;
-        let i = pos;
-
-        // first one active, none above
-        if (i === 0) b = false;
 
-        while (b) {
+        // Adjust positions of boxes above active comment
+        for (let i = pos; i > 0; i--) {
           const boxAbove = marksNodes[area][i - 1];
           const boxAboveEnds = boxAbove.endHeight;
           const currentTop = result[i];
 
-          const doesOverlap = boxAboveEnds > currentTop;
-
-          if (doesOverlap) {
+          if (boxAboveEnds > currentTop) {
             const overlap = boxAboveEnds - currentTop;
             result[i - 1] -= overlap;
-            let previousMarkNode = '';
-
-            if (marksNodes[area][i - 1]?.node?.attrs.id) {
-              previousMarkNode = marksNodes[area][i - 1].node.attrs.id;
-            } else if (marksNodes[area][i - 1]?.attrs?.id) {
-              previousMarkNode = marksNodes[area][i - 1].attrs.id;
-            } else {
-              previousMarkNode = marksNodes[area][i - 1].id;
-            }
-
-            allCommentsTop[i - 1][previousMarkNode] = result[i - 1];
+            const previousId =
+              marksNodes[area][i - 1]?.node?.attrs?.id ||
+              marksNodes[area][i - 1]?.attrs?.id ||
+              marksNodes[area][i - 1].id;
+            allCommentsTop[i - 1][previousId] = result[i - 1];
+          } else {
+            break;
           }
-
-          if (!doesOverlap) b = false;
-          if (i <= 1) b = false;
-          i -= 1;
         }
       }
     });
+
     return allCommentsTop;
-  });
+  }, [
+    area,
+    marksNodes,
+    main,
+    activeView.state,
+    activeComment,
+    trakChangePlugin,
+  ]);
 
-  const recalculateTops = () => {
+  const recalculateTops = useCallback(() => {
     setTimeout(() => {
       setPosition(setTops());
     });
-  };
+  }, [setTops]);
 
   useDeepCompareEffect(() => {
     if (app.config.get('config.YjsService')) {
@@ -187,14 +162,7 @@ export default ({ area, users }) => {
         ),
       );
     } else {
-      setMarksNodes(
-        updateMarks(
-          pmViews,
-          CommentDecorationPluginKey?.getState(
-            activeView.state,
-          )?.allCommentsList(),
-        ),
-      );
+      setMarksNodes(updateMarksMemoized);
     }
 
     let firstRunTimeout = () => true;
@@ -208,12 +176,12 @@ export default ({ area, users }) => {
     }
 
     return () => clearTimeout(firstRunTimeout);
-  }, [
-    updateMarks(
-      pmViews,
-      CommentDecorationPluginKey?.getState(activeView.state)?.allCommentsList(),
-    ),
-    setTops(),
+  }, [updateMarksMemoized, setTops, isFirstRun, app.config]);
+
+  // Memoize the marks nodes for the current area
+  const currentAreaMarks = useMemo(() => marksNodes[area] || [], [
+    marksNodes,
+    area,
   ]);
 
   const CommentTrackComponent = useMemo(
@@ -221,15 +189,24 @@ export default ({ area, users }) => {
       <BoxList
         activeComment={context.options.activeComment}
         area={area}
-        commentsTracks={marksNodes[area] || []}
+        commentsTracks={currentAreaMarks}
         position={position}
         recalculateTops={recalculateTops}
         users={users}
         view={main}
       />
     ),
-    [marksNodes[area] || [], position, users, context.options.activeComment],
+    [
+      currentAreaMarks,
+      position,
+      users,
+      context.options.activeComment,
+      area,
+      recalculateTops,
+      main,
+    ],
   );
+
   return <>{CommentTrackComponent}</>;
 };
 
diff --git a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBox.js b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBox.js
index 9cc25d87580a7ab4df684ac17611a91426565f9a..28785f70911bda1b6be98c68bbcb479c576e06ad 100644
--- a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBox.js
+++ b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBox.js
@@ -59,7 +59,7 @@ const Resolve = styled.button`
     border: none;
   }
 
-  ${props => props.isReadOnly && inactiveButton}
+  ${props => props.isReadOnlyResolve && inactiveButton}
 
   ${override('Wax.CommentResolve')}
 `;
@@ -76,7 +76,8 @@ const CommentBox = props => {
     className,
     commentId,
     commentData,
-    isReadOnly,
+    isReadOnlyResolve,
+    isReadOnlyPost,
     onClickBox,
     onClickPost,
     onClickResolve,
@@ -100,9 +101,9 @@ const CommentBox = props => {
       {active && commentData.length > 0 && (
         <Head>
           <Resolve
-            isReadOnly={isReadOnly}
+            isReadOnlyResolve={isReadOnlyResolve}
             onClick={e => {
-              if (!isReadOnly) return onClickResolve(e, commentId);
+              if (!isReadOnlyResolve) return onClickResolve(e, commentId);
               return false;
             }}
           >
@@ -121,7 +122,7 @@ const CommentBox = props => {
       {active && (
         <StyledReply
           isNewComment={commentData.length === 0}
-          isReadOnly={isReadOnly}
+          isReadOnlyPost={isReadOnlyPost}
           onClickPost={onClickPost}
           onTextAreaBlur={onTextAreaBlur}
           showTitle={showTitle}
@@ -135,7 +136,8 @@ const CommentBox = props => {
 CommentBox.propTypes = {
   /** Whether this is the current active comment */
   active: PropTypes.bool,
-  isReadOnly: PropTypes.bool.isRequired,
+  isReadOnlyResolve: PropTypes.bool.isRequired,
+  isReadOnlyPost: PropTypes.bool.isRequired,
   /** List of objects containing data for comment items */
   commentData: PropTypes.arrayOf(
     PropTypes.shape({
diff --git a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBubbleComponent.js b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBubbleComponent.js
index 3b54d591d134920d356166a3e8edeb7e5a2f904e..afea824461f2e03790ec00fa4fbce75d4345b29d 100644
--- a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBubbleComponent.js
+++ b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBubbleComponent.js
@@ -49,6 +49,8 @@ const CommentBubbleComponent = ({ setPosition, position, group }) => {
   };
 
   const isCommentAllowed = () => {
+    if (activeViewId !== 'main') return false;
+
     let allowed = true;
     state.doc.nodesBetween(
       state.selection.$from.pos,
@@ -77,13 +79,12 @@ const CommentBubbleComponent = ({ setPosition, position, group }) => {
     return allowed;
   };
 
-  const isEditable = main.props.editable(editable => {
-    return editable;
-  });
+  // const isEditable = main.props.editable(editable => {
+  //   return editable;
+  // });
 
   return (
-    isCommentAllowed() &&
-    isEditable && (
+    isCommentAllowed() && (
       <CommentBubble
         onClick={event => {
           createComment(event);
diff --git a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentReply.js b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentReply.js
index 56d0a37f870f52c225645e182ede3e6f673a3eab..bb1945f4c43b21ec4fe20fb38e4a3311ecdec6c7 100644
--- a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentReply.js
+++ b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentReply.js
@@ -90,7 +90,7 @@ const CommentReply = props => {
     className,
     isNewComment,
     onClickPost,
-    isReadOnly,
+    isReadOnlyPost,
     onTextAreaBlur,
     showTitle,
     usersMentionList,
@@ -194,7 +194,7 @@ const CommentReply = props => {
       <ActionWrapper>
         <ButtonGroup>
           <Button
-            disabled={commentValue.length === 0 || isReadOnly}
+            disabled={commentValue.length === 0 || isReadOnlyPost}
             onClick={handleSubmit}
             primary
             type="submit"
@@ -218,7 +218,7 @@ const CommentReply = props => {
 CommentReply.propTypes = {
   isNewComment: PropTypes.bool.isRequired,
   onClickPost: PropTypes.func.isRequired,
-  isReadOnly: PropTypes.bool.isRequired,
+  isReadOnlyPost: PropTypes.bool.isRequired,
   onTextAreaBlur: PropTypes.func.isRequired,
   showTitle: PropTypes.bool.isRequired,
 };
diff --git a/wax-prosemirror-services/src/NoteService/Editor.js b/wax-prosemirror-services/src/NoteService/Editor.js
index ac9916787f68e321a70441be64914e15ba8e133b..16f6a2524dbdf54b67018a708cdf88a17f5f3114 100644
--- a/wax-prosemirror-services/src/NoteService/Editor.js
+++ b/wax-prosemirror-services/src/NoteService/Editor.js
@@ -41,9 +41,13 @@ export default ({ node, view }) => {
     return editable;
   });
 
-  // const filteredplugins = app.PmPlugins.getAll().filter(
-  //   plugin => !plugin.key.includes('comment') && !plugin.key.includes('yjs'),
-  // );
+  const filteredplugins = app.PmPlugins.getAll().filter(
+    plugin =>
+      !plugin.key.includes('y-sync') &&
+      !plugin.key.includes('y-undo') &&
+      !plugin.key.includes('yjs') &&
+      !plugin.key.includes('comment'),
+  );
 
   const setEditorRef = useCallback(noteNode => {
     if (noteNode) {
@@ -54,7 +58,7 @@ export default ({ node, view }) => {
           editable: () => isEditable,
           state: EditorState.create({
             doc: node,
-            plugins: [keymap(createKeyBindings()), ...app.PmPlugins.getAll()],
+            plugins: [keymap(createKeyBindings()), ...filteredplugins],
           }),
           dispatchTransaction,
           disallowedTools: ['Tables', 'Images', 'Lists', 'CodeBlock'],
diff --git a/wax-prosemirror-services/src/YjsService/YjsService.js b/wax-prosemirror-services/src/YjsService/YjsService.js
index c9655c093086351a94014a09301ba78de928496f..d203214bd99d872f0ab2ae497da616b63a9b1c13 100644
--- a/wax-prosemirror-services/src/YjsService/YjsService.js
+++ b/wax-prosemirror-services/src/YjsService/YjsService.js
@@ -40,7 +40,6 @@ class YjsService extends Service {
     });
 
     const type = ydoc.getXmlFragment(YjsType || 'prosemirror');
-    console.log('dsf');
 
     this.app.PmPlugins.add('ySyncPlugin', ySyncPlugin(type));