71쪽
"말을 얼룩말로 바꾸는 도구는 인류가 수천 년 동안 숨죽여 기다려왔으며" ->

표현이 너무 엄숙, 근엄, 진지해서 원문을 찾아봤더니, "While humankind hasn’t held its breath over the last few thousand years for a tool that turn horses into zebras" [원문에서 "turn"은 "turns"라고 써야 문법에 맞는다]

"has held its breath"였다면 국역본과 같은 번역이 타당할 수 있겠는데,
"has"가 아닌 "hasn't"여서 "인류는 말을 얼룩말로 바꾸는 도구를 개발하기 위해 지난 수천 년 동안 멈추지 않았지만"이 더 정확한 것 아닌가 싶다.
그래도 '숨죽여 왔다'가 느낌은 더 와닿는 것 같기도...


아무튼 저자들이 말하는 '인류의 수천 년 숙원'을 받들어... 책에 나오는 코드로 다양한 말들을 얼룩말로 바꿔 봄...

말들아, 줄 그어서 미안해!! ㅠㅠ







연습문제에 나오는 대로 골든 리트리버 이미지도 넣어 봄...

개들아, 미안해!! ㅠㅠ




(음... 나뭇잎도 얼룩나뭇잎이 되어버렸네...)


덧. 원본 이미지는 royalty free 사이트에서 받았음(https://pixabay.com/images/search/horse/, https://pixabay.com/images/search/golden+retriever/)



댓글(0) 먼댓글(0) 좋아요(11)
좋아요
북마크하기찜하기 thankstoThanksTo
 
 
 

앞의 글 https://blog.aladin.co.kr/SilentPaul/14856526 에 이어서 쓴다.


이번에는 범위를 좀 더 넓혀서 판매자별 장바구니의 html 코드를 ChatGPT에 분석하게 하였다. 코드가 길어져서 나누어 입력했다.


---------- ChatGPT가 제시한 문제의 원인 ----------


입력하신 (1), (2), (3), (4) 코드를 기반으로 페이지가 다운되는 원인에 대한 여러 가능한 원인을 제시하겠습니다:


1. 스크립트 충돌: 입력하신 코드 내에는 여러 `javascript:void(0);`와 같은 JavaScript 코드들이 있습니다. 다른 스크립트와의 상호작용 중 충돌이 일어날 가능성이 있습니다.


2. HTML 구조 문제: 코드를 빠르게 보았을 때 일부 HTML 태그들이 완전하게 닫히지 않거나, 일부 태그들의 순서가 잘못되었을 수 있습니다. 예를 들어, `</ul>` 이나 `</div>` 등의 태그가 필요한 위치에 없거나, 불필요한 위치에 있을 수 있습니다.


3. 이벤트 핸들러 문제: `onmousedown`이나 `onclick` 같은 이벤트 핸들러에 연결된 JavaScript 함수(예: `QtyApply_Layer`, `BasketDelete`, `SafeKeepSingle_Add` 등)가 정의되지 않았거나, 오류를 발생시킬 수 있는 코드를 포함하고 있을 수 있습니다.


--> 코드를 옮겨 붙이다가 받은 인상으로는, 이 3.이 문제인가도 싶다.


4. 외부 리소스 문제: `img` 태그를 통해 로드하는 외부 이미지나 다른 외부 리소스들이 존재하지 않거나 접근이 불가능할 경우, 페이지 로딩에 문제가 발생할 수 있습니다.


5. 서버 측 코드 문제: 표시된 HTML이 서버 측 코드로 생성될 경우, 해당 서버 코드에서 문제가 발생할 수 있습니다.


6. 브라우저 호환성 문제: 일부 브라우저에서는 특정 HTML 구조나 JavaScript 코드를 잘 처리하지 못할 수 있습니다. 여러 브라우저에서 테스트를 해보는 것이 좋습니다.


7. CSS 문제: 코드에 포함된 `style` 속성이나 외부 CSS 파일에 문제가 있을 수 있습니다. 특히 Internet Explorer와 같은 오래된 브라우저에서는 일부 CSS 속성이 제대로 동작하지 않을 수 있습니다.


이러한 원인 중 하나 혹은 여러 원인이 합쳐져서 페이지 다운의 원인이 될 수 있습니다. 디버깅을 위해 개발자 도구의 콘솔 탭에서 오류 메시지를 확인해보는 것이 도움이 될 수 있습니다.


댓글(0) 먼댓글(0) 좋아요(17)
좋아요
북마크하기찜하기
 
 
 

알라딘이 책 판매를 넘어서는 어떤 비전을 가지고 있는지는 모르겠지만,


자주, 정기적으로 접속하는 여러 사이트, 서비스 중에 알라딘 장바구니처럼 자주 다운되고 불안정한 페이지는 없는 것 같다.


장바구니에서 책 한 권을 지우려 해도 거의 항상, 매번 페이지가 다운된다. 수십 분씩 다운되는 일이 허다하다. 영 돌아오지 않을 것 같을 때는 '작업관리자'를 켜서 강제 종료시키는데, 오늘은 작업관리자 창마저 거듭 다운시켜 버리는 위력에 기가 찼다. 이 글을 쓰는 데도 몇 시간이 걸렸는지 모르겠다. 내 컴퓨터 사양이 아주 떨어지는 것도 아닌데 말이다.


책 한 권 한 권마다 아래와 같은 코드를 쓰고 있는데, 평소 장바구니에 책을 많이 넣어두는 사람에게는 너무 무거운 것 같다. 군더더기와 이미지 개수를 줄이고, 개별 이미지도 크기를 가볍게 했으면 좋겠다. 이미 장바구니에 넣었는데, 굳이 책 이미지를 볼 필요가 있나도 싶다. 사용자가 장바구니에 책 이미지를 표시할지 말지 고를 수 있게 해도 좋을 것 같다. 장바구니에 책을 담는 것까지는 괜찮은데, 삭제 등 장바구니 관리가 너무너무 어렵다. 페이지 전체에 정보가 너무 많다. 아무튼 무게를 확 줄여야 한다.


덧붙여, 책 검색도 너무 경직되어 있다. 아주 조금만 검색어가 어긋나도 검색 결과를 전혀 돌려주지 못한다. ChatGPT에 Clova X에 시대가 어떻게 변하고 있는데 이렇게 맹탕이다.


아마존 같은 테크 기업이 되는 건 기대도 안 한다.

대안이 마땅치 않아 의존하고는 있지만, 아무튼 심히 불만스럽다.



---------- 알라딘 장바구니의 책 한 권마다 들어가는 html 코드 ----------


&lt;tr id="CartTr_189641292"&gt;

    &lt;td align="center" width="46"&gt;

        &lt;input type="checkbox" checked="" name="chkCart.K972635587" class="ShopCode_Basket_Check basket_CheckBox" pricesales="26100" qty="1" mileage="1450" dcprice="2900" itemid="189641292" onclick="BasketSalseSummary(0);"&gt;

        &lt;input type="hidden" name="hidCart.K972635587" value="189641292"&gt;

    &lt;/td&gt;

    &lt;td width="48" bgcolor="#ffffff"&gt;

        &lt;a href="https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=189641292" title="밑바닥부터 시작하는 딥러닝 2"&gt;

            &lt;img src="https://image.aladin.co.kr/product/18964/12/covermini/k972635587_1.jpg" style="width:48px;"&gt;

        &lt;/a&gt;

    &lt;/td&gt;

    &lt;td width="*" bgcolor="#ffffff" align="left"&gt;

        &lt;span class="basket_tit"&gt;

            &lt;a href="https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=189641292" style="color:#386DA1;"&gt;[국내도서] 밑바닥부터 시작하는 딥러닝 2&lt;/a&gt; - 파이썬으로 직접 구현하며 배우는 순환 신경망과 자연어 처리

        &lt;/span&gt;

        &lt;a href="https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=189641292" target="_blank"&gt;

            &lt;img src="//image.aladin.co.kr/img/common/btn_newwindow.gif" style="vertical-align:sub;"&gt;

        &lt;/a&gt;&nbsp;

        &lt;a href="http://www.aladin.co.kr/events/wevent.aspx?EventId=179240"&gt;

            &lt;span class="label_deduct"&gt;소득공제&lt;/span&gt;

        &lt;/a&gt;&lt;br&gt;

        &lt;span&gt;

            &lt;table cellpadding="0" cellspacing="0" border="0" width="100%"&gt;

                &lt;tbody&gt;

                    &lt;tr&gt;

                        &lt;td&gt;

                            &lt;span class="expDeliveryItem"&gt;* 내일 밤 11시 잠들기전 배송&lt;/span&gt;

                        &lt;/td&gt;

                    &lt;/tr&gt;

                &lt;/tbody&gt;

            &lt;/table&gt;

        &lt;/span&gt;

        &lt;font color="#f26122"&gt;스프링 분철 선택 가능&lt;/font&gt;

        &lt;div id="btn_189641292" class="button"&gt;

            &lt;a class="button_small" href="javascript:void(0);" onclick="BasketOptionLayer(2, 189641292, 0);"&gt;변경&lt;/a&gt;

        &lt;/div&gt;

    &lt;/td&gt;

    &lt;td width="130" bgcolor="#ffffff" align="left"&gt;

        정가 : &lt;s&gt;29,000&lt;/s&gt;원&lt;br&gt;

        판매가 : &lt;span class="p1"&gt;26,100&lt;/span&gt;원&lt;br&gt;

        마일리지 : &lt;span class="p2"&gt;1,450&lt;/span&gt;원 (&lt;span class="p2"&gt;5%&lt;/span&gt;)

    &lt;/td&gt;

    &lt;td width="90" align="center" bgcolor="#ffffff"&gt;

        &lt;div class="ordernumber_box"&gt;

            &lt;div class="Hleft2"&gt;

                &lt;div class="number1"&gt;

                    &lt;input type="text" size="2" value="1" name="OrderQty.K972635587" class="input1" onkeydown="QtyApply_Enter(event, 'K972635587', 0);" onfocusout="QtyApply_Focus('K972635587', 0);" onclick="QtyLayerOpen('K972635587');" autocomplete="off" spellcheck="false" data-ms-editor="true"&gt;

                    &lt;img id="Arrow_K972635587" src="//image.aladin.co.kr/img/order/2019/icon_arrow_down_order.png" onclick="QtyLayerOpen('K972635587');" align="absmiddle" style="float:right;margin:6px 0px 0 0;cursor:pointer;"&gt;

                    &lt;div style="clear:both"&gt;&lt;/div&gt;

                &lt;/div&gt;

            &lt;/div&gt;

            &lt;div id="QtyLayer_K972635587" class="list1" style="position:absolute; z-index:99;top:27px;left:5px;display:none;"&gt;

                &lt;ul&gt;

                    &lt;a href="javascript:void(0);" onmousedown="QtyApply_Layer('K972635587', 0, 1);" style="color:#222"&gt;

                        &lt;li&gt;1&lt;/li&gt;

                    &lt;/a&gt;

                    &lt;a href="javascript:void(0);" onmousedown="QtyApply_Layer('K972635587', 0, 2);" style="color:#222"&gt;

                        &lt;li&gt;2&lt;/li&gt;

                    &lt;/a&gt;

                    &lt;a href="javascript:void(0);" onmousedown="QtyApply_Layer('K972635587', 0, 3);" style="color:#222"&gt;

                        &lt;li&gt;3&lt;/li&gt;

                    &lt;/a&gt;

                    &lt;a href="javascript:void(0);" onmousedown="QtyApply_Layer('K972635587', 0, 4);" style="color:#222"&gt;

                        &lt;li&gt;&4lt;/li&gt;

                    &lt;/a&gt;

                    &lt;a href="javascript:void(0);" onmousedown="QtyApply_Layer('K972635587', 0, 5);" style="color:#222"&gt;

                        &lt;li&gt;5&lt;/li&gt;

                    &lt;/a&gt;

                    &lt;a href="javascript:void(0);" onmousedown="QtyApply_Layer('K972635587', 0, 6);" style="color:#222"&gt;

                        &lt;li&gt;&6lt;/li&gt;

                    &lt;/a&gt;

                    &lt;a href="javascript:void(0);" onmousedown="QtyApply_Layer('K972635587', 0, 7);" style="color:#222"&gt;

                        &lt;li&gt;&7lt;/li&gt;

                    &lt;/a&gt;

                    &lt;a href="javascript:void(0);" onmousedown="QtyApply_Layer('K972635587', 0, 8);" style="color:#222"&gt;

                        &lt;li&gt;8&lt;/li&gt;

                    &lt;/a&gt;

                    &lt;a href="javascript:void(0);" onmousedown="QtyApply_Layer('K972635587', 0, 9);" style="color:#222"&gt;

                        &lt;li&gt;&9lt;/li&gt;

                    &lt;/a&gt;

                    &lt;a href="javascript:void(0);" onmousedown="QtyApply_Layer('K972635587', 0, 10);" style="color:#222"&gt;

                        &lt;li&gt;10&lt;/li&gt;

                    &lt;/a&gt;

                &lt;/ul&gt;

            &lt;/div&gt;

        &lt;/div&gt;

    &lt;/td&gt;

    &lt;td width="90" align="center" bgcolor="#ffffff"&gt;

        &lt;table cellspacing="0" cellpadding="1" border="0"&gt;

            &lt;tbody&gt;

                &lt;tr&gt;

                    &lt;td align="center" width="48"&gt;

                        &lt;div class="button_gray"&gt;

                            &lt;a class="button_small" href="javascript:void(0);" onclick="BasketDelete(189641292, 0);"&gt;삭제&lt;/a&gt;

                        &lt;/div&gt;

                    &lt;/td&gt;

                &lt;/tr&gt;

                &lt;tr&gt;

                    &lt;td align="center"&gt;

                        &lt;div class="button_gray"&gt;

                            &lt;a class="button_small" href="javascript:void(0);" onclick="SafeKeepSingle_Add('756067871','K972635587','False')"&gt;보관&lt;/a&gt;

                        &lt;/div&gt;

                    &lt;/td&gt;

                &lt;/tr&gt;

            &lt;/tbody&gt;

        &lt;/table&gt;

    &lt;/td&gt;

&lt;/tr&gt;



이왕 쓴 김에 ChatGPT가 제안한 해결책도 써둔다(내가 전문적으로 판단할 역량은 없지만, 답변 결과를 일부 수정하였다). + 답변 내용 수정, 추가

---------- ChatGPT가 제안한 해결방안 ----------


제시해주신 HTML 코드를 바탕으로 문제와 최적화 방안을 정리해보겠습니다.


1. JavaScript 함수 호출: 해당 코드에서는 여러 자바스크립트 함수가 호출되는데, 특히 삭제 버튼을 클릭하면 BasketDelete(189641292, 0); 함수가 실행됩니다. 이 함수는 삭제 기능을 처리하는 것으로 보이는데, 문제가 발생하면 해당 함수를 첫 번째로 살펴보아야 합니다.


2. 서버 응답: 삭제 버튼을 클릭하면 서버에 요청을 보내 해당 아이템을 장바구니에서 삭제하는 요청을 처리하게 될 것입니다. 서버의 응답이 느린 경우, 혹은 서버에서 오류 응답을 반환하는 경우 문제가 발생할 수 있습니다.


3. 코드 복잡성: 주어진 코드는 하나의 책에 대한 정보와 연관된 버튼, 이미지 등의 세부 요소를 표현합니다. 코드 자체는 복잡성이 크게 높지 않으나, 이런 형식의 코드가 1,000번 반복된다면 전체 HTML 문서의 크기가 커져 로딩 속도에 영향을 줄 수 있습니다.


3-1. DOM 구조: tr 태그 안에 있는 각각의 td는 장바구니의 한 아이템에 대한 정보나 기능을 나타냅니다. DOM의 구조나 스타일이 복잡하면 이로 인해 페이지의 반응 속도가 느려질 수 있습니다.


4. 이미지 로딩: 코드에 포함된 이미지 링크들(책 표지 이미지, 새 창 아이콘, 화살표 아이콘 등)은 페이지 로딩 시간에 큰 영향을 미칠 수 있습니다. 각 이미지의 크기가 크거나, 이미지의 수가 많을 경우 로딩 시간이 증가합니다.



해결 방안:


1. JavaScript 최적화:

  - 'BasketDelete'와 같은 관련 자바스크립트 함수의 동작을 확인합니다.

  - 필요한 경우 개발자 도구의 Network 탭과 Console 탭에서 오류나 경고 메시지를 확인합니다.

  - JavaScript 함수는 외부 파일로 분리하여 필요할 때만 로드하게 합니다.

  - 비동기 로딩: 필요한 부분만 AJAX, Fetch API, async, defer 등을 이용해 동적으로 로드합니다.

  - 이벤트 위임을 사용하여 동일한 이벤트 핸들러를 여러 요소에 적용하는 대신 상위 요소에 한 번만 적용합니다.


cf. 추가 질문 내용 보충

 (1) AJAX (Asynchronous JavaScript and XML):

   - 웹 페이지를 다시 로드하지 않고도 서버와 비동기적으로 데이터를 교환할 수 있는 방법입니다.

   - XMLHttpRequest 객체를 사용하여 구현합니다.

   - 주로 XML 혹은 JSON 데이터 형식으로 데이터를 주고 받지만, 다른 형식도 가능합니다.

   - 페이지의 일부만 업데이트 할 때 주로 사용됩니다.

  (2) Fetch API:

   - 서버와 비동기적으로 통신하는데 사용되는 모던한 API입니다.

   - XMLHttpRequest의 대체제로 생각될 수 있으며, 보다 간결하고 유연한 API를 제공합니다.

   - Promise 기반으로 동작하며, async/await와 함께 사용하여 가독성 좋은 코드를 작성할 수 있습니다.

  (3) async (attribute in script tag): 

   - HTML에서 script 태그에 사용되는 속성입니다.

   - async 속성이 있는 스크립트는 페이지의 파싱과 동시에 다운로드되며, 다운로드 완료 즉시 실행됩니다.

   - 페이지의 파싱을 막지 않기 때문에 비동기적으로 로딩되는 효과가 있습니다.

  (4) defer (attribute in script tag):

   - HTML에서 script 태그에 사용되는 속성입니다.

   - defer 속성이 있는 스크립트는 페이지의 파싱과 동시에 다운로드되지만, 파싱이 완전히 끝난 후에 실행됩니다.

   - 스크립트의 순서가 중요할 때 유용하게 사용됩니다. (즉, 여러 개의 defer 스크립트는 순서대로 실행됩니다.)


요약하면, AJAX와 Fetch API는 웹 페이지와 서버 간의 비동기 통신을 위한 방법이며, async와 defer는 script 태그의 다운로드와 실행 방식을 제어하는 속성입니다.


2. 서버 응답 문제: 삭제 버튼을 클릭했을 때 서버에서 적절한 응답을 하지 않거나 지연될 수 있습니다.

  - 서버의 로그를 확인하여 오류 메시지나 원인을 찾습니다.

  - 서버의 처리 속도가 느릴 경우, 백엔드 최적화를 고려합니다. 데이터베이스 쿼리 최적화, 서버 설정 최적화 등을 통해 서버 응답 시간을 줄입니다.

  - 서버에서 HTML을 미리 렌더링하여 클라이언트에게 전송함으로써 초기 로딩 속도를 향상시킬 수 있습니다.

  - CDN 사용: 이미지나 스크립트 파일을 분산된 서버에서 로드하여 로딩 속도를 향상시킵니다.


3. 코드 간소화, 캐싱: HTML 구조를 간단하게 만드는 것이 중요합니다.

  - 불필요한 div 또는 span 태그를 줄이는 등 불필요한 중첩된 태그 구조나 스타일을 최소화합니다.

  - CSS 스타일은 가능한 한 외부 파일로 분리합니다(이미 분리되어 있다면 중복 스타일 제거).

  - 웹페이지의 정적 리소스(CSS, JS, 이미지 등)에 대한 캐싱 정책을 설정합니다.

  - 데이터베이스 쿼리 결과에 대한 캐싱을 고려합니다. 


4. 이미지 등 페이지 성능 최적화:

  - 이미지의 크기와 해상도를 줄입니다.

  - 이미지의 포맷을 웹에 최적화된 형식으로 변경하여 로딩 시간을 줄일 수 있습니다. 예를 들면, JPEG나 PNG 이미지를 WebP 포맷으로 변경하는 것이 효과적일 수 있습니다.

  - 페이지 로딩 시 모든 이미지를 한 번에 로드하는 대신, 사용자의 스크롤 위치에 따라 필요한 이미지만 로드하는 Lazy Loading을 적용하여 초기 로딩 속도를 개선합니다.

  - 데이터 페이징: 1,000권의 책을 한 번에 표시하는 대신 페이지별로 나누어 표시합니다. 사용자가 필요한 부분만 로드하여 전체 로딩 시간을 줄입니다.


결론적으로, 웹 페이지의 성능 문제는 다양한 요인에 의해 발생할 수 있습니다. 따라서 개발자 도구의 Network 탭이나 Performance 탭을 사용하여 웹 페이지의 로딩 속도를 분석하고, 구체적인 문제점을 파악하는 것이 좋습니다.


---------------------------------------------


다음은 순서대로, (장바구니에서 책을 삭제하였을 때) 개발자 도구의 Network 탭, Performance 탭 캡쳐 화면(서재에 이미지를 첨부하려니 해상도가 떨어진다)





나도 알라딘을 이루는 일원이라는 생각이 있고, 애정이 있으니 쓴 글이다.

부디 알라딘 관계자가 진지하게 읽어주기 바란다.


읽어주시는 분들께서도 공감하시면 "좋아요" 눌러서 올려주시면 감사하겠습니다.


댓글(3) 먼댓글(0) 좋아요(23)
좋아요
북마크하기찜하기
 
 
머리쓰기&글쓰기 2023-08-26 00:34   좋아요 1 | 댓글달기 | URL
근래 북플도 며칠간 다운되었었죠...

묵향 2023-08-26 00:52   좋아요 0 | URL
그러게나 말입니다... 최근 더 느려진 것 같은 느낌적인 느낌도 듭니다...

묵향 2023-08-26 09:58   좋아요 0 | 댓글달기 | URL
글을 조금 수정하여, 해결책이 될 만한 방법을 썼습니다. ChatGPT가 제안해 준 방법들입니다.

https://blog.aladin.co.kr/SilentPaul/14856988 에도 글을 이어서 썼습니다.
 

일단 2019년에 나온 책이라는 데 높은 점수를 주고 싶다.



인간의 언어는 컴퓨터 프로그래밍 언어처럼 명확하지 않습니다. 우리는 언어의 모호성을 적극적으로 활용함으로써 의사소통의 효율을 극대화합니다. 예를 들어 우리는 정보나 단어를 생략하고 문장을 짧게 만들기도 하고, 같은 단어와 어절이라고 해도 때에 따라서는 다른 의미로 해석하기도 합니다. 더욱이 한국어의 경우에는 앞서 다루었듯이 어순이 불규칙하고 주어가 생략되는 등, 다른 언어에 비해 그 효율이 더욱 극대화되었습니다. - P305

사람의 경우에는 일반화 능력이 뛰어나므로 몇 가지 규칙만으로도 훌륭하게 적용하여 번역을 수행할 수 있지만, 컴퓨터의 경우에는 사람보다 일반화 능력이 현저히 떨어지므로 규칙 기반 기계번역은 매우 어렵습니다. 잘 만들어진 규칙 안에서는 통계 기반 기계번역에 비해 자연스러운 표현이 가능하지만, 그 규칙을 일일이 사람이 만들어내야 하므로 번역기를 만드는 데 많은 자원과 시간이 소모됩니다. 번역 언어쌍을 확장할 때도 매번 새로운 규칙을 찾아내고 적용해야 하므로 매우 불리합니다. - P306


댓글(0) 먼댓글(0) 좋아요(8)
좋아요
북마크하기찜하기 thankstoThanksTo
 
 
 

7 비지학습 -> 비지도학습(이 아닐지...)

(수시로 추가 예정)



댓글(0) 먼댓글(0) 좋아요(4)
좋아요
북마크하기찜하기 thankstoThanksTo